diff --git a/external_src/raspicam-0.1.3-1.zip b/external_src/raspicam-0.1.3-1.zip new file mode 100644 index 0000000..a8e6f20 Binary files /dev/null and b/external_src/raspicam-0.1.3-1.zip differ diff --git a/external_src/raspicam-0.1.3.zip b/external_src/raspicam-0.1.3.zip new file mode 100644 index 0000000..a8e6f20 Binary files /dev/null and b/external_src/raspicam-0.1.3.zip differ diff --git a/external_src/raspicam-0.1.3/CMakeLists.txt b/external_src/raspicam-0.1.3/CMakeLists.txt new file mode 100644 index 0000000..3630364 --- /dev/null +++ b/external_src/raspicam-0.1.3/CMakeLists.txt @@ -0,0 +1,250 @@ +# ---------------------------------------------------------------------------- +# Basic Configuration +# ---------------------------------------------------------------------------- +CMAKE_MINIMUM_REQUIRED(VERSION 2.8) + +PROJECT(raspicam) +set(PROJECT_VERSION "0.1.2") +string(REGEX MATCHALL "[0-9]" PROJECT_VERSION_PARTS "${PROJECT_VERSION}") +list(GET PROJECT_VERSION_PARTS 0 PROJECT_VERSION_MAJOR) +list(GET PROJECT_VERSION_PARTS 1 PROJECT_VERSION_MINOR) +list(GET PROJECT_VERSION_PARTS 2 PROJECT_VERSION_PATCH) +set(PROJECT_SOVERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}") + +#------------------------------------------------------ +# Build type +#------------------------------------------------------ + +IF(NOT CMAKE_BUILD_TYPE ) + SET( CMAKE_BUILD_TYPE "Release" ) +ENDIF() + +#------------------------------------------------------ +# Lib Names and Dirs +#------------------------------------------------------ + + # Postfix of so's: +set(PROJECT_DLLVERSION) +SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_INSTALL_PREFIX}/lib/cmake/ /usr/lib/cmake) + +OPTION(BUILD_SHARED_LIBS "Set to OFF to build static libraries" ON) +OPTION(BUILD_UTILS "Acitvates/Deactivates building utils libraries" ON) + +# ---------------------------------------------------------------------------- +# Find Dependencies +# ---------------------------------------------------------------------------- + #Add include to dependencies dir +include_directories(${PROJECT_SOURCE_DIR}/dependencies ${PROJECT_SOURCE_DIR}/dependencies/mmal ${PROJECT_SOURCE_DIR}/dependencies/vcos) +#find the mmal libraries(I use conditional because I normally comile in pc) + +if(${CMAKE_SYSTEM_PROCESSOR} MATCHES arm*) +FIND_LIBRARY(mmalcore_LIBS NAMES mmal_core PATHS /opt/vc/lib) +FIND_LIBRARY(mmalutil_LIBS NAMES mmal_util PATHS /opt/vc/lib) +FIND_LIBRARY(mmal_LIBS NAMES mmal PATHS /opt/vc/lib) +IF( (NOT mmal_LIBS ) OR (NOT mmalutil_LIBS) OR (NOT mmalcore_LIBS) ) + MESSAGE(FATAL_ERROR "Could not find mmal libraries") + ENDIF() + set(REQUIRED_LIBRARIES ${REQUIRED_LIBRARIES} ${mmalcore_LIBS} ${mmalutil_LIBS} ${mmal_LIBS} ) +ENDIF() + +#If opencv installed, creates the libraspicam_cv library module +FIND_PACKAGE(OpenCV) +IF(OpenCV_FOUND) + include_directories(${OpenCV_INCLUDE_DIRS}) + SET(LIB_COMPONENTS ${LIB_COMPONENTS} ${PROJECT_NAME}_cv) + SET(PROJECT_CV_CREATED_FLAG "YES") +ENDIF() + + + +# ---------------------------------------------------------------------------- +# PROJECT CONFIGURATION +# force some variables that could be defined in the command line to be written to cache +# ---------------------------------------------------------------------------- +OPTION(INSTALL_DOC "Set to ON to build/install Documentation" OFF) +IF (INSTALL_DOC) + FIND_PACKAGE(Doxygen REQUIRED) + MESSAGE( STATUS "INSTALL_DOC: ${INSTALL_DOC} ") + INCLUDE("${PROJECT_SOURCE_DIR}/generateDoc.cmake") + GENERATE_DOCUMENTATION(${PROJECT_SOURCE_DIR}/dox.in) +ENDIF() + + +# ---------------------------------------------------------------------------- +# Uninstall target, for "make uninstall" +# ---------------------------------------------------------------------------- +CONFIGURE_FILE( "${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" IMMEDIATE @ONLY) +ADD_CUSTOM_TARGET(uninstall "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake") + +# ---------------------------------------------------------------------------- +# create configuration file from .in file (If you use windows take care with paths) +# ---------------------------------------------------------------------------- +CONFIGURE_FILE("${PROJECT_SOURCE_DIR}/config.cmake.in" "${PROJECT_BINARY_DIR}/Find${PROJECT_NAME}.cmake") +CONFIGURE_FILE("${PROJECT_SOURCE_DIR}/config.cmake.in" "${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake") +INSTALL(FILES "${PROJECT_BINARY_DIR}/Find${PROJECT_NAME}.cmake" DESTINATION lib/cmake/ ) +INSTALL(FILES "${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake" DESTINATION lib/cmake/ ) + +# ---------------------------------------------------------------------------- +# Program Optimization and debug (Extracted from OpenCV) +# ---------------------------------------------------------------------------- +set(WARNINGS_ARE_ERRORS OFF CACHE BOOL "Treat warnings as errors") +set(WHOLE_PROGRAM_OPTIMIZATION OFF CACHE BOOL "Flags for whole program optimization.") +set(EXTRA_C_FLAGS "") +set(EXTRA_C_FLAGS_RELEASE "") +set(EXTRA_C_FLAGS_DEBUG "") +set(EXTRA_EXE_LINKER_FLAGS "") +set(EXTRA_EXE_LINKER_FLAGS_RELEASE "") +set(EXTRA_EXE_LINKER_FLAGS_DEBUG "") + +IF(CMAKE_COMPILER_IS_GNUCXX 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 + set(USE_O2 ON CACHE BOOL "Enable -O2 for GCC") + set(USE_FAST_MATH ON CACHE BOOL "Enable -ffast-math for GCC") + endif() + if(${CMAKE_SYSTEM_PROCESSOR} MATCHES powerpc*) + set(USE_O3 ON CACHE BOOL "Enable -O3 for GCC") + set(USE_POWERPC ON CACHE BOOL "Enable PowerPC for GCC") + endif () + if(${CMAKE_SYSTEM_PROCESSOR} MATCHES amd64* OR ${CMAKE_SYSTEM_PROCESSOR} MATCHES x86_64*) + set(USE_O3 ON CACHE BOOL "Enable -O3 for GCC") + set(USE_FAST_MATH ON CACHE BOOL "Enable -ffast-math for GCC") + set(USE_MMX ON CACHE BOOL "Enable MMX for GCC") + set(USE_SSE ON CACHE BOOL "Enable SSE for GCC") + set(USE_SSE2 ON CACHE BOOL "Enable SSE2 for GCC") + set(USE_SSE3 ON CACHE BOOL "Enable SSE3 for GCC") + endif() + if(${CMAKE_SYSTEM_PROCESSOR} MATCHES i686* OR ${CMAKE_SYSTEM_PROCESSOR} MATCHES x86) + set(USE_O3 ON CACHE BOOL "Enable -O3 for GCC") + set(USE_FAST_MATH ON CACHE BOOL "Enable -ffast-math for GCC") + set(USE_MMX ON CACHE BOOL "Enable MMX for GCC") + set(USE_SSE OFF CACHE BOOL "Enable SSE for GCC") + set(USE_SSE2 OFF CACHE BOOL "Enable SSE2 for GCC") + set(USE_SSE3 OFF CACHE BOOL "Enable SSE3 for GCC") + endif () + + set(EXTRA_C_FLAGS "${EXTRA_C_FLAGS} -Wall") + + if(WARNINGS_ARE_ERRORS) + set(EXTRA_C_FLAGS "${EXTRA_C_FLAGS} -Werror") + endif() + + # The -Wno-long-long is required in 64bit systems when including sytem headers. + if(${CMAKE_SYSTEM_PROCESSOR} MATCHES x86_64* OR ${CMAKE_SYSTEM_PROCESSOR} MATCHES amd64*) + set(EXTRA_C_FLAGS "${EXTRA_C_FLAGS} -Wno-long-long") + endif() + + # Whole program optimization + if(WHOLE_PROGRAM_OPTIMIZATION) + set(EXTRA_C_FLAGS_RELEASE "${EXTRA_C_FLAGS_RELEASE} -fwhole-program --combine") + endif() + + # Other optimizations + if(USE_OMIT_FRAME_POINTER) + set(EXTRA_C_FLAGS_RELEASE "${EXTRA_C_FLAGS_RELEASE} -fomit-frame-pointer") + endif() + if(USE_O2) + set(EXTRA_C_FLAGS_RELEASE "${EXTRA_C_FLAGS_RELEASE} -O2") + endif() + if(USE_O3) + set(EXTRA_C_FLAGS_RELEASE "${EXTRA_C_FLAGS_RELEASE} -O3") + endif() + if(USE_FAST_MATH) + set(EXTRA_C_FLAGS_RELEASE "${EXTRA_C_FLAGS_RELEASE} -ffast-math") + endif() + if(USE_POWERPC) + set(EXTRA_C_FLAGS_RELEASE "${EXTRA_C_FLAGS_RELEASE} -mcpu=G3 -mtune=G5") + endif() + if(USE_MMX) + set(EXTRA_C_FLAGS_RELEASE "${EXTRA_C_FLAGS_RELEASE} -mmmx") + endif() + if(USE_SSE) + set(EXTRA_C_FLAGS_RELEASE "${EXTRA_C_FLAGS_RELEASE} -msse") + endif() + if(USE_SSE2) + set(EXTRA_C_FLAGS_RELEASE "${EXTRA_C_FLAGS_RELEASE} -msse2") + endif() + if(USE_SSE3 AND NOT MINGW) # SSE3 should be disabled under MingW because it generates compiler errors + set(EXTRA_C_FLAGS_RELEASE "${EXTRA_C_FLAGS_RELEASE} -msse3") + endif() + + if(ENABLE_PROFILING) + set(EXTRA_C_FLAGS_RELEASE "${EXTRA_C_FLAGS_RELEASE} -pg -g") + else() + if(NOT APPLE) + set(EXTRA_C_FLAGS "${EXTRA_C_FLAGS} -ffunction-sections") + endif() + endif() + + # Parallel mode + if(ENABLE_OPENMP) + set(EXTRA_C_FLAGS "${EXTRA_C_FLAGS} -fopenmp") + set(LINKER_LIBS ${LINKER_LIBS} gomp) + endif() + + set(EXTRA_C_FLAGS_RELEASE "${EXTRA_C_FLAGS_RELEASE} -DNDEBUG") + set(EXTRA_C_FLAGS_DEBUG "-g3 -O0 -DDEBUG -D_DEBUG -W -Wextra -Wno-return-type") + + MESSAGE( STATUS "-------------------------------------------------------------------------------" ) + message( STATUS "GNU COMPILER") + MESSAGE( STATUS "-------------------------------------------------------------------------------" ) + +ENDIF () + +IF(${CMAKE_SYSTEM_PROCESSOR} MATCHES armv6l ) ##BEAGLE BOARD + SET(EXTRA_C_FLAGS_RELEASE "${EXTRA_C_FLAGS_RELEASE} -mcpu=arm1176jzf-s -mfpu=vfp -mfloat-abi=hard -ftree-vectorize") +ENDIF() + +SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x -Wl,--no-as-needed")#for using condition variables +SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_C_FLAGS} ") +SET(CMAKE_CXX_FLAGS_RELEASE "${EXTRA_C_FLAGS_RELEASE} -lpthread") +SET(CMAKE_CXX_FLAGS_DEBUG "${EXTRA_C_FLAGS_DEBUG} -lpthread") +SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${EXTRA_EXE_LINKER_FLAGS}") +SET(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} ${EXTRA_EXE_LINKER_FLAGS_RELEASE}") +SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} ${EXTRA_EXE_LINKER_FLAGS_DEBUG}") + + + + +#------------------------------------------------ +# DIRS +#------------------------------------------------ +ADD_SUBDIRECTORY(src) +IF(BUILD_UTILS) +ADD_SUBDIRECTORY(utils) +ENDIF() + + +# ---------------------------------------------------------------------------- +# display status message for important variables +# ---------------------------------------------------------------------------- +message( STATUS ) +MESSAGE( STATUS "-------------------------------------------------------------------------------" ) +message( STATUS "General configuration for ${PROJECT_NAME} ${PROJECT_VERSION}") +MESSAGE( STATUS "-------------------------------------------------------------------------------" ) +message( STATUS ) +message(" Built as dynamic libs?:" ${BUILD_SHARED_LIBS}) +message(" Compiler:" "${CMAKE_COMPILER}" "${CMAKE_CXX_COMPILER}") +message( STATUS "C++ flags (Release): ${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_RELEASE}") +message( STATUS "C++ flags (Debug): ${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_DEBUG}") +message( STATUS "CMAKE_CXX_FLAGS: ${CMAKE_CXX_FLAGS}") +message( STATUS "CMAKE_BINARY_DIR: ${CMAKE_BINARY_DIR}") + +MESSAGE( STATUS ) +MESSAGE( STATUS "CMAKE_SYSTEM_PROCESSOR = ${CMAKE_SYSTEM_PROCESSOR}" ) +MESSAGE( STATUS "BUILD_SHARED_LIBS = ${BUILD_SHARED_LIBS}" ) +MESSAGE( STATUS "BUILD_UTILS = ${BUILD_UTILS}" ) + +MESSAGE( STATUS "CMAKE_INSTALL_PREFIX = ${CMAKE_INSTALL_PREFIX}" ) +MESSAGE( STATUS "CMAKE_BUILD_TYPE = ${CMAKE_BUILD_TYPE}" ) +MESSAGE( STATUS "CMAKE_MODULE_PATH = ${CMAKE_MODULE_PATH}" ) + +MESSAGE( STATUS ) +MESSAGE( STATUS "CREATE OPENCV MODULE=${OpenCV_FOUND}") +MESSAGE( STATUS "CMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}") +MESSAGE( STATUS "REQUIRED_LIBRARIES=${REQUIRED_LIBRARIES}") +MESSAGE( STATUS ) +MESSAGE( STATUS ) +MESSAGE( STATUS "Change a value with: cmake -D=" ) +MESSAGE( STATUS ) diff --git a/external_src/raspicam-0.1.3/Changelog b/external_src/raspicam-0.1.3/Changelog new file mode 100644 index 0000000..f82bad1 --- /dev/null +++ b/external_src/raspicam-0.1.3/Changelog @@ -0,0 +1,33 @@ +0.1.3 + - Native support for BGR and RGB in opencv classes. No need to do conversion anymore. +0.1.2 + - Solved deadlock error in grab +0.1.1 + - Moved to c++11 mutex and condition_variables. Bug fixed that caused random dead lock condition in grab() +0.1.0 + - Bug fixed in release for RapiCam and RaspiCam_Cv +0.0.7 + - Added classes RaspiCam_Still and RaspiCam_Still_Cv for still camera mode +0.0.6 + - Bug ins cv camera corrected +0.0.5 + - getImageBuffeSize change by getImageBufferSize (sorry) + - Change in capture format. Now, it is able to capture in RGB at high speed. + - The second parameter of retrieve is now useless. Format must be specified in Raspicam::(set/get)Format before opening the camera and can not be change during operation. + - RaspiCam_Cv captures in BGR, which is obtained by converting from RGB. Therefore, performance drops to half repect to the RaspiCam in RGB mode when using 1280x960. +0.0.4 + - Added shutter speed camera control + - OpenCv set/get params are now scaled to [0,100] + - Added more command line options in test programs +0.0.3 + - Fixed error in color conversion (rgb and bgr were swapped) + - Added command line options in raspicam_test to adjust exposure + - Changes in RaspiCam_Cv so that exposure can be adjusted. Very simply. +0.0.2 + - Decoupled opening from the start of capture in RaspiCam if desired. RapiCam::open and RaspiCam::startCapture + - Added function RaspiCam::getId and RaspiCam_Cv::getId + - Added a new way to convert yuv2rgb which is a bit faster.Thanks to Stefan Gufman (gruffypuffy at gmail dot com) + - Added command line option -test_speed to utils programs (do not save images to memory) + - Removed useless code in private_impl +0.0.1 +Initial libary diff --git a/external_src/raspicam-0.1.3/README b/external_src/raspicam-0.1.3/README new file mode 100644 index 0000000..5aaf15a --- /dev/null +++ b/external_src/raspicam-0.1.3/README @@ -0,0 +1,207 @@ + +This library allows to use the Raspberry Pi Camera. + +* Main features: + - Provides class RaspiCam for easy and full control of the camera + - Provides class RaspiCam_Cv for easy control of the camera with OpenCV. + - Provides class RaspiCam_Still and RaspiCam_Still_Cv for controlling the camera in still mode + - Easy compilation/installation using cmake. + - No need to install development file of userland. Implementation is hidden. + - Many examples + +* ChangeLog +0.1.3 + - Native support for BGR and RGB in opencv classes. No need to do conversion anymore. +0.1.2 + - Solved deadlock error in grab +0.1.1 + - Moved to c++11 mutex and condition_variables. Bug fixed that caused random dead lock condition in grab() +0.1.0 + - Bug fixed in release for RapiCam and RaspiCam_Cv +0.0.7 + - Added classes RaspiCam_Still and RaspiCam_Still_Cv for still camera mode +0.0.6 + - Bug ins cv camera corrected +0.0.5 + - getImageBuffeSize change by getImageBufferSize (sorry) + - Change in capture format. Now, it is able to capture in RGB at high speed. + - The second parameter of retrieve is now useless. Format must be specified in Raspicam::(set/get)Format before opening the camera and can not be change during operation. + - RaspiCam_Cv captures in BGR, which is obtained by converting from RGB. Therefore, performance drops to half repect to the RaspiCam in RGB mode when using 1280x960. +0.0.4 + - Added shutter speed camera control + - OpenCv set/get params are now scaled to [0,100] + - Added more command line options in test programs +0.0.3 + - Fixed error in color conversion (rgb and bgr were swapped) + - Added command line options in raspicam_test to adjust exposure + - Changes in RaspiCam_Cv so that exposure can be adjusted. Very simply. +0.0.2 + - Decoupled opening from the start of capture in RaspiCam if desired. RapiCam::open and RaspiCam::startCapture + - Added function RaspiCam::getId and RaspiCam_Cv::getId + - Added a new way to convert yuv2rgb which is a bit faster.Thanks to Stefan Gufman (gruffypuffy at gmail dot com) + - Added command line option -test_speed to utils programs (do not save images to memory) + - Removed useless code in private_impl + +0.0.1 +Initial libary + + +* Compiling + +Download the file to your raspberry. Then, uncompress the file and compile + +tar xvzf raspicamxx.tgz +cd raspicamxx +mkdir build +cd build +cmake .. + +At this point you'll see something like +-- CREATE OPENCV MODULE=1 +-- CMAKE_INSTALL_PREFIX=/usr/local +-- REQUIRED_LIBRARIES=/opt/vc/lib/libmmal_core.so;/opt/vc/lib/libmmal_util.so;/opt/vc/lib/libmmal.so +-- Change a value with: cmake -D= +-- +-- Configuring done +-- Generating done +-- Build files have been written to: /home/pi/raspicam/trunk/build + +If OpenCV development files are installed in your system, then you see +-- CREATE OPENCV MODULE=1 +otherwise this option will be 0 and the opencv module of the library will not be compiled. + +Finally compile and install +make +sudo make install + + +After that, you have the programs raspicam_test and raspicam_cv_test (if opencv was enabled). +Run the first program to check that compilation is ok. + +You can check that the library has installed the header files under /usr/local/lib/raspicam , and the libraries in +/usr/local/lib/libraspicam.so and /usr/local/lib/libraspicam_cv.so (if opencv support enabled) + +* Using it in your projects + +We provide a simple example to use the library. Create a directory for our own project. + +First create a file with the name simpletest_raspicam.cpp and add the following code + +/** +*/ +#include +#include +#include +#include +using namespace std; + +int main ( int argc,char **argv ) { + raspicam::RaspiCam Camera; //Cmaera object + //Open camera + cout<<"Opening Camera..."< +#include +#include +using namespace std; + +int main ( int argc,char **argv ) { + + time_t timer_begin,timer_end; + raspicam::RaspiCam_Cv Camera; + cv::Mat image; + int nCount=100; + //set camera params + Camera.set( CV_CAP_PROP_FORMAT, CV_8UC1 ); + //Open camera + cout<<"Opening Camera..."<>24 & 0x00FF) +# define COMPILER_VERSION_MINOR HEX(__CODEGEARC_VERSION__>>16 & 0x00FF) +# define COMPILER_VERSION_PATCH HEX(__CODEGEARC_VERSION__ & 0xFFFF) + +#elif defined(__BORLANDC__) +# define COMPILER_ID "Borland" + /* __BORLANDC__ = 0xVRR */ +# define COMPILER_VERSION_MAJOR HEX(__BORLANDC__>>8) +# define COMPILER_VERSION_MINOR HEX(__BORLANDC__ & 0xFF) + +#elif defined(__WATCOMC__) +# define COMPILER_ID "Watcom" + /* __WATCOMC__ = VVRR */ +# define COMPILER_VERSION_MAJOR DEC(__WATCOMC__ / 100) +# define COMPILER_VERSION_MINOR DEC(__WATCOMC__ % 100) + +#elif defined(__SUNPRO_C) +# define COMPILER_ID "SunPro" +# if __SUNPRO_C >= 0x5100 + /* __SUNPRO_C = 0xVRRP */ +# define COMPILER_VERSION_MAJOR HEX(__SUNPRO_C>>12) +# define COMPILER_VERSION_MINOR HEX(__SUNPRO_C>>4 & 0xFF) +# define COMPILER_VERSION_PATCH HEX(__SUNPRO_C & 0xF) +# else + /* __SUNPRO_C = 0xVRP */ +# define COMPILER_VERSION_MAJOR HEX(__SUNPRO_C>>8) +# define COMPILER_VERSION_MINOR HEX(__SUNPRO_C>>4 & 0xF) +# define COMPILER_VERSION_PATCH HEX(__SUNPRO_C & 0xF) +# endif + +#elif defined(__HP_cc) +# define COMPILER_ID "HP" + /* __HP_cc = VVRRPP */ +# define COMPILER_VERSION_MAJOR DEC(__HP_cc/10000) +# define COMPILER_VERSION_MINOR DEC(__HP_cc/100 % 100) +# define COMPILER_VERSION_PATCH DEC(__HP_cc % 100) + +#elif defined(__DECC) +# define COMPILER_ID "Compaq" + /* __DECC_VER = VVRRTPPPP */ +# define COMPILER_VERSION_MAJOR DEC(__DECC_VER/10000000) +# define COMPILER_VERSION_MINOR DEC(__DECC_VER/100000 % 100) +# define COMPILER_VERSION_PATCH DEC(__DECC_VER % 10000) + +#elif defined(__IBMC__) +# if defined(__COMPILER_VER__) +# define COMPILER_ID "zOS" +# else +# if __IBMC__ >= 800 +# define COMPILER_ID "XL" +# else +# define COMPILER_ID "VisualAge" +# endif + /* __IBMC__ = VRP */ +# define COMPILER_VERSION_MAJOR DEC(__IBMC__/100) +# define COMPILER_VERSION_MINOR DEC(__IBMC__/10 % 10) +# define COMPILER_VERSION_PATCH DEC(__IBMC__ % 10) +# endif + +#elif defined(__PGI) +# define COMPILER_ID "PGI" +# define COMPILER_VERSION_MAJOR DEC(__PGIC__) +# define COMPILER_VERSION_MINOR DEC(__PGIC_MINOR__) +# if defined(__PGIC_PATCHLEVEL__) +# define COMPILER_VERSION_PATCH DEC(__PGIC_PATCHLEVEL__) +# endif + +#elif defined(_CRAYC) +# define COMPILER_ID "Cray" +# define COMPILER_VERSION_MAJOR DEC(_RELEASE) +# define COMPILER_VERSION_MINOR DEC(_RELEASE_MINOR) + +#elif defined(__TI_COMPILER_VERSION__) +# define COMPILER_ID "TI" + /* __TI_COMPILER_VERSION__ = VVVRRRPPP */ +# define COMPILER_VERSION_MAJOR DEC(__TI_COMPILER_VERSION__/1000000) +# define COMPILER_VERSION_MINOR DEC(__TI_COMPILER_VERSION__/1000 % 1000) +# define COMPILER_VERSION_PATCH DEC(__TI_COMPILER_VERSION__ % 1000) + +#elif defined(__TINYC__) +# define COMPILER_ID "TinyCC" + +#elif defined(__SCO_VERSION__) +# define COMPILER_ID "SCO" + +#elif defined(__GNUC__) +# define COMPILER_ID "GNU" +# define COMPILER_VERSION_MAJOR DEC(__GNUC__) +# define COMPILER_VERSION_MINOR DEC(__GNUC_MINOR__) +# if defined(__GNUC_PATCHLEVEL__) +# define COMPILER_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__) +# endif + +#elif defined(_MSC_VER) +# define COMPILER_ID "MSVC" + /* _MSC_VER = VVRR */ +# define COMPILER_VERSION_MAJOR DEC(_MSC_VER / 100) +# define COMPILER_VERSION_MINOR DEC(_MSC_VER % 100) +# if defined(_MSC_FULL_VER) +# if _MSC_VER >= 1400 + /* _MSC_FULL_VER = VVRRPPPPP */ +# define COMPILER_VERSION_PATCH DEC(_MSC_FULL_VER % 100000) +# else + /* _MSC_FULL_VER = VVRRPPPP */ +# define COMPILER_VERSION_PATCH DEC(_MSC_FULL_VER % 10000) +# endif +# endif +# if defined(_MSC_BUILD) +# define COMPILER_VERSION_TWEAK DEC(_MSC_BUILD) +# endif + +/* Analog VisualDSP++ >= 4.5.6 */ +#elif defined(__VISUALDSPVERSION__) +# define COMPILER_ID "ADSP" + /* __VISUALDSPVERSION__ = 0xVVRRPP00 */ +# define COMPILER_VERSION_MAJOR HEX(__VISUALDSPVERSION__>>24) +# define COMPILER_VERSION_MINOR HEX(__VISUALDSPVERSION__>>16 & 0xFF) +# define COMPILER_VERSION_PATCH HEX(__VISUALDSPVERSION__>>8 & 0xFF) + +/* Analog VisualDSP++ < 4.5.6 */ +#elif defined(__ADSPBLACKFIN__) || defined(__ADSPTS__) || defined(__ADSP21000__) +# define COMPILER_ID "ADSP" + +/* IAR Systems compiler for embedded systems. + http://www.iar.com */ +#elif defined(__IAR_SYSTEMS_ICC__ ) || defined(__IAR_SYSTEMS_ICC) +# define COMPILER_ID "IAR" + +/* sdcc, the small devices C compiler for embedded systems, + http://sdcc.sourceforge.net */ +#elif defined(SDCC) +# define COMPILER_ID "SDCC" + /* SDCC = VRP */ +# define COMPILER_VERSION_MAJOR DEC(SDCC/100) +# define COMPILER_VERSION_MINOR DEC(SDCC/10 % 10) +# define COMPILER_VERSION_PATCH DEC(SDCC % 10) + +#elif defined(_SGI_COMPILER_VERSION) || defined(_COMPILER_VERSION) +# define COMPILER_ID "MIPSpro" +# if defined(_SGI_COMPILER_VERSION) + /* _SGI_COMPILER_VERSION = VRP */ +# define COMPILER_VERSION_MAJOR DEC(_SGI_COMPILER_VERSION/100) +# define COMPILER_VERSION_MINOR DEC(_SGI_COMPILER_VERSION/10 % 10) +# define COMPILER_VERSION_PATCH DEC(_SGI_COMPILER_VERSION % 10) +# else + /* _COMPILER_VERSION = VRP */ +# define COMPILER_VERSION_MAJOR DEC(_COMPILER_VERSION/100) +# define COMPILER_VERSION_MINOR DEC(_COMPILER_VERSION/10 % 10) +# define COMPILER_VERSION_PATCH DEC(_COMPILER_VERSION % 10) +# endif + +/* This compiler is either not known or is too old to define an + identification macro. Try to identify the platform and guess that + it is the native compiler. */ +#elif defined(__sgi) +# define COMPILER_ID "MIPSpro" + +#elif defined(__hpux) || defined(__hpua) +# define COMPILER_ID "HP" + +#else /* unknown compiler */ +# define COMPILER_ID "" + +#endif + +/* Construct the string literal in pieces to prevent the source from + getting matched. Store it in a pointer rather than an array + because some compilers will just produce instructions to fill the + array rather than assigning a pointer to a static array. */ +char const* info_compiler = "INFO" ":" "compiler[" COMPILER_ID "]"; + +/* Identify known platforms by name. */ +#if defined(__linux) || defined(__linux__) || defined(linux) +# define PLATFORM_ID "Linux" + +#elif defined(__CYGWIN__) +# define PLATFORM_ID "Cygwin" + +#elif defined(__MINGW32__) +# define PLATFORM_ID "MinGW" + +#elif defined(__APPLE__) +# define PLATFORM_ID "Darwin" + +#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32) +# define PLATFORM_ID "Windows" + +#elif defined(__FreeBSD__) || defined(__FreeBSD) +# define PLATFORM_ID "FreeBSD" + +#elif defined(__NetBSD__) || defined(__NetBSD) +# define PLATFORM_ID "NetBSD" + +#elif defined(__OpenBSD__) || defined(__OPENBSD) +# define PLATFORM_ID "OpenBSD" + +#elif defined(__sun) || defined(sun) +# define PLATFORM_ID "SunOS" + +#elif defined(_AIX) || defined(__AIX) || defined(__AIX__) || defined(__aix) || defined(__aix__) +# define PLATFORM_ID "AIX" + +#elif defined(__sgi) || defined(__sgi__) || defined(_SGI) +# define PLATFORM_ID "IRIX" + +#elif defined(__hpux) || defined(__hpux__) +# define PLATFORM_ID "HP-UX" + +#elif defined(__HAIKU__) +# define PLATFORM_ID "Haiku" + +#elif defined(__BeOS) || defined(__BEOS__) || defined(_BEOS) +# define PLATFORM_ID "BeOS" + +#elif defined(__QNX__) || defined(__QNXNTO__) +# define PLATFORM_ID "QNX" + +#elif defined(__tru64) || defined(_tru64) || defined(__TRU64__) +# define PLATFORM_ID "Tru64" + +#elif defined(__riscos) || defined(__riscos__) +# define PLATFORM_ID "RISCos" + +#elif defined(__sinix) || defined(__sinix__) || defined(__SINIX__) +# define PLATFORM_ID "SINIX" + +#elif defined(__UNIX_SV__) +# define PLATFORM_ID "UNIX_SV" + +#elif defined(__bsdos__) +# define PLATFORM_ID "BSDOS" + +#elif defined(_MPRAS) || defined(MPRAS) +# define PLATFORM_ID "MP-RAS" + +#elif defined(__osf) || defined(__osf__) +# define PLATFORM_ID "OSF1" + +#elif defined(_SCO_SV) || defined(SCO_SV) || defined(sco_sv) +# define PLATFORM_ID "SCO_SV" + +#elif defined(__ultrix) || defined(__ultrix__) || defined(_ULTRIX) +# define PLATFORM_ID "ULTRIX" + +#elif defined(__XENIX__) || defined(_XENIX) || defined(XENIX) +# define PLATFORM_ID "Xenix" + +#else /* unknown platform */ +# define PLATFORM_ID "" + +#endif + +/* For windows compilers MSVC and Intel we can determine + the architecture of the compiler being used. This is because + the compilers do not have flags that can change the architecture, + but rather depend on which compiler is being used +*/ +#if defined(_WIN32) && defined(_MSC_VER) +# if defined(_M_IA64) +# define ARCHITECTURE_ID "IA64" + +# elif defined(_M_X64) || defined(_M_AMD64) +# define ARCHITECTURE_ID "x64" + +# elif defined(_M_IX86) +# define ARCHITECTURE_ID "X86" + +# elif defined(_M_ARM) +# define ARCHITECTURE_ID "ARM" + +# elif defined(_M_MIPS) +# define ARCHITECTURE_ID "MIPS" + +# elif defined(_M_SH) +# define ARCHITECTURE_ID "SHx" + +# else /* unknown architecture */ +# define ARCHITECTURE_ID "" +# endif + +#else +# define ARCHITECTURE_ID "" +#endif + +/* Convert integer to decimal digit literals. */ +#define DEC(n) \ + ('0' + (((n) / 10000000)%10)), \ + ('0' + (((n) / 1000000)%10)), \ + ('0' + (((n) / 100000)%10)), \ + ('0' + (((n) / 10000)%10)), \ + ('0' + (((n) / 1000)%10)), \ + ('0' + (((n) / 100)%10)), \ + ('0' + (((n) / 10)%10)), \ + ('0' + ((n) % 10)) + +/* Convert integer to hex digit literals. */ +#define HEX(n) \ + ('0' + ((n)>>28 & 0xF)), \ + ('0' + ((n)>>24 & 0xF)), \ + ('0' + ((n)>>20 & 0xF)), \ + ('0' + ((n)>>16 & 0xF)), \ + ('0' + ((n)>>12 & 0xF)), \ + ('0' + ((n)>>8 & 0xF)), \ + ('0' + ((n)>>4 & 0xF)), \ + ('0' + ((n) & 0xF)) + +/* Construct a string literal encoding the version number components. */ +#ifdef COMPILER_VERSION_MAJOR +char const info_version[] = { + 'I', 'N', 'F', 'O', ':', + 'c','o','m','p','i','l','e','r','_','v','e','r','s','i','o','n','[', + COMPILER_VERSION_MAJOR, +# ifdef COMPILER_VERSION_MINOR + '.', COMPILER_VERSION_MINOR, +# ifdef COMPILER_VERSION_PATCH + '.', COMPILER_VERSION_PATCH, +# ifdef COMPILER_VERSION_TWEAK + '.', COMPILER_VERSION_TWEAK, +# endif +# endif +# endif + ']','\0'}; +#endif + +/* Construct the string literal in pieces to prevent the source from + getting matched. Store it in a pointer rather than an array + because some compilers will just produce instructions to fill the + array rather than assigning a pointer to a static array. */ +char const* info_platform = "INFO" ":" "platform[" PLATFORM_ID "]"; +char const* info_arch = "INFO" ":" "arch[" ARCHITECTURE_ID "]"; + + + +/*--------------------------------------------------------------------------*/ + +#ifdef ID_VOID_MAIN +void main() {} +#else +int main(int argc, char* argv[]) +{ + int require = 0; + require += info_compiler[argc]; + require += info_platform[argc]; + require += info_arch[argc]; +#ifdef COMPILER_VERSION_MAJOR + require += info_version[argc]; +#endif + (void)argv; + return require; +} +#endif diff --git a/external_src/raspicam-0.1.3/build/CMakeFiles/2.8.12.2/CompilerIdC/a.out b/external_src/raspicam-0.1.3/build/CMakeFiles/2.8.12.2/CompilerIdC/a.out new file mode 100755 index 0000000..a45b789 Binary files /dev/null and b/external_src/raspicam-0.1.3/build/CMakeFiles/2.8.12.2/CompilerIdC/a.out differ diff --git a/external_src/raspicam-0.1.3/build/CMakeFiles/2.8.12.2/CompilerIdCXX/CMakeCXXCompilerId.cpp b/external_src/raspicam-0.1.3/build/CMakeFiles/2.8.12.2/CompilerIdCXX/CMakeCXXCompilerId.cpp new file mode 100644 index 0000000..e8220b2 --- /dev/null +++ b/external_src/raspicam-0.1.3/build/CMakeFiles/2.8.12.2/CompilerIdCXX/CMakeCXXCompilerId.cpp @@ -0,0 +1,377 @@ +/* This source file must have a .cpp extension so that all C++ compilers + recognize the extension without flags. Borland does not know .cxx for + example. */ +#ifndef __cplusplus +# error "A C compiler has been selected for C++." +#endif + +/* Version number components: V=Version, R=Revision, P=Patch + Version date components: YYYY=Year, MM=Month, DD=Day */ + +#if defined(__COMO__) +# define COMPILER_ID "Comeau" + /* __COMO_VERSION__ = VRR */ +# define COMPILER_VERSION_MAJOR DEC(__COMO_VERSION__ / 100) +# define COMPILER_VERSION_MINOR DEC(__COMO_VERSION__ % 100) + +#elif defined(__INTEL_COMPILER) || defined(__ICC) +# define COMPILER_ID "Intel" + /* __INTEL_COMPILER = VRP */ +# define COMPILER_VERSION_MAJOR DEC(__INTEL_COMPILER/100) +# define COMPILER_VERSION_MINOR DEC(__INTEL_COMPILER/10 % 10) +# define COMPILER_VERSION_PATCH DEC(__INTEL_COMPILER % 10) +# if defined(__INTEL_COMPILER_BUILD_DATE) + /* __INTEL_COMPILER_BUILD_DATE = YYYYMMDD */ +# define COMPILER_VERSION_TWEAK DEC(__INTEL_COMPILER_BUILD_DATE) +# endif + +#elif defined(__PATHCC__) +# define COMPILER_ID "PathScale" +# define COMPILER_VERSION_MAJOR DEC(__PATHCC__) +# define COMPILER_VERSION_MINOR DEC(__PATHCC_MINOR__) +# if defined(__PATHCC_PATCHLEVEL__) +# define COMPILER_VERSION_PATCH DEC(__PATHCC_PATCHLEVEL__) +# endif + +#elif defined(__clang__) +# define COMPILER_ID "Clang" +# define COMPILER_VERSION_MAJOR DEC(__clang_major__) +# define COMPILER_VERSION_MINOR DEC(__clang_minor__) +# define COMPILER_VERSION_PATCH DEC(__clang_patchlevel__) + +#elif defined(__BORLANDC__) && defined(__CODEGEARC_VERSION__) +# define COMPILER_ID "Embarcadero" +# define COMPILER_VERSION_MAJOR HEX(__CODEGEARC_VERSION__>>24 & 0x00FF) +# define COMPILER_VERSION_MINOR HEX(__CODEGEARC_VERSION__>>16 & 0x00FF) +# define COMPILER_VERSION_PATCH HEX(__CODEGEARC_VERSION__ & 0xFFFF) + +#elif defined(__BORLANDC__) +# define COMPILER_ID "Borland" + /* __BORLANDC__ = 0xVRR */ +# define COMPILER_VERSION_MAJOR HEX(__BORLANDC__>>8) +# define COMPILER_VERSION_MINOR HEX(__BORLANDC__ & 0xFF) + +#elif defined(__WATCOMC__) +# define COMPILER_ID "Watcom" + /* __WATCOMC__ = VVRR */ +# define COMPILER_VERSION_MAJOR DEC(__WATCOMC__ / 100) +# define COMPILER_VERSION_MINOR DEC(__WATCOMC__ % 100) + +#elif defined(__SUNPRO_CC) +# define COMPILER_ID "SunPro" +# if __SUNPRO_CC >= 0x5100 + /* __SUNPRO_CC = 0xVRRP */ +# define COMPILER_VERSION_MAJOR HEX(__SUNPRO_CC>>12) +# define COMPILER_VERSION_MINOR HEX(__SUNPRO_CC>>4 & 0xFF) +# define COMPILER_VERSION_PATCH HEX(__SUNPRO_CC & 0xF) +# else + /* __SUNPRO_CC = 0xVRP */ +# define COMPILER_VERSION_MAJOR HEX(__SUNPRO_CC>>8) +# define COMPILER_VERSION_MINOR HEX(__SUNPRO_CC>>4 & 0xF) +# define COMPILER_VERSION_PATCH HEX(__SUNPRO_CC & 0xF) +# endif + +#elif defined(__HP_aCC) +# define COMPILER_ID "HP" + /* __HP_aCC = VVRRPP */ +# define COMPILER_VERSION_MAJOR DEC(__HP_aCC/10000) +# define COMPILER_VERSION_MINOR DEC(__HP_aCC/100 % 100) +# define COMPILER_VERSION_PATCH DEC(__HP_aCC % 100) + +#elif defined(__DECCXX) +# define COMPILER_ID "Compaq" + /* __DECCXX_VER = VVRRTPPPP */ +# define COMPILER_VERSION_MAJOR DEC(__DECCXX_VER/10000000) +# define COMPILER_VERSION_MINOR DEC(__DECCXX_VER/100000 % 100) +# define COMPILER_VERSION_PATCH DEC(__DECCXX_VER % 10000) + +#elif defined(__IBMCPP__) +# if defined(__COMPILER_VER__) +# define COMPILER_ID "zOS" +# else +# if __IBMCPP__ >= 800 +# define COMPILER_ID "XL" +# else +# define COMPILER_ID "VisualAge" +# endif + /* __IBMCPP__ = VRP */ +# define COMPILER_VERSION_MAJOR DEC(__IBMCPP__/100) +# define COMPILER_VERSION_MINOR DEC(__IBMCPP__/10 % 10) +# define COMPILER_VERSION_PATCH DEC(__IBMCPP__ % 10) +# endif + +#elif defined(__PGI) +# define COMPILER_ID "PGI" +# define COMPILER_VERSION_MAJOR DEC(__PGIC__) +# define COMPILER_VERSION_MINOR DEC(__PGIC_MINOR__) +# if defined(__PGIC_PATCHLEVEL__) +# define COMPILER_VERSION_PATCH DEC(__PGIC_PATCHLEVEL__) +# endif + +#elif defined(_CRAYC) +# define COMPILER_ID "Cray" +# define COMPILER_VERSION_MAJOR DEC(_RELEASE) +# define COMPILER_VERSION_MINOR DEC(_RELEASE_MINOR) + +#elif defined(__TI_COMPILER_VERSION__) +# define COMPILER_ID "TI" + /* __TI_COMPILER_VERSION__ = VVVRRRPPP */ +# define COMPILER_VERSION_MAJOR DEC(__TI_COMPILER_VERSION__/1000000) +# define COMPILER_VERSION_MINOR DEC(__TI_COMPILER_VERSION__/1000 % 1000) +# define COMPILER_VERSION_PATCH DEC(__TI_COMPILER_VERSION__ % 1000) + +#elif defined(__SCO_VERSION__) +# define COMPILER_ID "SCO" + +#elif defined(__GNUC__) +# define COMPILER_ID "GNU" +# define COMPILER_VERSION_MAJOR DEC(__GNUC__) +# define COMPILER_VERSION_MINOR DEC(__GNUC_MINOR__) +# if defined(__GNUC_PATCHLEVEL__) +# define COMPILER_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__) +# endif + +#elif defined(_MSC_VER) +# define COMPILER_ID "MSVC" + /* _MSC_VER = VVRR */ +# define COMPILER_VERSION_MAJOR DEC(_MSC_VER / 100) +# define COMPILER_VERSION_MINOR DEC(_MSC_VER % 100) +# if defined(_MSC_FULL_VER) +# if _MSC_VER >= 1400 + /* _MSC_FULL_VER = VVRRPPPPP */ +# define COMPILER_VERSION_PATCH DEC(_MSC_FULL_VER % 100000) +# else + /* _MSC_FULL_VER = VVRRPPPP */ +# define COMPILER_VERSION_PATCH DEC(_MSC_FULL_VER % 10000) +# endif +# endif +# if defined(_MSC_BUILD) +# define COMPILER_VERSION_TWEAK DEC(_MSC_BUILD) +# endif + +/* Analog VisualDSP++ >= 4.5.6 */ +#elif defined(__VISUALDSPVERSION__) +# define COMPILER_ID "ADSP" + /* __VISUALDSPVERSION__ = 0xVVRRPP00 */ +# define COMPILER_VERSION_MAJOR HEX(__VISUALDSPVERSION__>>24) +# define COMPILER_VERSION_MINOR HEX(__VISUALDSPVERSION__>>16 & 0xFF) +# define COMPILER_VERSION_PATCH HEX(__VISUALDSPVERSION__>>8 & 0xFF) + +/* Analog VisualDSP++ < 4.5.6 */ +#elif defined(__ADSPBLACKFIN__) || defined(__ADSPTS__) || defined(__ADSP21000__) +# define COMPILER_ID "ADSP" + +/* IAR Systems compiler for embedded systems. + http://www.iar.com */ +#elif defined(__IAR_SYSTEMS_ICC__ ) || defined(__IAR_SYSTEMS_ICC) +# define COMPILER_ID "IAR" + +#elif defined(_SGI_COMPILER_VERSION) || defined(_COMPILER_VERSION) +# define COMPILER_ID "MIPSpro" +# if defined(_SGI_COMPILER_VERSION) + /* _SGI_COMPILER_VERSION = VRP */ +# define COMPILER_VERSION_MAJOR DEC(_SGI_COMPILER_VERSION/100) +# define COMPILER_VERSION_MINOR DEC(_SGI_COMPILER_VERSION/10 % 10) +# define COMPILER_VERSION_PATCH DEC(_SGI_COMPILER_VERSION % 10) +# else + /* _COMPILER_VERSION = VRP */ +# define COMPILER_VERSION_MAJOR DEC(_COMPILER_VERSION/100) +# define COMPILER_VERSION_MINOR DEC(_COMPILER_VERSION/10 % 10) +# define COMPILER_VERSION_PATCH DEC(_COMPILER_VERSION % 10) +# endif + +/* This compiler is either not known or is too old to define an + identification macro. Try to identify the platform and guess that + it is the native compiler. */ +#elif defined(__sgi) +# define COMPILER_ID "MIPSpro" + +#elif defined(__hpux) || defined(__hpua) +# define COMPILER_ID "HP" + +#else /* unknown compiler */ +# define COMPILER_ID "" + +#endif + +/* Construct the string literal in pieces to prevent the source from + getting matched. Store it in a pointer rather than an array + because some compilers will just produce instructions to fill the + array rather than assigning a pointer to a static array. */ +char const* info_compiler = "INFO" ":" "compiler[" COMPILER_ID "]"; + +/* Identify known platforms by name. */ +#if defined(__linux) || defined(__linux__) || defined(linux) +# define PLATFORM_ID "Linux" + +#elif defined(__CYGWIN__) +# define PLATFORM_ID "Cygwin" + +#elif defined(__MINGW32__) +# define PLATFORM_ID "MinGW" + +#elif defined(__APPLE__) +# define PLATFORM_ID "Darwin" + +#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32) +# define PLATFORM_ID "Windows" + +#elif defined(__FreeBSD__) || defined(__FreeBSD) +# define PLATFORM_ID "FreeBSD" + +#elif defined(__NetBSD__) || defined(__NetBSD) +# define PLATFORM_ID "NetBSD" + +#elif defined(__OpenBSD__) || defined(__OPENBSD) +# define PLATFORM_ID "OpenBSD" + +#elif defined(__sun) || defined(sun) +# define PLATFORM_ID "SunOS" + +#elif defined(_AIX) || defined(__AIX) || defined(__AIX__) || defined(__aix) || defined(__aix__) +# define PLATFORM_ID "AIX" + +#elif defined(__sgi) || defined(__sgi__) || defined(_SGI) +# define PLATFORM_ID "IRIX" + +#elif defined(__hpux) || defined(__hpux__) +# define PLATFORM_ID "HP-UX" + +#elif defined(__HAIKU__) +# define PLATFORM_ID "Haiku" + +#elif defined(__BeOS) || defined(__BEOS__) || defined(_BEOS) +# define PLATFORM_ID "BeOS" + +#elif defined(__QNX__) || defined(__QNXNTO__) +# define PLATFORM_ID "QNX" + +#elif defined(__tru64) || defined(_tru64) || defined(__TRU64__) +# define PLATFORM_ID "Tru64" + +#elif defined(__riscos) || defined(__riscos__) +# define PLATFORM_ID "RISCos" + +#elif defined(__sinix) || defined(__sinix__) || defined(__SINIX__) +# define PLATFORM_ID "SINIX" + +#elif defined(__UNIX_SV__) +# define PLATFORM_ID "UNIX_SV" + +#elif defined(__bsdos__) +# define PLATFORM_ID "BSDOS" + +#elif defined(_MPRAS) || defined(MPRAS) +# define PLATFORM_ID "MP-RAS" + +#elif defined(__osf) || defined(__osf__) +# define PLATFORM_ID "OSF1" + +#elif defined(_SCO_SV) || defined(SCO_SV) || defined(sco_sv) +# define PLATFORM_ID "SCO_SV" + +#elif defined(__ultrix) || defined(__ultrix__) || defined(_ULTRIX) +# define PLATFORM_ID "ULTRIX" + +#elif defined(__XENIX__) || defined(_XENIX) || defined(XENIX) +# define PLATFORM_ID "Xenix" + +#else /* unknown platform */ +# define PLATFORM_ID "" + +#endif + +/* For windows compilers MSVC and Intel we can determine + the architecture of the compiler being used. This is because + the compilers do not have flags that can change the architecture, + but rather depend on which compiler is being used +*/ +#if defined(_WIN32) && defined(_MSC_VER) +# if defined(_M_IA64) +# define ARCHITECTURE_ID "IA64" + +# elif defined(_M_X64) || defined(_M_AMD64) +# define ARCHITECTURE_ID "x64" + +# elif defined(_M_IX86) +# define ARCHITECTURE_ID "X86" + +# elif defined(_M_ARM) +# define ARCHITECTURE_ID "ARM" + +# elif defined(_M_MIPS) +# define ARCHITECTURE_ID "MIPS" + +# elif defined(_M_SH) +# define ARCHITECTURE_ID "SHx" + +# else /* unknown architecture */ +# define ARCHITECTURE_ID "" +# endif + +#else +# define ARCHITECTURE_ID "" +#endif + +/* Convert integer to decimal digit literals. */ +#define DEC(n) \ + ('0' + (((n) / 10000000)%10)), \ + ('0' + (((n) / 1000000)%10)), \ + ('0' + (((n) / 100000)%10)), \ + ('0' + (((n) / 10000)%10)), \ + ('0' + (((n) / 1000)%10)), \ + ('0' + (((n) / 100)%10)), \ + ('0' + (((n) / 10)%10)), \ + ('0' + ((n) % 10)) + +/* Convert integer to hex digit literals. */ +#define HEX(n) \ + ('0' + ((n)>>28 & 0xF)), \ + ('0' + ((n)>>24 & 0xF)), \ + ('0' + ((n)>>20 & 0xF)), \ + ('0' + ((n)>>16 & 0xF)), \ + ('0' + ((n)>>12 & 0xF)), \ + ('0' + ((n)>>8 & 0xF)), \ + ('0' + ((n)>>4 & 0xF)), \ + ('0' + ((n) & 0xF)) + +/* Construct a string literal encoding the version number components. */ +#ifdef COMPILER_VERSION_MAJOR +char const info_version[] = { + 'I', 'N', 'F', 'O', ':', + 'c','o','m','p','i','l','e','r','_','v','e','r','s','i','o','n','[', + COMPILER_VERSION_MAJOR, +# ifdef COMPILER_VERSION_MINOR + '.', COMPILER_VERSION_MINOR, +# ifdef COMPILER_VERSION_PATCH + '.', COMPILER_VERSION_PATCH, +# ifdef COMPILER_VERSION_TWEAK + '.', COMPILER_VERSION_TWEAK, +# endif +# endif +# endif + ']','\0'}; +#endif + +/* Construct the string literal in pieces to prevent the source from + getting matched. Store it in a pointer rather than an array + because some compilers will just produce instructions to fill the + array rather than assigning a pointer to a static array. */ +char const* info_platform = "INFO" ":" "platform[" PLATFORM_ID "]"; +char const* info_arch = "INFO" ":" "arch[" ARCHITECTURE_ID "]"; + + + +/*--------------------------------------------------------------------------*/ + +int main(int argc, char* argv[]) +{ + int require = 0; + require += info_compiler[argc]; + require += info_platform[argc]; +#ifdef COMPILER_VERSION_MAJOR + require += info_version[argc]; +#endif + (void)argv; + return require; +} diff --git a/external_src/raspicam-0.1.3/build/CMakeFiles/2.8.12.2/CompilerIdCXX/a.out b/external_src/raspicam-0.1.3/build/CMakeFiles/2.8.12.2/CompilerIdCXX/a.out new file mode 100755 index 0000000..8b271d6 Binary files /dev/null and b/external_src/raspicam-0.1.3/build/CMakeFiles/2.8.12.2/CompilerIdCXX/a.out differ diff --git a/external_src/raspicam-0.1.3/build/CMakeFiles/CMakeDirectoryInformation.cmake b/external_src/raspicam-0.1.3/build/CMakeFiles/CMakeDirectoryInformation.cmake new file mode 100644 index 0000000..24120d7 --- /dev/null +++ b/external_src/raspicam-0.1.3/build/CMakeFiles/CMakeDirectoryInformation.cmake @@ -0,0 +1,16 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +# Relative path conversion top directories. +SET(CMAKE_RELATIVE_PATH_TOP_SOURCE "/home/ubuntu/Nomad/external_src/raspicam-0.1.3") +SET(CMAKE_RELATIVE_PATH_TOP_BINARY "/home/ubuntu/Nomad/external_src/raspicam-0.1.3/build") + +# Force unix paths in dependencies. +SET(CMAKE_FORCE_UNIX_PATHS 1) + + +# The C and CXX include file regular expressions for this directory. +SET(CMAKE_C_INCLUDE_REGEX_SCAN "^.*$") +SET(CMAKE_C_INCLUDE_REGEX_COMPLAIN "^$") +SET(CMAKE_CXX_INCLUDE_REGEX_SCAN ${CMAKE_C_INCLUDE_REGEX_SCAN}) +SET(CMAKE_CXX_INCLUDE_REGEX_COMPLAIN ${CMAKE_C_INCLUDE_REGEX_COMPLAIN}) diff --git a/external_src/raspicam-0.1.3/build/CMakeFiles/CMakeOutput.log b/external_src/raspicam-0.1.3/build/CMakeFiles/CMakeOutput.log new file mode 100644 index 0000000..28a3e1e --- /dev/null +++ b/external_src/raspicam-0.1.3/build/CMakeFiles/CMakeOutput.log @@ -0,0 +1,265 @@ +The system is: Linux - 3.18.0-20-rpi2 - armv7l +Compiling the C compiler identification source file "CMakeCCompilerId.c" succeeded. +Compiler: /usr/bin/cc +Build flags: +Id flags: + +The output was: +0 + + +Compilation of the C compiler identification source "CMakeCCompilerId.c" produced "a.out" + +The C compiler identification is GNU, found in "/home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/CMakeFiles/2.8.12.2/CompilerIdC/a.out" + +Compiling the CXX compiler identification source file "CMakeCXXCompilerId.cpp" succeeded. +Compiler: /usr/bin/c++ +Build flags: +Id flags: + +The output was: +0 + + +Compilation of the CXX compiler identification source "CMakeCXXCompilerId.cpp" produced "a.out" + +The CXX compiler identification is GNU, found in "/home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/CMakeFiles/2.8.12.2/CompilerIdCXX/a.out" + +Determining if the C compiler works passed with the following output: +Change Dir: /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/CMakeFiles/CMakeTmp + +Run Build Command:/usr/bin/make "cmTryCompileExec2659741268/fast" +/usr/bin/make -f CMakeFiles/cmTryCompileExec2659741268.dir/build.make CMakeFiles/cmTryCompileExec2659741268.dir/build +make[1]: Entering directory `/home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/CMakeFiles/CMakeTmp' +/usr/bin/cmake -E cmake_progress_report /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/CMakeFiles/CMakeTmp/CMakeFiles 1 +Building C object CMakeFiles/cmTryCompileExec2659741268.dir/testCCompiler.c.o +/usr/bin/cc -o CMakeFiles/cmTryCompileExec2659741268.dir/testCCompiler.c.o -c /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/CMakeFiles/CMakeTmp/testCCompiler.c +Linking C executable cmTryCompileExec2659741268 +/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTryCompileExec2659741268.dir/link.txt --verbose=1 +/usr/bin/cc CMakeFiles/cmTryCompileExec2659741268.dir/testCCompiler.c.o -o cmTryCompileExec2659741268 -rdynamic +make[1]: Leaving directory `/home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/CMakeFiles/CMakeTmp' + + +Detecting C compiler ABI info compiled with the following output: +Change Dir: /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/CMakeFiles/CMakeTmp + +Run Build Command:/usr/bin/make "cmTryCompileExec781799643/fast" +/usr/bin/make -f CMakeFiles/cmTryCompileExec781799643.dir/build.make CMakeFiles/cmTryCompileExec781799643.dir/build +make[1]: Entering directory `/home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/CMakeFiles/CMakeTmp' +/usr/bin/cmake -E cmake_progress_report /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/CMakeFiles/CMakeTmp/CMakeFiles 1 +Building C object CMakeFiles/cmTryCompileExec781799643.dir/CMakeCCompilerABI.c.o +/usr/bin/cc -o CMakeFiles/cmTryCompileExec781799643.dir/CMakeCCompilerABI.c.o -c /usr/share/cmake-2.8/Modules/CMakeCCompilerABI.c +Linking C executable cmTryCompileExec781799643 +/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTryCompileExec781799643.dir/link.txt --verbose=1 +/usr/bin/cc -v CMakeFiles/cmTryCompileExec781799643.dir/CMakeCCompilerABI.c.o -o cmTryCompileExec781799643 -rdynamic +Using built-in specs. +COLLECT_GCC=/usr/bin/cc +COLLECT_LTO_WRAPPER=/usr/lib/gcc/arm-linux-gnueabihf/4.8/lto-wrapper +Target: arm-linux-gnueabihf +Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.8.4-2ubuntu1~14.04' --with-bugurl=file:///usr/share/doc/gcc-4.8/README.Bugs --enable-languages=c,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.8 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.8 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --disable-libmudflap --disable-libitm --disable-libquadmath --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-4.8-armhf/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-4.8-armhf --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-4.8-armhf --with-arch-directory=arm --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc --enable-multiarch --enable-multilib --disable-sjlj-exceptions --with-arch=armv7-a --with-fpu=vfpv3-d16 --with-float=hard --with-mode=thumb --disable-werror --enable-checking=release --build=arm-linux-gnueabihf --host=arm-linux-gnueabihf --target=arm-linux-gnueabihf +Thread model: posix +gcc version 4.8.4 (Ubuntu/Linaro 4.8.4-2ubuntu1~14.04) +COMPILER_PATH=/usr/lib/gcc/arm-linux-gnueabihf/4.8/:/usr/lib/gcc/arm-linux-gnueabihf/4.8/:/usr/lib/gcc/arm-linux-gnueabihf/:/usr/lib/gcc/arm-linux-gnueabihf/4.8/:/usr/lib/gcc/arm-linux-gnueabihf/ +LIBRARY_PATH=/usr/lib/gcc/arm-linux-gnueabihf/4.8/:/usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf/:/usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../../lib/:/lib/arm-linux-gnueabihf/:/lib/../lib/:/usr/lib/arm-linux-gnueabihf/:/usr/lib/../lib/:/usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../:/lib/:/usr/lib/ +COLLECT_GCC_OPTIONS='-v' '-o' 'cmTryCompileExec781799643' '-rdynamic' '-march=armv7-a' '-mfloat-abi=hard' '-mfpu=vfpv3-d16' '-mthumb' '-mtls-dialect=gnu' + /usr/lib/gcc/arm-linux-gnueabihf/4.8/collect2 --sysroot=/ --build-id --eh-frame-hdr -export-dynamic -dynamic-linker /lib/ld-linux-armhf.so.3 -X --hash-style=gnu --as-needed -m armelf_linux_eabi -z relro -o cmTryCompileExec781799643 /usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf/crt1.o /usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf/crti.o /usr/lib/gcc/arm-linux-gnueabihf/4.8/crtbegin.o -L/usr/lib/gcc/arm-linux-gnueabihf/4.8 -L/usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf -L/usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../../lib -L/lib/arm-linux-gnueabihf -L/lib/../lib -L/usr/lib/arm-linux-gnueabihf -L/usr/lib/../lib -L/usr/lib/gcc/arm-linux-gnueabihf/4.8/../../.. CMakeFiles/cmTryCompileExec781799643.dir/CMakeCCompilerABI.c.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/arm-linux-gnueabihf/4.8/crtend.o /usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf/crtn.o +make[1]: Leaving directory `/home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/CMakeFiles/CMakeTmp' + + +Parsed C implicit link information from above output: + link line regex: [^( *|.*[/\])(ld|([^/\]+-)?ld|collect2)[^/\]*( |$)] + ignore line: [Change Dir: /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/CMakeFiles/CMakeTmp] + ignore line: [] + ignore line: [Run Build Command:/usr/bin/make "cmTryCompileExec781799643/fast"] + ignore line: [/usr/bin/make -f CMakeFiles/cmTryCompileExec781799643.dir/build.make CMakeFiles/cmTryCompileExec781799643.dir/build] + ignore line: [make[1]: Entering directory `/home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/CMakeFiles/CMakeTmp'] + ignore line: [/usr/bin/cmake -E cmake_progress_report /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/CMakeFiles/CMakeTmp/CMakeFiles 1] + ignore line: [Building C object CMakeFiles/cmTryCompileExec781799643.dir/CMakeCCompilerABI.c.o] + ignore line: [/usr/bin/cc -o CMakeFiles/cmTryCompileExec781799643.dir/CMakeCCompilerABI.c.o -c /usr/share/cmake-2.8/Modules/CMakeCCompilerABI.c] + ignore line: [Linking C executable cmTryCompileExec781799643] + ignore line: [/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTryCompileExec781799643.dir/link.txt --verbose=1] + ignore line: [/usr/bin/cc -v CMakeFiles/cmTryCompileExec781799643.dir/CMakeCCompilerABI.c.o -o cmTryCompileExec781799643 -rdynamic ] + ignore line: [Using built-in specs.] + ignore line: [COLLECT_GCC=/usr/bin/cc] + ignore line: [COLLECT_LTO_WRAPPER=/usr/lib/gcc/arm-linux-gnueabihf/4.8/lto-wrapper] + ignore line: [Target: arm-linux-gnueabihf] + ignore line: [Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.8.4-2ubuntu1~14.04' --with-bugurl=file:///usr/share/doc/gcc-4.8/README.Bugs --enable-languages=c,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.8 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.8 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --disable-libmudflap --disable-libitm --disable-libquadmath --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-4.8-armhf/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-4.8-armhf --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-4.8-armhf --with-arch-directory=arm --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc --enable-multiarch --enable-multilib --disable-sjlj-exceptions --with-arch=armv7-a --with-fpu=vfpv3-d16 --with-float=hard --with-mode=thumb --disable-werror --enable-checking=release --build=arm-linux-gnueabihf --host=arm-linux-gnueabihf --target=arm-linux-gnueabihf] + ignore line: [Thread model: posix] + ignore line: [gcc version 4.8.4 (Ubuntu/Linaro 4.8.4-2ubuntu1~14.04) ] + ignore line: [COMPILER_PATH=/usr/lib/gcc/arm-linux-gnueabihf/4.8/:/usr/lib/gcc/arm-linux-gnueabihf/4.8/:/usr/lib/gcc/arm-linux-gnueabihf/:/usr/lib/gcc/arm-linux-gnueabihf/4.8/:/usr/lib/gcc/arm-linux-gnueabihf/] + ignore line: [LIBRARY_PATH=/usr/lib/gcc/arm-linux-gnueabihf/4.8/:/usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf/:/usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../../lib/:/lib/arm-linux-gnueabihf/:/lib/../lib/:/usr/lib/arm-linux-gnueabihf/:/usr/lib/../lib/:/usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../:/lib/:/usr/lib/] + ignore line: [COLLECT_GCC_OPTIONS='-v' '-o' 'cmTryCompileExec781799643' '-rdynamic' '-march=armv7-a' '-mfloat-abi=hard' '-mfpu=vfpv3-d16' '-mthumb' '-mtls-dialect=gnu'] + link line: [ /usr/lib/gcc/arm-linux-gnueabihf/4.8/collect2 --sysroot=/ --build-id --eh-frame-hdr -export-dynamic -dynamic-linker /lib/ld-linux-armhf.so.3 -X --hash-style=gnu --as-needed -m armelf_linux_eabi -z relro -o cmTryCompileExec781799643 /usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf/crt1.o /usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf/crti.o /usr/lib/gcc/arm-linux-gnueabihf/4.8/crtbegin.o -L/usr/lib/gcc/arm-linux-gnueabihf/4.8 -L/usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf -L/usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../../lib -L/lib/arm-linux-gnueabihf -L/lib/../lib -L/usr/lib/arm-linux-gnueabihf -L/usr/lib/../lib -L/usr/lib/gcc/arm-linux-gnueabihf/4.8/../../.. CMakeFiles/cmTryCompileExec781799643.dir/CMakeCCompilerABI.c.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/arm-linux-gnueabihf/4.8/crtend.o /usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf/crtn.o] + arg [/usr/lib/gcc/arm-linux-gnueabihf/4.8/collect2] ==> ignore + arg [--sysroot=/] ==> ignore + arg [--build-id] ==> ignore + arg [--eh-frame-hdr] ==> ignore + arg [-export-dynamic] ==> ignore + arg [-dynamic-linker] ==> ignore + arg [/lib/ld-linux-armhf.so.3] ==> ignore + arg [-X] ==> ignore + arg [--hash-style=gnu] ==> ignore + arg [--as-needed] ==> ignore + arg [-m] ==> ignore + arg [armelf_linux_eabi] ==> ignore + arg [-zrelro] ==> ignore + arg [-o] ==> ignore + arg [cmTryCompileExec781799643] ==> ignore + arg [/usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf/crt1.o] ==> ignore + arg [/usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf/crti.o] ==> ignore + arg [/usr/lib/gcc/arm-linux-gnueabihf/4.8/crtbegin.o] ==> ignore + arg [-L/usr/lib/gcc/arm-linux-gnueabihf/4.8] ==> dir [/usr/lib/gcc/arm-linux-gnueabihf/4.8] + arg [-L/usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf] ==> dir [/usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf] + arg [-L/usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../../lib] ==> dir [/usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../../lib] + arg [-L/lib/arm-linux-gnueabihf] ==> dir [/lib/arm-linux-gnueabihf] + arg [-L/lib/../lib] ==> dir [/lib/../lib] + arg [-L/usr/lib/arm-linux-gnueabihf] ==> dir [/usr/lib/arm-linux-gnueabihf] + arg [-L/usr/lib/../lib] ==> dir [/usr/lib/../lib] + arg [-L/usr/lib/gcc/arm-linux-gnueabihf/4.8/../../..] ==> dir [/usr/lib/gcc/arm-linux-gnueabihf/4.8/../../..] + arg [CMakeFiles/cmTryCompileExec781799643.dir/CMakeCCompilerABI.c.o] ==> ignore + arg [-lgcc] ==> lib [gcc] + arg [--as-needed] ==> ignore + arg [-lgcc_s] ==> lib [gcc_s] + arg [--no-as-needed] ==> ignore + arg [-lc] ==> lib [c] + arg [-lgcc] ==> lib [gcc] + arg [--as-needed] ==> ignore + arg [-lgcc_s] ==> lib [gcc_s] + arg [--no-as-needed] ==> ignore + arg [/usr/lib/gcc/arm-linux-gnueabihf/4.8/crtend.o] ==> ignore + arg [/usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf/crtn.o] ==> ignore + remove lib [gcc] + remove lib [gcc_s] + remove lib [gcc] + remove lib [gcc_s] + collapse library dir [/usr/lib/gcc/arm-linux-gnueabihf/4.8] ==> [/usr/lib/gcc/arm-linux-gnueabihf/4.8] + collapse library dir [/usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf] ==> [/usr/lib/arm-linux-gnueabihf] + collapse library dir [/usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../../lib] ==> [/usr/lib] + collapse library dir [/lib/arm-linux-gnueabihf] ==> [/lib/arm-linux-gnueabihf] + collapse library dir [/lib/../lib] ==> [/lib] + collapse library dir [/usr/lib/arm-linux-gnueabihf] ==> [/usr/lib/arm-linux-gnueabihf] + collapse library dir [/usr/lib/../lib] ==> [/usr/lib] + collapse library dir [/usr/lib/gcc/arm-linux-gnueabihf/4.8/../../..] ==> [/usr/lib] + implicit libs: [c] + implicit dirs: [/usr/lib/gcc/arm-linux-gnueabihf/4.8;/usr/lib/arm-linux-gnueabihf;/usr/lib;/lib/arm-linux-gnueabihf;/lib] + implicit fwks: [] + + +Determining if the CXX compiler works passed with the following output: +Change Dir: /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/CMakeFiles/CMakeTmp + +Run Build Command:/usr/bin/make "cmTryCompileExec1028053359/fast" +/usr/bin/make -f CMakeFiles/cmTryCompileExec1028053359.dir/build.make CMakeFiles/cmTryCompileExec1028053359.dir/build +make[1]: Entering directory `/home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/CMakeFiles/CMakeTmp' +/usr/bin/cmake -E cmake_progress_report /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/CMakeFiles/CMakeTmp/CMakeFiles 1 +Building CXX object CMakeFiles/cmTryCompileExec1028053359.dir/testCXXCompiler.cxx.o +/usr/bin/c++ -o CMakeFiles/cmTryCompileExec1028053359.dir/testCXXCompiler.cxx.o -c /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/CMakeFiles/CMakeTmp/testCXXCompiler.cxx +Linking CXX executable cmTryCompileExec1028053359 +/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTryCompileExec1028053359.dir/link.txt --verbose=1 +/usr/bin/c++ CMakeFiles/cmTryCompileExec1028053359.dir/testCXXCompiler.cxx.o -o cmTryCompileExec1028053359 -rdynamic +make[1]: Leaving directory `/home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/CMakeFiles/CMakeTmp' + + +Detecting CXX compiler ABI info compiled with the following output: +Change Dir: /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/CMakeFiles/CMakeTmp + +Run Build Command:/usr/bin/make "cmTryCompileExec3957457156/fast" +/usr/bin/make -f CMakeFiles/cmTryCompileExec3957457156.dir/build.make CMakeFiles/cmTryCompileExec3957457156.dir/build +make[1]: Entering directory `/home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/CMakeFiles/CMakeTmp' +/usr/bin/cmake -E cmake_progress_report /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/CMakeFiles/CMakeTmp/CMakeFiles 1 +Building CXX object CMakeFiles/cmTryCompileExec3957457156.dir/CMakeCXXCompilerABI.cpp.o +/usr/bin/c++ -o CMakeFiles/cmTryCompileExec3957457156.dir/CMakeCXXCompilerABI.cpp.o -c /usr/share/cmake-2.8/Modules/CMakeCXXCompilerABI.cpp +Linking CXX executable cmTryCompileExec3957457156 +/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTryCompileExec3957457156.dir/link.txt --verbose=1 +/usr/bin/c++ -v CMakeFiles/cmTryCompileExec3957457156.dir/CMakeCXXCompilerABI.cpp.o -o cmTryCompileExec3957457156 -rdynamic +Using built-in specs. +COLLECT_GCC=/usr/bin/c++ +COLLECT_LTO_WRAPPER=/usr/lib/gcc/arm-linux-gnueabihf/4.8/lto-wrapper +Target: arm-linux-gnueabihf +Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.8.4-2ubuntu1~14.04' --with-bugurl=file:///usr/share/doc/gcc-4.8/README.Bugs --enable-languages=c,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.8 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.8 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --disable-libmudflap --disable-libitm --disable-libquadmath --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-4.8-armhf/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-4.8-armhf --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-4.8-armhf --with-arch-directory=arm --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc --enable-multiarch --enable-multilib --disable-sjlj-exceptions --with-arch=armv7-a --with-fpu=vfpv3-d16 --with-float=hard --with-mode=thumb --disable-werror --enable-checking=release --build=arm-linux-gnueabihf --host=arm-linux-gnueabihf --target=arm-linux-gnueabihf +Thread model: posix +gcc version 4.8.4 (Ubuntu/Linaro 4.8.4-2ubuntu1~14.04) +COMPILER_PATH=/usr/lib/gcc/arm-linux-gnueabihf/4.8/:/usr/lib/gcc/arm-linux-gnueabihf/4.8/:/usr/lib/gcc/arm-linux-gnueabihf/:/usr/lib/gcc/arm-linux-gnueabihf/4.8/:/usr/lib/gcc/arm-linux-gnueabihf/ +LIBRARY_PATH=/usr/lib/gcc/arm-linux-gnueabihf/4.8/:/usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf/:/usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../../lib/:/lib/arm-linux-gnueabihf/:/lib/../lib/:/usr/lib/arm-linux-gnueabihf/:/usr/lib/../lib/:/usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../:/lib/:/usr/lib/ +COLLECT_GCC_OPTIONS='-v' '-o' 'cmTryCompileExec3957457156' '-rdynamic' '-shared-libgcc' '-march=armv7-a' '-mfloat-abi=hard' '-mfpu=vfpv3-d16' '-mthumb' '-mtls-dialect=gnu' + /usr/lib/gcc/arm-linux-gnueabihf/4.8/collect2 --sysroot=/ --build-id --eh-frame-hdr -export-dynamic -dynamic-linker /lib/ld-linux-armhf.so.3 -X --hash-style=gnu --as-needed -m armelf_linux_eabi -z relro -o cmTryCompileExec3957457156 /usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf/crt1.o /usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf/crti.o /usr/lib/gcc/arm-linux-gnueabihf/4.8/crtbegin.o -L/usr/lib/gcc/arm-linux-gnueabihf/4.8 -L/usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf -L/usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../../lib -L/lib/arm-linux-gnueabihf -L/lib/../lib -L/usr/lib/arm-linux-gnueabihf -L/usr/lib/../lib -L/usr/lib/gcc/arm-linux-gnueabihf/4.8/../../.. CMakeFiles/cmTryCompileExec3957457156.dir/CMakeCXXCompilerABI.cpp.o -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/lib/gcc/arm-linux-gnueabihf/4.8/crtend.o /usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf/crtn.o +make[1]: Leaving directory `/home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/CMakeFiles/CMakeTmp' + + +Parsed CXX implicit link information from above output: + link line regex: [^( *|.*[/\])(ld|([^/\]+-)?ld|collect2)[^/\]*( |$)] + ignore line: [Change Dir: /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/CMakeFiles/CMakeTmp] + ignore line: [] + ignore line: [Run Build Command:/usr/bin/make "cmTryCompileExec3957457156/fast"] + ignore line: [/usr/bin/make -f CMakeFiles/cmTryCompileExec3957457156.dir/build.make CMakeFiles/cmTryCompileExec3957457156.dir/build] + ignore line: [make[1]: Entering directory `/home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/CMakeFiles/CMakeTmp'] + ignore line: [/usr/bin/cmake -E cmake_progress_report /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/CMakeFiles/CMakeTmp/CMakeFiles 1] + ignore line: [Building CXX object CMakeFiles/cmTryCompileExec3957457156.dir/CMakeCXXCompilerABI.cpp.o] + ignore line: [/usr/bin/c++ -o CMakeFiles/cmTryCompileExec3957457156.dir/CMakeCXXCompilerABI.cpp.o -c /usr/share/cmake-2.8/Modules/CMakeCXXCompilerABI.cpp] + ignore line: [Linking CXX executable cmTryCompileExec3957457156] + ignore line: [/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTryCompileExec3957457156.dir/link.txt --verbose=1] + ignore line: [/usr/bin/c++ -v CMakeFiles/cmTryCompileExec3957457156.dir/CMakeCXXCompilerABI.cpp.o -o cmTryCompileExec3957457156 -rdynamic ] + ignore line: [Using built-in specs.] + ignore line: [COLLECT_GCC=/usr/bin/c++] + ignore line: [COLLECT_LTO_WRAPPER=/usr/lib/gcc/arm-linux-gnueabihf/4.8/lto-wrapper] + ignore line: [Target: arm-linux-gnueabihf] + ignore line: [Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.8.4-2ubuntu1~14.04' --with-bugurl=file:///usr/share/doc/gcc-4.8/README.Bugs --enable-languages=c,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.8 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.8 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --disable-libmudflap --disable-libitm --disable-libquadmath --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-4.8-armhf/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-4.8-armhf --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-4.8-armhf --with-arch-directory=arm --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc --enable-multiarch --enable-multilib --disable-sjlj-exceptions --with-arch=armv7-a --with-fpu=vfpv3-d16 --with-float=hard --with-mode=thumb --disable-werror --enable-checking=release --build=arm-linux-gnueabihf --host=arm-linux-gnueabihf --target=arm-linux-gnueabihf] + ignore line: [Thread model: posix] + ignore line: [gcc version 4.8.4 (Ubuntu/Linaro 4.8.4-2ubuntu1~14.04) ] + ignore line: [COMPILER_PATH=/usr/lib/gcc/arm-linux-gnueabihf/4.8/:/usr/lib/gcc/arm-linux-gnueabihf/4.8/:/usr/lib/gcc/arm-linux-gnueabihf/:/usr/lib/gcc/arm-linux-gnueabihf/4.8/:/usr/lib/gcc/arm-linux-gnueabihf/] + ignore line: [LIBRARY_PATH=/usr/lib/gcc/arm-linux-gnueabihf/4.8/:/usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf/:/usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../../lib/:/lib/arm-linux-gnueabihf/:/lib/../lib/:/usr/lib/arm-linux-gnueabihf/:/usr/lib/../lib/:/usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../:/lib/:/usr/lib/] + ignore line: [COLLECT_GCC_OPTIONS='-v' '-o' 'cmTryCompileExec3957457156' '-rdynamic' '-shared-libgcc' '-march=armv7-a' '-mfloat-abi=hard' '-mfpu=vfpv3-d16' '-mthumb' '-mtls-dialect=gnu'] + link line: [ /usr/lib/gcc/arm-linux-gnueabihf/4.8/collect2 --sysroot=/ --build-id --eh-frame-hdr -export-dynamic -dynamic-linker /lib/ld-linux-armhf.so.3 -X --hash-style=gnu --as-needed -m armelf_linux_eabi -z relro -o cmTryCompileExec3957457156 /usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf/crt1.o /usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf/crti.o /usr/lib/gcc/arm-linux-gnueabihf/4.8/crtbegin.o -L/usr/lib/gcc/arm-linux-gnueabihf/4.8 -L/usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf -L/usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../../lib -L/lib/arm-linux-gnueabihf -L/lib/../lib -L/usr/lib/arm-linux-gnueabihf -L/usr/lib/../lib -L/usr/lib/gcc/arm-linux-gnueabihf/4.8/../../.. CMakeFiles/cmTryCompileExec3957457156.dir/CMakeCXXCompilerABI.cpp.o -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/lib/gcc/arm-linux-gnueabihf/4.8/crtend.o /usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf/crtn.o] + arg [/usr/lib/gcc/arm-linux-gnueabihf/4.8/collect2] ==> ignore + arg [--sysroot=/] ==> ignore + arg [--build-id] ==> ignore + arg [--eh-frame-hdr] ==> ignore + arg [-export-dynamic] ==> ignore + arg [-dynamic-linker] ==> ignore + arg [/lib/ld-linux-armhf.so.3] ==> ignore + arg [-X] ==> ignore + arg [--hash-style=gnu] ==> ignore + arg [--as-needed] ==> ignore + arg [-m] ==> ignore + arg [armelf_linux_eabi] ==> ignore + arg [-zrelro] ==> ignore + arg [-o] ==> ignore + arg [cmTryCompileExec3957457156] ==> ignore + arg [/usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf/crt1.o] ==> ignore + arg [/usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf/crti.o] ==> ignore + arg [/usr/lib/gcc/arm-linux-gnueabihf/4.8/crtbegin.o] ==> ignore + arg [-L/usr/lib/gcc/arm-linux-gnueabihf/4.8] ==> dir [/usr/lib/gcc/arm-linux-gnueabihf/4.8] + arg [-L/usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf] ==> dir [/usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf] + arg [-L/usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../../lib] ==> dir [/usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../../lib] + arg [-L/lib/arm-linux-gnueabihf] ==> dir [/lib/arm-linux-gnueabihf] + arg [-L/lib/../lib] ==> dir [/lib/../lib] + arg [-L/usr/lib/arm-linux-gnueabihf] ==> dir [/usr/lib/arm-linux-gnueabihf] + arg [-L/usr/lib/../lib] ==> dir [/usr/lib/../lib] + arg [-L/usr/lib/gcc/arm-linux-gnueabihf/4.8/../../..] ==> dir [/usr/lib/gcc/arm-linux-gnueabihf/4.8/../../..] + arg [CMakeFiles/cmTryCompileExec3957457156.dir/CMakeCXXCompilerABI.cpp.o] ==> ignore + arg [-lstdc++] ==> lib [stdc++] + arg [-lm] ==> lib [m] + arg [-lgcc_s] ==> lib [gcc_s] + arg [-lgcc] ==> lib [gcc] + arg [-lc] ==> lib [c] + arg [-lgcc_s] ==> lib [gcc_s] + arg [-lgcc] ==> lib [gcc] + arg [/usr/lib/gcc/arm-linux-gnueabihf/4.8/crtend.o] ==> ignore + arg [/usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf/crtn.o] ==> ignore + remove lib [gcc_s] + remove lib [gcc] + remove lib [gcc_s] + remove lib [gcc] + collapse library dir [/usr/lib/gcc/arm-linux-gnueabihf/4.8] ==> [/usr/lib/gcc/arm-linux-gnueabihf/4.8] + collapse library dir [/usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf] ==> [/usr/lib/arm-linux-gnueabihf] + collapse library dir [/usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../../lib] ==> [/usr/lib] + collapse library dir [/lib/arm-linux-gnueabihf] ==> [/lib/arm-linux-gnueabihf] + collapse library dir [/lib/../lib] ==> [/lib] + collapse library dir [/usr/lib/arm-linux-gnueabihf] ==> [/usr/lib/arm-linux-gnueabihf] + collapse library dir [/usr/lib/../lib] ==> [/usr/lib] + collapse library dir [/usr/lib/gcc/arm-linux-gnueabihf/4.8/../../..] ==> [/usr/lib] + implicit libs: [stdc++;m;c] + implicit dirs: [/usr/lib/gcc/arm-linux-gnueabihf/4.8;/usr/lib/arm-linux-gnueabihf;/usr/lib;/lib/arm-linux-gnueabihf;/lib] + implicit fwks: [] + + diff --git a/external_src/raspicam-0.1.3/build/CMakeFiles/CMakeRuleHashes.txt b/external_src/raspicam-0.1.3/build/CMakeFiles/CMakeRuleHashes.txt new file mode 100644 index 0000000..f94bc5c --- /dev/null +++ b/external_src/raspicam-0.1.3/build/CMakeFiles/CMakeRuleHashes.txt @@ -0,0 +1,2 @@ +# Hashes of file build rules. +d40b852367b8f17b70ad02dd31dc09d5 CMakeFiles/uninstall diff --git a/external_src/raspicam-0.1.3/build/CMakeFiles/Makefile.cmake b/external_src/raspicam-0.1.3/build/CMakeFiles/Makefile.cmake new file mode 100644 index 0000000..dd33d36 --- /dev/null +++ b/external_src/raspicam-0.1.3/build/CMakeFiles/Makefile.cmake @@ -0,0 +1,87 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +# The generator used is: +SET(CMAKE_DEPENDS_GENERATOR "Unix Makefiles") + +# The top level Makefile was generated from the following files: +SET(CMAKE_MAKEFILE_DEPENDS + "CMakeCache.txt" + "../CMakeLists.txt" + "CMakeFiles/2.8.12.2/CMakeCCompiler.cmake" + "CMakeFiles/2.8.12.2/CMakeCXXCompiler.cmake" + "CMakeFiles/2.8.12.2/CMakeSystem.cmake" + "../cmake_uninstall.cmake.in" + "../config.cmake.in" + "../src/CMakeLists.txt" + "../utils/CMakeLists.txt" + "/usr/local/share/OpenCV/OpenCVConfig-version.cmake" + "/usr/local/share/OpenCV/OpenCVConfig.cmake" + "/usr/local/share/OpenCV/OpenCVModules-release.cmake" + "/usr/local/share/OpenCV/OpenCVModules.cmake" + "/usr/share/cmake-2.8/Modules/CMakeCCompiler.cmake.in" + "/usr/share/cmake-2.8/Modules/CMakeCCompilerABI.c" + "/usr/share/cmake-2.8/Modules/CMakeCInformation.cmake" + "/usr/share/cmake-2.8/Modules/CMakeCXXCompiler.cmake.in" + "/usr/share/cmake-2.8/Modules/CMakeCXXCompilerABI.cpp" + "/usr/share/cmake-2.8/Modules/CMakeCXXInformation.cmake" + "/usr/share/cmake-2.8/Modules/CMakeClDeps.cmake" + "/usr/share/cmake-2.8/Modules/CMakeCommonLanguageInclude.cmake" + "/usr/share/cmake-2.8/Modules/CMakeDetermineCCompiler.cmake" + "/usr/share/cmake-2.8/Modules/CMakeDetermineCXXCompiler.cmake" + "/usr/share/cmake-2.8/Modules/CMakeDetermineCompiler.cmake" + "/usr/share/cmake-2.8/Modules/CMakeDetermineCompilerABI.cmake" + "/usr/share/cmake-2.8/Modules/CMakeDetermineCompilerId.cmake" + "/usr/share/cmake-2.8/Modules/CMakeDetermineSystem.cmake" + "/usr/share/cmake-2.8/Modules/CMakeFindBinUtils.cmake" + "/usr/share/cmake-2.8/Modules/CMakeGenericSystem.cmake" + "/usr/share/cmake-2.8/Modules/CMakeParseImplicitLinkInfo.cmake" + "/usr/share/cmake-2.8/Modules/CMakeSystem.cmake.in" + "/usr/share/cmake-2.8/Modules/CMakeSystemSpecificInformation.cmake" + "/usr/share/cmake-2.8/Modules/CMakeTestCCompiler.cmake" + "/usr/share/cmake-2.8/Modules/CMakeTestCXXCompiler.cmake" + "/usr/share/cmake-2.8/Modules/CMakeTestCompilerCommon.cmake" + "/usr/share/cmake-2.8/Modules/CMakeUnixFindMake.cmake" + "/usr/share/cmake-2.8/Modules/Compiler/GNU-C.cmake" + "/usr/share/cmake-2.8/Modules/Compiler/GNU-CXX.cmake" + "/usr/share/cmake-2.8/Modules/Compiler/GNU.cmake" + "/usr/share/cmake-2.8/Modules/MultiArchCross.cmake" + "/usr/share/cmake-2.8/Modules/Platform/Linux-CXX.cmake" + "/usr/share/cmake-2.8/Modules/Platform/Linux-GNU-C.cmake" + "/usr/share/cmake-2.8/Modules/Platform/Linux-GNU-CXX.cmake" + "/usr/share/cmake-2.8/Modules/Platform/Linux-GNU.cmake" + "/usr/share/cmake-2.8/Modules/Platform/Linux.cmake" + "/usr/share/cmake-2.8/Modules/Platform/UnixPaths.cmake" + ) + +# The corresponding makefile is: +SET(CMAKE_MAKEFILE_OUTPUTS + "Makefile" + "CMakeFiles/cmake.check_cache" + ) + +# Byproducts of CMake generate step: +SET(CMAKE_MAKEFILE_PRODUCTS + "CMakeFiles/2.8.12.2/CMakeSystem.cmake" + "CMakeFiles/2.8.12.2/CMakeCCompiler.cmake" + "CMakeFiles/2.8.12.2/CMakeCXXCompiler.cmake" + "CMakeFiles/2.8.12.2/CMakeCCompiler.cmake" + "CMakeFiles/2.8.12.2/CMakeCXXCompiler.cmake" + "cmake_uninstall.cmake" + "Findraspicam.cmake" + "raspicamConfig.cmake" + "CMakeFiles/CMakeDirectoryInformation.cmake" + "src/CMakeFiles/CMakeDirectoryInformation.cmake" + "utils/CMakeFiles/CMakeDirectoryInformation.cmake" + ) + +# Dependency information for all targets: +SET(CMAKE_DEPEND_INFO_FILES + "CMakeFiles/uninstall.dir/DependInfo.cmake" + "src/CMakeFiles/raspicam.dir/DependInfo.cmake" + "src/CMakeFiles/raspicam_cv.dir/DependInfo.cmake" + "utils/CMakeFiles/raspicam_cv_still_test.dir/DependInfo.cmake" + "utils/CMakeFiles/raspicam_cv_test.dir/DependInfo.cmake" + "utils/CMakeFiles/raspicam_still_test.dir/DependInfo.cmake" + "utils/CMakeFiles/raspicam_test.dir/DependInfo.cmake" + ) diff --git a/external_src/raspicam-0.1.3/build/CMakeFiles/Makefile2 b/external_src/raspicam-0.1.3/build/CMakeFiles/Makefile2 new file mode 100644 index 0000000..8863e1c --- /dev/null +++ b/external_src/raspicam-0.1.3/build/CMakeFiles/Makefile2 @@ -0,0 +1,345 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +# Default target executed when no arguments are given to make. +default_target: all +.PHONY : default_target + +# The main recursive all target +all: +.PHONY : all + +# The main recursive preinstall target +preinstall: +.PHONY : preinstall + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/ubuntu/Nomad/external_src/raspicam-0.1.3 + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build + +#============================================================================= +# Target rules for target CMakeFiles/uninstall.dir + +# All Build rule for target. +CMakeFiles/uninstall.dir/all: + $(MAKE) -f CMakeFiles/uninstall.dir/build.make CMakeFiles/uninstall.dir/depend + $(MAKE) -f CMakeFiles/uninstall.dir/build.make CMakeFiles/uninstall.dir/build + $(CMAKE_COMMAND) -E cmake_progress_report /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/CMakeFiles + @echo "Built target uninstall" +.PHONY : CMakeFiles/uninstall.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/uninstall.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/CMakeFiles 0 + $(MAKE) -f CMakeFiles/Makefile2 CMakeFiles/uninstall.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/CMakeFiles 0 +.PHONY : CMakeFiles/uninstall.dir/rule + +# Convenience name for target. +uninstall: CMakeFiles/uninstall.dir/rule +.PHONY : uninstall + +# clean rule for target. +CMakeFiles/uninstall.dir/clean: + $(MAKE) -f CMakeFiles/uninstall.dir/build.make CMakeFiles/uninstall.dir/clean +.PHONY : CMakeFiles/uninstall.dir/clean + +# clean rule for target. +clean: CMakeFiles/uninstall.dir/clean +.PHONY : clean + +#============================================================================= +# Directory level rules for directory src + +# Convenience name for "all" pass in the directory. +src/all: src/CMakeFiles/raspicam.dir/all +src/all: src/CMakeFiles/raspicam_cv.dir/all +.PHONY : src/all + +# Convenience name for "clean" pass in the directory. +src/clean: src/CMakeFiles/raspicam.dir/clean +src/clean: src/CMakeFiles/raspicam_cv.dir/clean +.PHONY : src/clean + +# Convenience name for "preinstall" pass in the directory. +src/preinstall: +.PHONY : src/preinstall + +#============================================================================= +# Target rules for target src/CMakeFiles/raspicam.dir + +# All Build rule for target. +src/CMakeFiles/raspicam.dir/all: + $(MAKE) -f src/CMakeFiles/raspicam.dir/build.make src/CMakeFiles/raspicam.dir/depend + $(MAKE) -f src/CMakeFiles/raspicam.dir/build.make src/CMakeFiles/raspicam.dir/build + $(CMAKE_COMMAND) -E cmake_progress_report /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/CMakeFiles 1 2 3 4 5 + @echo "Built target raspicam" +.PHONY : src/CMakeFiles/raspicam.dir/all + +# Include target in all. +all: src/CMakeFiles/raspicam.dir/all +.PHONY : all + +# Build rule for subdir invocation for target. +src/CMakeFiles/raspicam.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/CMakeFiles 5 + $(MAKE) -f CMakeFiles/Makefile2 src/CMakeFiles/raspicam.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/CMakeFiles 0 +.PHONY : src/CMakeFiles/raspicam.dir/rule + +# Convenience name for target. +raspicam: src/CMakeFiles/raspicam.dir/rule +.PHONY : raspicam + +# clean rule for target. +src/CMakeFiles/raspicam.dir/clean: + $(MAKE) -f src/CMakeFiles/raspicam.dir/build.make src/CMakeFiles/raspicam.dir/clean +.PHONY : src/CMakeFiles/raspicam.dir/clean + +# clean rule for target. +clean: src/CMakeFiles/raspicam.dir/clean +.PHONY : clean + +#============================================================================= +# Target rules for target src/CMakeFiles/raspicam_cv.dir + +# All Build rule for target. +src/CMakeFiles/raspicam_cv.dir/all: + $(MAKE) -f src/CMakeFiles/raspicam_cv.dir/build.make src/CMakeFiles/raspicam_cv.dir/depend + $(MAKE) -f src/CMakeFiles/raspicam_cv.dir/build.make src/CMakeFiles/raspicam_cv.dir/build + $(CMAKE_COMMAND) -E cmake_progress_report /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/CMakeFiles 6 7 + @echo "Built target raspicam_cv" +.PHONY : src/CMakeFiles/raspicam_cv.dir/all + +# Include target in all. +all: src/CMakeFiles/raspicam_cv.dir/all +.PHONY : all + +# Build rule for subdir invocation for target. +src/CMakeFiles/raspicam_cv.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/CMakeFiles 2 + $(MAKE) -f CMakeFiles/Makefile2 src/CMakeFiles/raspicam_cv.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/CMakeFiles 0 +.PHONY : src/CMakeFiles/raspicam_cv.dir/rule + +# Convenience name for target. +raspicam_cv: src/CMakeFiles/raspicam_cv.dir/rule +.PHONY : raspicam_cv + +# clean rule for target. +src/CMakeFiles/raspicam_cv.dir/clean: + $(MAKE) -f src/CMakeFiles/raspicam_cv.dir/build.make src/CMakeFiles/raspicam_cv.dir/clean +.PHONY : src/CMakeFiles/raspicam_cv.dir/clean + +# clean rule for target. +clean: src/CMakeFiles/raspicam_cv.dir/clean +.PHONY : clean + +#============================================================================= +# Directory level rules for directory utils + +# Convenience name for "all" pass in the directory. +utils/all: utils/CMakeFiles/raspicam_cv_still_test.dir/all +utils/all: utils/CMakeFiles/raspicam_cv_test.dir/all +utils/all: utils/CMakeFiles/raspicam_still_test.dir/all +utils/all: utils/CMakeFiles/raspicam_test.dir/all +.PHONY : utils/all + +# Convenience name for "clean" pass in the directory. +utils/clean: utils/CMakeFiles/raspicam_cv_still_test.dir/clean +utils/clean: utils/CMakeFiles/raspicam_cv_test.dir/clean +utils/clean: utils/CMakeFiles/raspicam_still_test.dir/clean +utils/clean: utils/CMakeFiles/raspicam_test.dir/clean +.PHONY : utils/clean + +# Convenience name for "preinstall" pass in the directory. +utils/preinstall: +.PHONY : utils/preinstall + +#============================================================================= +# Target rules for target utils/CMakeFiles/raspicam_cv_still_test.dir + +# All Build rule for target. +utils/CMakeFiles/raspicam_cv_still_test.dir/all: src/CMakeFiles/raspicam_cv.dir/all +utils/CMakeFiles/raspicam_cv_still_test.dir/all: src/CMakeFiles/raspicam.dir/all + $(MAKE) -f utils/CMakeFiles/raspicam_cv_still_test.dir/build.make utils/CMakeFiles/raspicam_cv_still_test.dir/depend + $(MAKE) -f utils/CMakeFiles/raspicam_cv_still_test.dir/build.make utils/CMakeFiles/raspicam_cv_still_test.dir/build + $(CMAKE_COMMAND) -E cmake_progress_report /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/CMakeFiles 8 + @echo "Built target raspicam_cv_still_test" +.PHONY : utils/CMakeFiles/raspicam_cv_still_test.dir/all + +# Include target in all. +all: utils/CMakeFiles/raspicam_cv_still_test.dir/all +.PHONY : all + +# Build rule for subdir invocation for target. +utils/CMakeFiles/raspicam_cv_still_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/CMakeFiles 8 + $(MAKE) -f CMakeFiles/Makefile2 utils/CMakeFiles/raspicam_cv_still_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/CMakeFiles 0 +.PHONY : utils/CMakeFiles/raspicam_cv_still_test.dir/rule + +# Convenience name for target. +raspicam_cv_still_test: utils/CMakeFiles/raspicam_cv_still_test.dir/rule +.PHONY : raspicam_cv_still_test + +# clean rule for target. +utils/CMakeFiles/raspicam_cv_still_test.dir/clean: + $(MAKE) -f utils/CMakeFiles/raspicam_cv_still_test.dir/build.make utils/CMakeFiles/raspicam_cv_still_test.dir/clean +.PHONY : utils/CMakeFiles/raspicam_cv_still_test.dir/clean + +# clean rule for target. +clean: utils/CMakeFiles/raspicam_cv_still_test.dir/clean +.PHONY : clean + +#============================================================================= +# Target rules for target utils/CMakeFiles/raspicam_cv_test.dir + +# All Build rule for target. +utils/CMakeFiles/raspicam_cv_test.dir/all: src/CMakeFiles/raspicam_cv.dir/all +utils/CMakeFiles/raspicam_cv_test.dir/all: src/CMakeFiles/raspicam.dir/all + $(MAKE) -f utils/CMakeFiles/raspicam_cv_test.dir/build.make utils/CMakeFiles/raspicam_cv_test.dir/depend + $(MAKE) -f utils/CMakeFiles/raspicam_cv_test.dir/build.make utils/CMakeFiles/raspicam_cv_test.dir/build + $(CMAKE_COMMAND) -E cmake_progress_report /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/CMakeFiles 9 + @echo "Built target raspicam_cv_test" +.PHONY : utils/CMakeFiles/raspicam_cv_test.dir/all + +# Include target in all. +all: utils/CMakeFiles/raspicam_cv_test.dir/all +.PHONY : all + +# Build rule for subdir invocation for target. +utils/CMakeFiles/raspicam_cv_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/CMakeFiles 8 + $(MAKE) -f CMakeFiles/Makefile2 utils/CMakeFiles/raspicam_cv_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/CMakeFiles 0 +.PHONY : utils/CMakeFiles/raspicam_cv_test.dir/rule + +# Convenience name for target. +raspicam_cv_test: utils/CMakeFiles/raspicam_cv_test.dir/rule +.PHONY : raspicam_cv_test + +# clean rule for target. +utils/CMakeFiles/raspicam_cv_test.dir/clean: + $(MAKE) -f utils/CMakeFiles/raspicam_cv_test.dir/build.make utils/CMakeFiles/raspicam_cv_test.dir/clean +.PHONY : utils/CMakeFiles/raspicam_cv_test.dir/clean + +# clean rule for target. +clean: utils/CMakeFiles/raspicam_cv_test.dir/clean +.PHONY : clean + +#============================================================================= +# Target rules for target utils/CMakeFiles/raspicam_still_test.dir + +# All Build rule for target. +utils/CMakeFiles/raspicam_still_test.dir/all: src/CMakeFiles/raspicam.dir/all + $(MAKE) -f utils/CMakeFiles/raspicam_still_test.dir/build.make utils/CMakeFiles/raspicam_still_test.dir/depend + $(MAKE) -f utils/CMakeFiles/raspicam_still_test.dir/build.make utils/CMakeFiles/raspicam_still_test.dir/build + $(CMAKE_COMMAND) -E cmake_progress_report /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/CMakeFiles 10 + @echo "Built target raspicam_still_test" +.PHONY : utils/CMakeFiles/raspicam_still_test.dir/all + +# Include target in all. +all: utils/CMakeFiles/raspicam_still_test.dir/all +.PHONY : all + +# Build rule for subdir invocation for target. +utils/CMakeFiles/raspicam_still_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/CMakeFiles 6 + $(MAKE) -f CMakeFiles/Makefile2 utils/CMakeFiles/raspicam_still_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/CMakeFiles 0 +.PHONY : utils/CMakeFiles/raspicam_still_test.dir/rule + +# Convenience name for target. +raspicam_still_test: utils/CMakeFiles/raspicam_still_test.dir/rule +.PHONY : raspicam_still_test + +# clean rule for target. +utils/CMakeFiles/raspicam_still_test.dir/clean: + $(MAKE) -f utils/CMakeFiles/raspicam_still_test.dir/build.make utils/CMakeFiles/raspicam_still_test.dir/clean +.PHONY : utils/CMakeFiles/raspicam_still_test.dir/clean + +# clean rule for target. +clean: utils/CMakeFiles/raspicam_still_test.dir/clean +.PHONY : clean + +#============================================================================= +# Target rules for target utils/CMakeFiles/raspicam_test.dir + +# All Build rule for target. +utils/CMakeFiles/raspicam_test.dir/all: src/CMakeFiles/raspicam.dir/all + $(MAKE) -f utils/CMakeFiles/raspicam_test.dir/build.make utils/CMakeFiles/raspicam_test.dir/depend + $(MAKE) -f utils/CMakeFiles/raspicam_test.dir/build.make utils/CMakeFiles/raspicam_test.dir/build + $(CMAKE_COMMAND) -E cmake_progress_report /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/CMakeFiles 11 + @echo "Built target raspicam_test" +.PHONY : utils/CMakeFiles/raspicam_test.dir/all + +# Include target in all. +all: utils/CMakeFiles/raspicam_test.dir/all +.PHONY : all + +# Build rule for subdir invocation for target. +utils/CMakeFiles/raspicam_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/CMakeFiles 6 + $(MAKE) -f CMakeFiles/Makefile2 utils/CMakeFiles/raspicam_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/CMakeFiles 0 +.PHONY : utils/CMakeFiles/raspicam_test.dir/rule + +# Convenience name for target. +raspicam_test: utils/CMakeFiles/raspicam_test.dir/rule +.PHONY : raspicam_test + +# clean rule for target. +utils/CMakeFiles/raspicam_test.dir/clean: + $(MAKE) -f utils/CMakeFiles/raspicam_test.dir/build.make utils/CMakeFiles/raspicam_test.dir/clean +.PHONY : utils/CMakeFiles/raspicam_test.dir/clean + +# clean rule for target. +clean: utils/CMakeFiles/raspicam_test.dir/clean +.PHONY : clean + +#============================================================================= +# Special targets to cleanup operation of make. + +# Special rule to run CMake to check the build system integrity. +# No rule that depends on this can have commands that come from listfiles +# because they might be regenerated. +cmake_check_build_system: + $(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 0 +.PHONY : cmake_check_build_system + diff --git a/external_src/raspicam-0.1.3/build/CMakeFiles/TargetDirectories.txt b/external_src/raspicam-0.1.3/build/CMakeFiles/TargetDirectories.txt new file mode 100644 index 0000000..824a262 --- /dev/null +++ b/external_src/raspicam-0.1.3/build/CMakeFiles/TargetDirectories.txt @@ -0,0 +1,7 @@ +/home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/src/CMakeFiles/raspicam.dir +/home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/src/CMakeFiles/raspicam_cv.dir +/home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_cv_still_test.dir +/home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_cv_test.dir +/home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_still_test.dir +/home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_test.dir +/home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/CMakeFiles/uninstall.dir diff --git a/external_src/raspicam-0.1.3/build/CMakeFiles/cmake.check_cache b/external_src/raspicam-0.1.3/build/CMakeFiles/cmake.check_cache new file mode 100644 index 0000000..3dccd73 --- /dev/null +++ b/external_src/raspicam-0.1.3/build/CMakeFiles/cmake.check_cache @@ -0,0 +1 @@ +# This file is generated by cmake for dependency checking of the CMakeCache.txt file diff --git a/external_src/raspicam-0.1.3/build/CMakeFiles/progress.marks b/external_src/raspicam-0.1.3/build/CMakeFiles/progress.marks new file mode 100644 index 0000000..b4de394 --- /dev/null +++ b/external_src/raspicam-0.1.3/build/CMakeFiles/progress.marks @@ -0,0 +1 @@ +11 diff --git a/external_src/raspicam-0.1.3/build/CMakeFiles/uninstall.dir/DependInfo.cmake b/external_src/raspicam-0.1.3/build/CMakeFiles/uninstall.dir/DependInfo.cmake new file mode 100644 index 0000000..604a15b --- /dev/null +++ b/external_src/raspicam-0.1.3/build/CMakeFiles/uninstall.dir/DependInfo.cmake @@ -0,0 +1,20 @@ +# The set of languages for which implicit dependencies are needed: +SET(CMAKE_DEPENDS_LANGUAGES + ) +# The set of files for implicit dependencies of each language: + +# Targets to which this target links. +SET(CMAKE_TARGET_LINKED_INFO_FILES + ) + +# The include file search paths: +SET(CMAKE_C_TARGET_INCLUDE_PATH + "../dependencies" + "../dependencies/mmal" + "../dependencies/vcos" + "/usr/local/include/opencv" + "/usr/local/include" + ) +SET(CMAKE_CXX_TARGET_INCLUDE_PATH ${CMAKE_C_TARGET_INCLUDE_PATH}) +SET(CMAKE_Fortran_TARGET_INCLUDE_PATH ${CMAKE_C_TARGET_INCLUDE_PATH}) +SET(CMAKE_ASM_TARGET_INCLUDE_PATH ${CMAKE_C_TARGET_INCLUDE_PATH}) diff --git a/external_src/raspicam-0.1.3/build/CMakeFiles/uninstall.dir/build.make b/external_src/raspicam-0.1.3/build/CMakeFiles/uninstall.dir/build.make new file mode 100644 index 0000000..0eb233a --- /dev/null +++ b/external_src/raspicam-0.1.3/build/CMakeFiles/uninstall.dir/build.make @@ -0,0 +1,66 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/ubuntu/Nomad/external_src/raspicam-0.1.3 + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build + +# Utility rule file for uninstall. + +# Include the progress variables for this target. +include CMakeFiles/uninstall.dir/progress.make + +CMakeFiles/uninstall: + /usr/bin/cmake -P /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/cmake_uninstall.cmake + +uninstall: CMakeFiles/uninstall +uninstall: CMakeFiles/uninstall.dir/build.make +.PHONY : uninstall + +# Rule to build all files generated by this target. +CMakeFiles/uninstall.dir/build: uninstall +.PHONY : CMakeFiles/uninstall.dir/build + +CMakeFiles/uninstall.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/uninstall.dir/cmake_clean.cmake +.PHONY : CMakeFiles/uninstall.dir/clean + +CMakeFiles/uninstall.dir/depend: + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/ubuntu/Nomad/external_src/raspicam-0.1.3 /home/ubuntu/Nomad/external_src/raspicam-0.1.3 /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/CMakeFiles/uninstall.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : CMakeFiles/uninstall.dir/depend + diff --git a/external_src/raspicam-0.1.3/build/CMakeFiles/uninstall.dir/cmake_clean.cmake b/external_src/raspicam-0.1.3/build/CMakeFiles/uninstall.dir/cmake_clean.cmake new file mode 100644 index 0000000..828e2a2 --- /dev/null +++ b/external_src/raspicam-0.1.3/build/CMakeFiles/uninstall.dir/cmake_clean.cmake @@ -0,0 +1,8 @@ +FILE(REMOVE_RECURSE + "CMakeFiles/uninstall" +) + +# Per-language clean rules from dependency scanning. +FOREACH(lang) + INCLUDE(CMakeFiles/uninstall.dir/cmake_clean_${lang}.cmake OPTIONAL) +ENDFOREACH(lang) diff --git a/external_src/raspicam-0.1.3/build/CMakeFiles/uninstall.dir/progress.make b/external_src/raspicam-0.1.3/build/CMakeFiles/uninstall.dir/progress.make new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/external_src/raspicam-0.1.3/build/CMakeFiles/uninstall.dir/progress.make @@ -0,0 +1 @@ + diff --git a/external_src/raspicam-0.1.3/build/Findraspicam.cmake b/external_src/raspicam-0.1.3/build/Findraspicam.cmake new file mode 100644 index 0000000..539e008 --- /dev/null +++ b/external_src/raspicam-0.1.3/build/Findraspicam.cmake @@ -0,0 +1,34 @@ +# =================================================================================== +# raspicam CMake configuration file +# +# ** File generated automatically, do not modify ** +# +# Usage from an external project: +# In your CMakeLists.txt, add these lines: +# +# FIND_PACKAGE(raspicam REQUIRED ) +# TARGET_LINK_LIBRARIES(MY_TARGET_NAME ) +# +# This file will define the following variables: +# - raspicam_LIBS : The list of libraries to links against. +# - raspicam_LIB_DIR : The directory where lib files are. Calling LINK_DIRECTORIES +# with this path is NOT needed. +# - raspicam_VERSION : The version of this PROJECT_NAME build. Example: "1.2.0" +# - raspicam_VERSION_MAJOR : Major version part of VERSION. Example: "1" +# - raspicam_VERSION_MINOR : Minor version part of VERSION. Example: "2" +# - raspicam_VERSION_PATCH : Patch version part of VERSION. Example: "0" +# +# =================================================================================== +INCLUDE_DIRECTORIES(;/usr/local/include) +LINK_DIRECTORIES("/usr/local/lib") + +SET(raspicam_LIBS /opt/vc/lib/libmmal_core.so;/opt/vc/lib/libmmal_util.so;/opt/vc/lib/libmmal.so raspicam) +SET(raspicam_FOUND "YES") + +SET(raspicam_CV_FOUND "YES") +SET(raspicam_CV_LIBS /opt/vc/lib/libmmal_core.so;/opt/vc/lib/libmmal_util.so;/opt/vc/lib/libmmal.so raspicam opencv_videostab;opencv_videoio;opencv_video;opencv_superres;opencv_stitching;opencv_shape;opencv_photo;opencv_objdetect;opencv_ml;opencv_imgproc;opencv_imgcodecs;opencv_highgui;opencv_hal;opencv_flann;opencv_features2d;opencv_core;opencv_calib3d raspicam_cv) + +SET(raspicam_VERSION 0.1.2) +SET(raspicam_VERSION_MAJOR 0) +SET(raspicam_VERSION_MINOR 1) +SET(raspicam_VERSION_PATCH 2) diff --git a/external_src/raspicam-0.1.3/build/Makefile b/external_src/raspicam-0.1.3/build/Makefile new file mode 100644 index 0000000..f175eb8 --- /dev/null +++ b/external_src/raspicam-0.1.3/build/Makefile @@ -0,0 +1,265 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +# Default target executed when no arguments are given to make. +default_target: all +.PHONY : default_target + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/ubuntu/Nomad/external_src/raspicam-0.1.3 + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build + +#============================================================================= +# Targets provided globally by CMake. + +# Special rule for the target edit_cache +edit_cache: + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running interactive CMake command-line interface..." + /usr/bin/cmake -i . +.PHONY : edit_cache + +# Special rule for the target edit_cache +edit_cache/fast: edit_cache +.PHONY : edit_cache/fast + +# Special rule for the target install +install: preinstall + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Install the project..." + /usr/bin/cmake -P cmake_install.cmake +.PHONY : install + +# Special rule for the target install +install/fast: preinstall/fast + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Install the project..." + /usr/bin/cmake -P cmake_install.cmake +.PHONY : install/fast + +# Special rule for the target install/local +install/local: preinstall + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Installing only the local directory..." + /usr/bin/cmake -DCMAKE_INSTALL_LOCAL_ONLY=1 -P cmake_install.cmake +.PHONY : install/local + +# Special rule for the target install/local +install/local/fast: install/local +.PHONY : install/local/fast + +# Special rule for the target install/strip +install/strip: preinstall + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Installing the project stripped..." + /usr/bin/cmake -DCMAKE_INSTALL_DO_STRIP=1 -P cmake_install.cmake +.PHONY : install/strip + +# Special rule for the target install/strip +install/strip/fast: install/strip +.PHONY : install/strip/fast + +# Special rule for the target list_install_components +list_install_components: + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Available install components are: \"Unspecified\" \"main\"" +.PHONY : list_install_components + +# Special rule for the target list_install_components +list_install_components/fast: list_install_components +.PHONY : list_install_components/fast + +# Special rule for the target rebuild_cache +rebuild_cache: + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running CMake to regenerate build system..." + /usr/bin/cmake -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) +.PHONY : rebuild_cache + +# Special rule for the target rebuild_cache +rebuild_cache/fast: rebuild_cache +.PHONY : rebuild_cache/fast + +# The main all target +all: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/CMakeFiles /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/CMakeFiles/progress.marks + $(MAKE) -f CMakeFiles/Makefile2 all + $(CMAKE_COMMAND) -E cmake_progress_start /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/CMakeFiles 0 +.PHONY : all + +# The main clean target +clean: + $(MAKE) -f CMakeFiles/Makefile2 clean +.PHONY : clean + +# The main clean target +clean/fast: clean +.PHONY : clean/fast + +# Prepare targets for installation. +preinstall: all + $(MAKE) -f CMakeFiles/Makefile2 preinstall +.PHONY : preinstall + +# Prepare targets for installation. +preinstall/fast: + $(MAKE) -f CMakeFiles/Makefile2 preinstall +.PHONY : preinstall/fast + +# clear depends +depend: + $(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 1 +.PHONY : depend + +#============================================================================= +# Target rules for targets named uninstall + +# Build rule for target. +uninstall: cmake_check_build_system + $(MAKE) -f CMakeFiles/Makefile2 uninstall +.PHONY : uninstall + +# fast build rule for target. +uninstall/fast: + $(MAKE) -f CMakeFiles/uninstall.dir/build.make CMakeFiles/uninstall.dir/build +.PHONY : uninstall/fast + +#============================================================================= +# Target rules for targets named raspicam + +# Build rule for target. +raspicam: cmake_check_build_system + $(MAKE) -f CMakeFiles/Makefile2 raspicam +.PHONY : raspicam + +# fast build rule for target. +raspicam/fast: + $(MAKE) -f src/CMakeFiles/raspicam.dir/build.make src/CMakeFiles/raspicam.dir/build +.PHONY : raspicam/fast + +#============================================================================= +# Target rules for targets named raspicam_cv + +# Build rule for target. +raspicam_cv: cmake_check_build_system + $(MAKE) -f CMakeFiles/Makefile2 raspicam_cv +.PHONY : raspicam_cv + +# fast build rule for target. +raspicam_cv/fast: + $(MAKE) -f src/CMakeFiles/raspicam_cv.dir/build.make src/CMakeFiles/raspicam_cv.dir/build +.PHONY : raspicam_cv/fast + +#============================================================================= +# Target rules for targets named raspicam_cv_still_test + +# Build rule for target. +raspicam_cv_still_test: cmake_check_build_system + $(MAKE) -f CMakeFiles/Makefile2 raspicam_cv_still_test +.PHONY : raspicam_cv_still_test + +# fast build rule for target. +raspicam_cv_still_test/fast: + $(MAKE) -f utils/CMakeFiles/raspicam_cv_still_test.dir/build.make utils/CMakeFiles/raspicam_cv_still_test.dir/build +.PHONY : raspicam_cv_still_test/fast + +#============================================================================= +# Target rules for targets named raspicam_cv_test + +# Build rule for target. +raspicam_cv_test: cmake_check_build_system + $(MAKE) -f CMakeFiles/Makefile2 raspicam_cv_test +.PHONY : raspicam_cv_test + +# fast build rule for target. +raspicam_cv_test/fast: + $(MAKE) -f utils/CMakeFiles/raspicam_cv_test.dir/build.make utils/CMakeFiles/raspicam_cv_test.dir/build +.PHONY : raspicam_cv_test/fast + +#============================================================================= +# Target rules for targets named raspicam_still_test + +# Build rule for target. +raspicam_still_test: cmake_check_build_system + $(MAKE) -f CMakeFiles/Makefile2 raspicam_still_test +.PHONY : raspicam_still_test + +# fast build rule for target. +raspicam_still_test/fast: + $(MAKE) -f utils/CMakeFiles/raspicam_still_test.dir/build.make utils/CMakeFiles/raspicam_still_test.dir/build +.PHONY : raspicam_still_test/fast + +#============================================================================= +# Target rules for targets named raspicam_test + +# Build rule for target. +raspicam_test: cmake_check_build_system + $(MAKE) -f CMakeFiles/Makefile2 raspicam_test +.PHONY : raspicam_test + +# fast build rule for target. +raspicam_test/fast: + $(MAKE) -f utils/CMakeFiles/raspicam_test.dir/build.make utils/CMakeFiles/raspicam_test.dir/build +.PHONY : raspicam_test/fast + +# Help Target +help: + @echo "The following are some of the valid targets for this Makefile:" + @echo "... all (the default if no target is provided)" + @echo "... clean" + @echo "... depend" + @echo "... edit_cache" + @echo "... install" + @echo "... install/local" + @echo "... install/strip" + @echo "... list_install_components" + @echo "... rebuild_cache" + @echo "... uninstall" + @echo "... raspicam" + @echo "... raspicam_cv" + @echo "... raspicam_cv_still_test" + @echo "... raspicam_cv_test" + @echo "... raspicam_still_test" + @echo "... raspicam_test" +.PHONY : help + + + +#============================================================================= +# Special targets to cleanup operation of make. + +# Special rule to run CMake to check the build system integrity. +# No rule that depends on this can have commands that come from listfiles +# because they might be regenerated. +cmake_check_build_system: + $(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 0 +.PHONY : cmake_check_build_system + diff --git a/external_src/raspicam-0.1.3/build/cmake_install.cmake b/external_src/raspicam-0.1.3/build/cmake_install.cmake new file mode 100644 index 0000000..cacc597 --- /dev/null +++ b/external_src/raspicam-0.1.3/build/cmake_install.cmake @@ -0,0 +1,59 @@ +# Install script for directory: /home/ubuntu/Nomad/external_src/raspicam-0.1.3 + +# Set the install prefix +IF(NOT DEFINED CMAKE_INSTALL_PREFIX) + SET(CMAKE_INSTALL_PREFIX "/usr/local") +ENDIF(NOT DEFINED CMAKE_INSTALL_PREFIX) +STRING(REGEX REPLACE "/$" "" CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}") + +# Set the install configuration name. +IF(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME) + IF(BUILD_TYPE) + STRING(REGEX REPLACE "^[^A-Za-z0-9_]+" "" + CMAKE_INSTALL_CONFIG_NAME "${BUILD_TYPE}") + ELSE(BUILD_TYPE) + SET(CMAKE_INSTALL_CONFIG_NAME "Release") + ENDIF(BUILD_TYPE) + MESSAGE(STATUS "Install configuration: \"${CMAKE_INSTALL_CONFIG_NAME}\"") +ENDIF(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME) + +# Set the component getting installed. +IF(NOT CMAKE_INSTALL_COMPONENT) + IF(COMPONENT) + MESSAGE(STATUS "Install component: \"${COMPONENT}\"") + SET(CMAKE_INSTALL_COMPONENT "${COMPONENT}") + ELSE(COMPONENT) + SET(CMAKE_INSTALL_COMPONENT) + ENDIF(COMPONENT) +ENDIF(NOT CMAKE_INSTALL_COMPONENT) + +# Install shared libraries without execute permission? +IF(NOT DEFINED CMAKE_INSTALL_SO_NO_EXE) + SET(CMAKE_INSTALL_SO_NO_EXE "1") +ENDIF(NOT DEFINED CMAKE_INSTALL_SO_NO_EXE) + +IF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + FILE(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/lib/cmake" TYPE FILE FILES "/home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/Findraspicam.cmake") +ENDIF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + +IF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + FILE(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/lib/cmake" TYPE FILE FILES "/home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/raspicamConfig.cmake") +ENDIF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + +IF(NOT CMAKE_INSTALL_LOCAL_ONLY) + # Include the install script for each subdirectory. + INCLUDE("/home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/src/cmake_install.cmake") + INCLUDE("/home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/utils/cmake_install.cmake") + +ENDIF(NOT CMAKE_INSTALL_LOCAL_ONLY) + +IF(CMAKE_INSTALL_COMPONENT) + SET(CMAKE_INSTALL_MANIFEST "install_manifest_${CMAKE_INSTALL_COMPONENT}.txt") +ELSE(CMAKE_INSTALL_COMPONENT) + SET(CMAKE_INSTALL_MANIFEST "install_manifest.txt") +ENDIF(CMAKE_INSTALL_COMPONENT) + +FILE(WRITE "/home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/${CMAKE_INSTALL_MANIFEST}" "") +FOREACH(file ${CMAKE_INSTALL_MANIFEST_FILES}) + FILE(APPEND "/home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/${CMAKE_INSTALL_MANIFEST}" "${file}\n") +ENDFOREACH(file) diff --git a/external_src/raspicam-0.1.3/build/cmake_uninstall.cmake b/external_src/raspicam-0.1.3/build/cmake_uninstall.cmake new file mode 100644 index 0000000..46a149b --- /dev/null +++ b/external_src/raspicam-0.1.3/build/cmake_uninstall.cmake @@ -0,0 +1,28 @@ +# ----------------------------------------------- +# File that provides "make uninstall" target +# We use the file 'install_manifest.txt' +# ----------------------------------------------- +IF(NOT EXISTS "/home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/install_manifest.txt") + MESSAGE(FATAL_ERROR "Cannot find install manifest: \"/home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/install_manifest.txt\"") +ENDIF(NOT EXISTS "/home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/install_manifest.txt") + +FILE(READ "/home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/install_manifest.txt" files) +STRING(REGEX REPLACE "\n" ";" files "${files}") +FOREACH(file ${files}) + MESSAGE(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"") +# IF(EXISTS "$ENV{DESTDIR}${file}") +# EXEC_PROGRAM( +# "/usr/bin/cmake" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" +# OUTPUT_VARIABLE rm_out +# RETURN_VALUE rm_retval +# ) + EXECUTE_PROCESS(COMMAND rm $ENV{DESTDIR}${file}) +# IF(NOT "${rm_retval}" STREQUAL 0) +# MESSAGE(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"") +# ENDIF(NOT "${rm_retval}" STREQUAL 0) +# ELSE(EXISTS "$ENV{DESTDIR}${file}") +# MESSAGE(STATUS "File \"$ENV{DESTDIR}${file}\" does not exist.") +# ENDIF(EXISTS "$ENV{DESTDIR}${file}") +ENDFOREACH(file) + + diff --git a/external_src/raspicam-0.1.3/build/raspicamConfig.cmake b/external_src/raspicam-0.1.3/build/raspicamConfig.cmake new file mode 100644 index 0000000..539e008 --- /dev/null +++ b/external_src/raspicam-0.1.3/build/raspicamConfig.cmake @@ -0,0 +1,34 @@ +# =================================================================================== +# raspicam CMake configuration file +# +# ** File generated automatically, do not modify ** +# +# Usage from an external project: +# In your CMakeLists.txt, add these lines: +# +# FIND_PACKAGE(raspicam REQUIRED ) +# TARGET_LINK_LIBRARIES(MY_TARGET_NAME ) +# +# This file will define the following variables: +# - raspicam_LIBS : The list of libraries to links against. +# - raspicam_LIB_DIR : The directory where lib files are. Calling LINK_DIRECTORIES +# with this path is NOT needed. +# - raspicam_VERSION : The version of this PROJECT_NAME build. Example: "1.2.0" +# - raspicam_VERSION_MAJOR : Major version part of VERSION. Example: "1" +# - raspicam_VERSION_MINOR : Minor version part of VERSION. Example: "2" +# - raspicam_VERSION_PATCH : Patch version part of VERSION. Example: "0" +# +# =================================================================================== +INCLUDE_DIRECTORIES(;/usr/local/include) +LINK_DIRECTORIES("/usr/local/lib") + +SET(raspicam_LIBS /opt/vc/lib/libmmal_core.so;/opt/vc/lib/libmmal_util.so;/opt/vc/lib/libmmal.so raspicam) +SET(raspicam_FOUND "YES") + +SET(raspicam_CV_FOUND "YES") +SET(raspicam_CV_LIBS /opt/vc/lib/libmmal_core.so;/opt/vc/lib/libmmal_util.so;/opt/vc/lib/libmmal.so raspicam opencv_videostab;opencv_videoio;opencv_video;opencv_superres;opencv_stitching;opencv_shape;opencv_photo;opencv_objdetect;opencv_ml;opencv_imgproc;opencv_imgcodecs;opencv_highgui;opencv_hal;opencv_flann;opencv_features2d;opencv_core;opencv_calib3d raspicam_cv) + +SET(raspicam_VERSION 0.1.2) +SET(raspicam_VERSION_MAJOR 0) +SET(raspicam_VERSION_MINOR 1) +SET(raspicam_VERSION_PATCH 2) diff --git a/external_src/raspicam-0.1.3/build/src/CMakeFiles/CMakeDirectoryInformation.cmake b/external_src/raspicam-0.1.3/build/src/CMakeFiles/CMakeDirectoryInformation.cmake new file mode 100644 index 0000000..24120d7 --- /dev/null +++ b/external_src/raspicam-0.1.3/build/src/CMakeFiles/CMakeDirectoryInformation.cmake @@ -0,0 +1,16 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +# Relative path conversion top directories. +SET(CMAKE_RELATIVE_PATH_TOP_SOURCE "/home/ubuntu/Nomad/external_src/raspicam-0.1.3") +SET(CMAKE_RELATIVE_PATH_TOP_BINARY "/home/ubuntu/Nomad/external_src/raspicam-0.1.3/build") + +# Force unix paths in dependencies. +SET(CMAKE_FORCE_UNIX_PATHS 1) + + +# The C and CXX include file regular expressions for this directory. +SET(CMAKE_C_INCLUDE_REGEX_SCAN "^.*$") +SET(CMAKE_C_INCLUDE_REGEX_COMPLAIN "^$") +SET(CMAKE_CXX_INCLUDE_REGEX_SCAN ${CMAKE_C_INCLUDE_REGEX_SCAN}) +SET(CMAKE_CXX_INCLUDE_REGEX_COMPLAIN ${CMAKE_C_INCLUDE_REGEX_COMPLAIN}) diff --git a/external_src/raspicam-0.1.3/build/src/CMakeFiles/progress.marks b/external_src/raspicam-0.1.3/build/src/CMakeFiles/progress.marks new file mode 100644 index 0000000..7f8f011 --- /dev/null +++ b/external_src/raspicam-0.1.3/build/src/CMakeFiles/progress.marks @@ -0,0 +1 @@ +7 diff --git a/external_src/raspicam-0.1.3/build/src/CMakeFiles/raspicam.dir/DependInfo.cmake b/external_src/raspicam-0.1.3/build/src/CMakeFiles/raspicam.dir/DependInfo.cmake new file mode 100644 index 0000000..3ffd2bc --- /dev/null +++ b/external_src/raspicam-0.1.3/build/src/CMakeFiles/raspicam.dir/DependInfo.cmake @@ -0,0 +1,38 @@ +# The set of languages for which implicit dependencies are needed: +SET(CMAKE_DEPENDS_LANGUAGES + "CXX" + ) +# The set of files for implicit dependencies of each language: +SET(CMAKE_DEPENDS_CHECK_CXX + "/home/ubuntu/Nomad/external_src/raspicam-0.1.3/src/private/private_impl.cpp" "/home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/src/CMakeFiles/raspicam.dir/private/private_impl.cpp.o" + "/home/ubuntu/Nomad/external_src/raspicam-0.1.3/src/private/threadcondition.cpp" "/home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/src/CMakeFiles/raspicam.dir/private/threadcondition.cpp.o" + "/home/ubuntu/Nomad/external_src/raspicam-0.1.3/src/private_still/private_still_impl.cpp" "/home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/src/CMakeFiles/raspicam.dir/private_still/private_still_impl.cpp.o" + "/home/ubuntu/Nomad/external_src/raspicam-0.1.3/src/raspicam.cpp" "/home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/src/CMakeFiles/raspicam.dir/raspicam.cpp.o" + "/home/ubuntu/Nomad/external_src/raspicam-0.1.3/src/raspicam_still.cpp" "/home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/src/CMakeFiles/raspicam.dir/raspicam_still.cpp.o" + ) +SET(CMAKE_CXX_COMPILER_ID "GNU") + +# Pairs of files generated by the same build rule. +SET(CMAKE_MULTIPLE_OUTPUT_PAIRS + "/home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/src/libraspicam.so" "/home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/src/libraspicam.so.0.1.2" + "/home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/src/libraspicam.so.0.1" "/home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/src/libraspicam.so.0.1.2" + ) + + +# Targets to which this target links. +SET(CMAKE_TARGET_LINKED_INFO_FILES + ) + +# The include file search paths: +SET(CMAKE_C_TARGET_INCLUDE_PATH + "../dependencies" + "../dependencies/mmal" + "../dependencies/vcos" + "/usr/local/include/opencv" + "/usr/local/include" + "../src/." + "src" + ) +SET(CMAKE_CXX_TARGET_INCLUDE_PATH ${CMAKE_C_TARGET_INCLUDE_PATH}) +SET(CMAKE_Fortran_TARGET_INCLUDE_PATH ${CMAKE_C_TARGET_INCLUDE_PATH}) +SET(CMAKE_ASM_TARGET_INCLUDE_PATH ${CMAKE_C_TARGET_INCLUDE_PATH}) diff --git a/external_src/raspicam-0.1.3/build/src/CMakeFiles/raspicam.dir/build.make b/external_src/raspicam-0.1.3/build/src/CMakeFiles/raspicam.dir/build.make new file mode 100644 index 0000000..510a80c --- /dev/null +++ b/external_src/raspicam-0.1.3/build/src/CMakeFiles/raspicam.dir/build.make @@ -0,0 +1,214 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/ubuntu/Nomad/external_src/raspicam-0.1.3 + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build + +# Include any dependencies generated for this target. +include src/CMakeFiles/raspicam.dir/depend.make + +# Include the progress variables for this target. +include src/CMakeFiles/raspicam.dir/progress.make + +# Include the compile flags for this target's objects. +include src/CMakeFiles/raspicam.dir/flags.make + +src/CMakeFiles/raspicam.dir/raspicam.cpp.o: src/CMakeFiles/raspicam.dir/flags.make +src/CMakeFiles/raspicam.dir/raspicam.cpp.o: ../src/raspicam.cpp + $(CMAKE_COMMAND) -E cmake_progress_report /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/CMakeFiles $(CMAKE_PROGRESS_1) + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Building CXX object src/CMakeFiles/raspicam.dir/raspicam.cpp.o" + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/src && /usr/bin/c++ $(CXX_DEFINES) $(CXX_FLAGS) -o CMakeFiles/raspicam.dir/raspicam.cpp.o -c /home/ubuntu/Nomad/external_src/raspicam-0.1.3/src/raspicam.cpp + +src/CMakeFiles/raspicam.dir/raspicam.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing CXX source to CMakeFiles/raspicam.dir/raspicam.cpp.i" + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/src && /usr/bin/c++ $(CXX_DEFINES) $(CXX_FLAGS) -E /home/ubuntu/Nomad/external_src/raspicam-0.1.3/src/raspicam.cpp > CMakeFiles/raspicam.dir/raspicam.cpp.i + +src/CMakeFiles/raspicam.dir/raspicam.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling CXX source to assembly CMakeFiles/raspicam.dir/raspicam.cpp.s" + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/src && /usr/bin/c++ $(CXX_DEFINES) $(CXX_FLAGS) -S /home/ubuntu/Nomad/external_src/raspicam-0.1.3/src/raspicam.cpp -o CMakeFiles/raspicam.dir/raspicam.cpp.s + +src/CMakeFiles/raspicam.dir/raspicam.cpp.o.requires: +.PHONY : src/CMakeFiles/raspicam.dir/raspicam.cpp.o.requires + +src/CMakeFiles/raspicam.dir/raspicam.cpp.o.provides: src/CMakeFiles/raspicam.dir/raspicam.cpp.o.requires + $(MAKE) -f src/CMakeFiles/raspicam.dir/build.make src/CMakeFiles/raspicam.dir/raspicam.cpp.o.provides.build +.PHONY : src/CMakeFiles/raspicam.dir/raspicam.cpp.o.provides + +src/CMakeFiles/raspicam.dir/raspicam.cpp.o.provides.build: src/CMakeFiles/raspicam.dir/raspicam.cpp.o + +src/CMakeFiles/raspicam.dir/raspicam_still.cpp.o: src/CMakeFiles/raspicam.dir/flags.make +src/CMakeFiles/raspicam.dir/raspicam_still.cpp.o: ../src/raspicam_still.cpp + $(CMAKE_COMMAND) -E cmake_progress_report /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/CMakeFiles $(CMAKE_PROGRESS_2) + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Building CXX object src/CMakeFiles/raspicam.dir/raspicam_still.cpp.o" + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/src && /usr/bin/c++ $(CXX_DEFINES) $(CXX_FLAGS) -o CMakeFiles/raspicam.dir/raspicam_still.cpp.o -c /home/ubuntu/Nomad/external_src/raspicam-0.1.3/src/raspicam_still.cpp + +src/CMakeFiles/raspicam.dir/raspicam_still.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing CXX source to CMakeFiles/raspicam.dir/raspicam_still.cpp.i" + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/src && /usr/bin/c++ $(CXX_DEFINES) $(CXX_FLAGS) -E /home/ubuntu/Nomad/external_src/raspicam-0.1.3/src/raspicam_still.cpp > CMakeFiles/raspicam.dir/raspicam_still.cpp.i + +src/CMakeFiles/raspicam.dir/raspicam_still.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling CXX source to assembly CMakeFiles/raspicam.dir/raspicam_still.cpp.s" + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/src && /usr/bin/c++ $(CXX_DEFINES) $(CXX_FLAGS) -S /home/ubuntu/Nomad/external_src/raspicam-0.1.3/src/raspicam_still.cpp -o CMakeFiles/raspicam.dir/raspicam_still.cpp.s + +src/CMakeFiles/raspicam.dir/raspicam_still.cpp.o.requires: +.PHONY : src/CMakeFiles/raspicam.dir/raspicam_still.cpp.o.requires + +src/CMakeFiles/raspicam.dir/raspicam_still.cpp.o.provides: src/CMakeFiles/raspicam.dir/raspicam_still.cpp.o.requires + $(MAKE) -f src/CMakeFiles/raspicam.dir/build.make src/CMakeFiles/raspicam.dir/raspicam_still.cpp.o.provides.build +.PHONY : src/CMakeFiles/raspicam.dir/raspicam_still.cpp.o.provides + +src/CMakeFiles/raspicam.dir/raspicam_still.cpp.o.provides.build: src/CMakeFiles/raspicam.dir/raspicam_still.cpp.o + +src/CMakeFiles/raspicam.dir/private/private_impl.cpp.o: src/CMakeFiles/raspicam.dir/flags.make +src/CMakeFiles/raspicam.dir/private/private_impl.cpp.o: ../src/private/private_impl.cpp + $(CMAKE_COMMAND) -E cmake_progress_report /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/CMakeFiles $(CMAKE_PROGRESS_3) + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Building CXX object src/CMakeFiles/raspicam.dir/private/private_impl.cpp.o" + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/src && /usr/bin/c++ $(CXX_DEFINES) $(CXX_FLAGS) -o CMakeFiles/raspicam.dir/private/private_impl.cpp.o -c /home/ubuntu/Nomad/external_src/raspicam-0.1.3/src/private/private_impl.cpp + +src/CMakeFiles/raspicam.dir/private/private_impl.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing CXX source to CMakeFiles/raspicam.dir/private/private_impl.cpp.i" + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/src && /usr/bin/c++ $(CXX_DEFINES) $(CXX_FLAGS) -E /home/ubuntu/Nomad/external_src/raspicam-0.1.3/src/private/private_impl.cpp > CMakeFiles/raspicam.dir/private/private_impl.cpp.i + +src/CMakeFiles/raspicam.dir/private/private_impl.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling CXX source to assembly CMakeFiles/raspicam.dir/private/private_impl.cpp.s" + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/src && /usr/bin/c++ $(CXX_DEFINES) $(CXX_FLAGS) -S /home/ubuntu/Nomad/external_src/raspicam-0.1.3/src/private/private_impl.cpp -o CMakeFiles/raspicam.dir/private/private_impl.cpp.s + +src/CMakeFiles/raspicam.dir/private/private_impl.cpp.o.requires: +.PHONY : src/CMakeFiles/raspicam.dir/private/private_impl.cpp.o.requires + +src/CMakeFiles/raspicam.dir/private/private_impl.cpp.o.provides: src/CMakeFiles/raspicam.dir/private/private_impl.cpp.o.requires + $(MAKE) -f src/CMakeFiles/raspicam.dir/build.make src/CMakeFiles/raspicam.dir/private/private_impl.cpp.o.provides.build +.PHONY : src/CMakeFiles/raspicam.dir/private/private_impl.cpp.o.provides + +src/CMakeFiles/raspicam.dir/private/private_impl.cpp.o.provides.build: src/CMakeFiles/raspicam.dir/private/private_impl.cpp.o + +src/CMakeFiles/raspicam.dir/private/threadcondition.cpp.o: src/CMakeFiles/raspicam.dir/flags.make +src/CMakeFiles/raspicam.dir/private/threadcondition.cpp.o: ../src/private/threadcondition.cpp + $(CMAKE_COMMAND) -E cmake_progress_report /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/CMakeFiles $(CMAKE_PROGRESS_4) + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Building CXX object src/CMakeFiles/raspicam.dir/private/threadcondition.cpp.o" + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/src && /usr/bin/c++ $(CXX_DEFINES) $(CXX_FLAGS) -o CMakeFiles/raspicam.dir/private/threadcondition.cpp.o -c /home/ubuntu/Nomad/external_src/raspicam-0.1.3/src/private/threadcondition.cpp + +src/CMakeFiles/raspicam.dir/private/threadcondition.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing CXX source to CMakeFiles/raspicam.dir/private/threadcondition.cpp.i" + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/src && /usr/bin/c++ $(CXX_DEFINES) $(CXX_FLAGS) -E /home/ubuntu/Nomad/external_src/raspicam-0.1.3/src/private/threadcondition.cpp > CMakeFiles/raspicam.dir/private/threadcondition.cpp.i + +src/CMakeFiles/raspicam.dir/private/threadcondition.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling CXX source to assembly CMakeFiles/raspicam.dir/private/threadcondition.cpp.s" + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/src && /usr/bin/c++ $(CXX_DEFINES) $(CXX_FLAGS) -S /home/ubuntu/Nomad/external_src/raspicam-0.1.3/src/private/threadcondition.cpp -o CMakeFiles/raspicam.dir/private/threadcondition.cpp.s + +src/CMakeFiles/raspicam.dir/private/threadcondition.cpp.o.requires: +.PHONY : src/CMakeFiles/raspicam.dir/private/threadcondition.cpp.o.requires + +src/CMakeFiles/raspicam.dir/private/threadcondition.cpp.o.provides: src/CMakeFiles/raspicam.dir/private/threadcondition.cpp.o.requires + $(MAKE) -f src/CMakeFiles/raspicam.dir/build.make src/CMakeFiles/raspicam.dir/private/threadcondition.cpp.o.provides.build +.PHONY : src/CMakeFiles/raspicam.dir/private/threadcondition.cpp.o.provides + +src/CMakeFiles/raspicam.dir/private/threadcondition.cpp.o.provides.build: src/CMakeFiles/raspicam.dir/private/threadcondition.cpp.o + +src/CMakeFiles/raspicam.dir/private_still/private_still_impl.cpp.o: src/CMakeFiles/raspicam.dir/flags.make +src/CMakeFiles/raspicam.dir/private_still/private_still_impl.cpp.o: ../src/private_still/private_still_impl.cpp + $(CMAKE_COMMAND) -E cmake_progress_report /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/CMakeFiles $(CMAKE_PROGRESS_5) + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Building CXX object src/CMakeFiles/raspicam.dir/private_still/private_still_impl.cpp.o" + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/src && /usr/bin/c++ $(CXX_DEFINES) $(CXX_FLAGS) -o CMakeFiles/raspicam.dir/private_still/private_still_impl.cpp.o -c /home/ubuntu/Nomad/external_src/raspicam-0.1.3/src/private_still/private_still_impl.cpp + +src/CMakeFiles/raspicam.dir/private_still/private_still_impl.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing CXX source to CMakeFiles/raspicam.dir/private_still/private_still_impl.cpp.i" + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/src && /usr/bin/c++ $(CXX_DEFINES) $(CXX_FLAGS) -E /home/ubuntu/Nomad/external_src/raspicam-0.1.3/src/private_still/private_still_impl.cpp > CMakeFiles/raspicam.dir/private_still/private_still_impl.cpp.i + +src/CMakeFiles/raspicam.dir/private_still/private_still_impl.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling CXX source to assembly CMakeFiles/raspicam.dir/private_still/private_still_impl.cpp.s" + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/src && /usr/bin/c++ $(CXX_DEFINES) $(CXX_FLAGS) -S /home/ubuntu/Nomad/external_src/raspicam-0.1.3/src/private_still/private_still_impl.cpp -o CMakeFiles/raspicam.dir/private_still/private_still_impl.cpp.s + +src/CMakeFiles/raspicam.dir/private_still/private_still_impl.cpp.o.requires: +.PHONY : src/CMakeFiles/raspicam.dir/private_still/private_still_impl.cpp.o.requires + +src/CMakeFiles/raspicam.dir/private_still/private_still_impl.cpp.o.provides: src/CMakeFiles/raspicam.dir/private_still/private_still_impl.cpp.o.requires + $(MAKE) -f src/CMakeFiles/raspicam.dir/build.make src/CMakeFiles/raspicam.dir/private_still/private_still_impl.cpp.o.provides.build +.PHONY : src/CMakeFiles/raspicam.dir/private_still/private_still_impl.cpp.o.provides + +src/CMakeFiles/raspicam.dir/private_still/private_still_impl.cpp.o.provides.build: src/CMakeFiles/raspicam.dir/private_still/private_still_impl.cpp.o + +# Object files for target raspicam +raspicam_OBJECTS = \ +"CMakeFiles/raspicam.dir/raspicam.cpp.o" \ +"CMakeFiles/raspicam.dir/raspicam_still.cpp.o" \ +"CMakeFiles/raspicam.dir/private/private_impl.cpp.o" \ +"CMakeFiles/raspicam.dir/private/threadcondition.cpp.o" \ +"CMakeFiles/raspicam.dir/private_still/private_still_impl.cpp.o" + +# External object files for target raspicam +raspicam_EXTERNAL_OBJECTS = + +src/libraspicam.so.0.1.2: src/CMakeFiles/raspicam.dir/raspicam.cpp.o +src/libraspicam.so.0.1.2: src/CMakeFiles/raspicam.dir/raspicam_still.cpp.o +src/libraspicam.so.0.1.2: src/CMakeFiles/raspicam.dir/private/private_impl.cpp.o +src/libraspicam.so.0.1.2: src/CMakeFiles/raspicam.dir/private/threadcondition.cpp.o +src/libraspicam.so.0.1.2: src/CMakeFiles/raspicam.dir/private_still/private_still_impl.cpp.o +src/libraspicam.so.0.1.2: src/CMakeFiles/raspicam.dir/build.make +src/libraspicam.so.0.1.2: /opt/vc/lib/libmmal_core.so +src/libraspicam.so.0.1.2: /opt/vc/lib/libmmal_util.so +src/libraspicam.so.0.1.2: /opt/vc/lib/libmmal.so +src/libraspicam.so.0.1.2: src/CMakeFiles/raspicam.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --red --bold "Linking CXX shared library libraspicam.so" + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/src && $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/raspicam.dir/link.txt --verbose=$(VERBOSE) + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/src && $(CMAKE_COMMAND) -E cmake_symlink_library libraspicam.so.0.1.2 libraspicam.so.0.1 libraspicam.so + +src/libraspicam.so.0.1: src/libraspicam.so.0.1.2 + +src/libraspicam.so: src/libraspicam.so.0.1.2 + +# Rule to build all files generated by this target. +src/CMakeFiles/raspicam.dir/build: src/libraspicam.so +.PHONY : src/CMakeFiles/raspicam.dir/build + +src/CMakeFiles/raspicam.dir/requires: src/CMakeFiles/raspicam.dir/raspicam.cpp.o.requires +src/CMakeFiles/raspicam.dir/requires: src/CMakeFiles/raspicam.dir/raspicam_still.cpp.o.requires +src/CMakeFiles/raspicam.dir/requires: src/CMakeFiles/raspicam.dir/private/private_impl.cpp.o.requires +src/CMakeFiles/raspicam.dir/requires: src/CMakeFiles/raspicam.dir/private/threadcondition.cpp.o.requires +src/CMakeFiles/raspicam.dir/requires: src/CMakeFiles/raspicam.dir/private_still/private_still_impl.cpp.o.requires +.PHONY : src/CMakeFiles/raspicam.dir/requires + +src/CMakeFiles/raspicam.dir/clean: + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/src && $(CMAKE_COMMAND) -P CMakeFiles/raspicam.dir/cmake_clean.cmake +.PHONY : src/CMakeFiles/raspicam.dir/clean + +src/CMakeFiles/raspicam.dir/depend: + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/ubuntu/Nomad/external_src/raspicam-0.1.3 /home/ubuntu/Nomad/external_src/raspicam-0.1.3/src /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/src /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/src/CMakeFiles/raspicam.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : src/CMakeFiles/raspicam.dir/depend + diff --git a/external_src/raspicam-0.1.3/build/src/CMakeFiles/raspicam.dir/cmake_clean.cmake b/external_src/raspicam-0.1.3/build/src/CMakeFiles/raspicam.dir/cmake_clean.cmake new file mode 100644 index 0000000..a8e1843 --- /dev/null +++ b/external_src/raspicam-0.1.3/build/src/CMakeFiles/raspicam.dir/cmake_clean.cmake @@ -0,0 +1,16 @@ +FILE(REMOVE_RECURSE + "CMakeFiles/raspicam.dir/raspicam.cpp.o" + "CMakeFiles/raspicam.dir/raspicam_still.cpp.o" + "CMakeFiles/raspicam.dir/private/private_impl.cpp.o" + "CMakeFiles/raspicam.dir/private/threadcondition.cpp.o" + "CMakeFiles/raspicam.dir/private_still/private_still_impl.cpp.o" + "libraspicam.pdb" + "libraspicam.so" + "libraspicam.so.0.1.2" + "libraspicam.so.0.1" +) + +# Per-language clean rules from dependency scanning. +FOREACH(lang CXX) + INCLUDE(CMakeFiles/raspicam.dir/cmake_clean_${lang}.cmake OPTIONAL) +ENDFOREACH(lang) diff --git a/external_src/raspicam-0.1.3/build/src/CMakeFiles/raspicam.dir/depend.make b/external_src/raspicam-0.1.3/build/src/CMakeFiles/raspicam.dir/depend.make new file mode 100644 index 0000000..ea0f1d8 --- /dev/null +++ b/external_src/raspicam-0.1.3/build/src/CMakeFiles/raspicam.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for raspicam. +# This may be replaced when dependencies are built. diff --git a/external_src/raspicam-0.1.3/build/src/CMakeFiles/raspicam.dir/flags.make b/external_src/raspicam-0.1.3/build/src/CMakeFiles/raspicam.dir/flags.make new file mode 100644 index 0000000..d84e64e --- /dev/null +++ b/external_src/raspicam-0.1.3/build/src/CMakeFiles/raspicam.dir/flags.make @@ -0,0 +1,8 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +# compile CXX with /usr/bin/c++ +CXX_FLAGS = -std=c++0x -Wl,--no-as-needed -Wall -ffunction-sections -fomit-frame-pointer -O2 -ffast-math -DNDEBUG -lpthread -fPIC -I/home/ubuntu/Nomad/external_src/raspicam-0.1.3/dependencies -I/home/ubuntu/Nomad/external_src/raspicam-0.1.3/dependencies/mmal -I/home/ubuntu/Nomad/external_src/raspicam-0.1.3/dependencies/vcos -I/usr/local/include/opencv -I/usr/local/include -I/home/ubuntu/Nomad/external_src/raspicam-0.1.3/src/. -I/home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/src + +CXX_DEFINES = -DDSO_EXPORTS + diff --git a/external_src/raspicam-0.1.3/build/src/CMakeFiles/raspicam.dir/link.txt b/external_src/raspicam-0.1.3/build/src/CMakeFiles/raspicam.dir/link.txt new file mode 100644 index 0000000..c722a1f --- /dev/null +++ b/external_src/raspicam-0.1.3/build/src/CMakeFiles/raspicam.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fPIC -std=c++0x -Wl,--no-as-needed -Wall -ffunction-sections -fomit-frame-pointer -O2 -ffast-math -DNDEBUG -lpthread -shared -Wl,-soname,libraspicam.so.0.1 -o libraspicam.so.0.1.2 CMakeFiles/raspicam.dir/raspicam.cpp.o CMakeFiles/raspicam.dir/raspicam_still.cpp.o CMakeFiles/raspicam.dir/private/private_impl.cpp.o CMakeFiles/raspicam.dir/private/threadcondition.cpp.o CMakeFiles/raspicam.dir/private_still/private_still_impl.cpp.o /opt/vc/lib/libmmal_core.so /opt/vc/lib/libmmal_util.so /opt/vc/lib/libmmal.so -Wl,-rpath,/opt/vc/lib: diff --git a/external_src/raspicam-0.1.3/build/src/CMakeFiles/raspicam.dir/progress.make b/external_src/raspicam-0.1.3/build/src/CMakeFiles/raspicam.dir/progress.make new file mode 100644 index 0000000..33e6bff --- /dev/null +++ b/external_src/raspicam-0.1.3/build/src/CMakeFiles/raspicam.dir/progress.make @@ -0,0 +1,6 @@ +CMAKE_PROGRESS_1 = 1 +CMAKE_PROGRESS_2 = 2 +CMAKE_PROGRESS_3 = 3 +CMAKE_PROGRESS_4 = 4 +CMAKE_PROGRESS_5 = 5 + diff --git a/external_src/raspicam-0.1.3/build/src/CMakeFiles/raspicam_cv.dir/DependInfo.cmake b/external_src/raspicam-0.1.3/build/src/CMakeFiles/raspicam_cv.dir/DependInfo.cmake new file mode 100644 index 0000000..6b2ac46 --- /dev/null +++ b/external_src/raspicam-0.1.3/build/src/CMakeFiles/raspicam_cv.dir/DependInfo.cmake @@ -0,0 +1,28 @@ +# The set of languages for which implicit dependencies are needed: +SET(CMAKE_DEPENDS_LANGUAGES + "CXX" + ) +# The set of files for implicit dependencies of each language: +SET(CMAKE_DEPENDS_CHECK_CXX + "/home/ubuntu/Nomad/external_src/raspicam-0.1.3/src/raspicam_cv.cpp" "/home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/src/CMakeFiles/raspicam_cv.dir/raspicam_cv.cpp.o" + "/home/ubuntu/Nomad/external_src/raspicam-0.1.3/src/raspicam_still_cv.cpp" "/home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/src/CMakeFiles/raspicam_cv.dir/raspicam_still_cv.cpp.o" + ) +SET(CMAKE_CXX_COMPILER_ID "GNU") + +# Targets to which this target links. +SET(CMAKE_TARGET_LINKED_INFO_FILES + ) + +# The include file search paths: +SET(CMAKE_C_TARGET_INCLUDE_PATH + "../dependencies" + "../dependencies/mmal" + "../dependencies/vcos" + "/usr/local/include/opencv" + "/usr/local/include" + "../src/." + "src" + ) +SET(CMAKE_CXX_TARGET_INCLUDE_PATH ${CMAKE_C_TARGET_INCLUDE_PATH}) +SET(CMAKE_Fortran_TARGET_INCLUDE_PATH ${CMAKE_C_TARGET_INCLUDE_PATH}) +SET(CMAKE_ASM_TARGET_INCLUDE_PATH ${CMAKE_C_TARGET_INCLUDE_PATH}) diff --git a/external_src/raspicam-0.1.3/build/src/CMakeFiles/raspicam_cv.dir/build.make b/external_src/raspicam-0.1.3/build/src/CMakeFiles/raspicam_cv.dir/build.make new file mode 100644 index 0000000..4221015 --- /dev/null +++ b/external_src/raspicam-0.1.3/build/src/CMakeFiles/raspicam_cv.dir/build.make @@ -0,0 +1,158 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/ubuntu/Nomad/external_src/raspicam-0.1.3 + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build + +# Include any dependencies generated for this target. +include src/CMakeFiles/raspicam_cv.dir/depend.make + +# Include the progress variables for this target. +include src/CMakeFiles/raspicam_cv.dir/progress.make + +# Include the compile flags for this target's objects. +include src/CMakeFiles/raspicam_cv.dir/flags.make + +src/CMakeFiles/raspicam_cv.dir/raspicam_cv.cpp.o: src/CMakeFiles/raspicam_cv.dir/flags.make +src/CMakeFiles/raspicam_cv.dir/raspicam_cv.cpp.o: ../src/raspicam_cv.cpp + $(CMAKE_COMMAND) -E cmake_progress_report /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/CMakeFiles $(CMAKE_PROGRESS_1) + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Building CXX object src/CMakeFiles/raspicam_cv.dir/raspicam_cv.cpp.o" + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/src && /usr/bin/c++ $(CXX_DEFINES) $(CXX_FLAGS) -o CMakeFiles/raspicam_cv.dir/raspicam_cv.cpp.o -c /home/ubuntu/Nomad/external_src/raspicam-0.1.3/src/raspicam_cv.cpp + +src/CMakeFiles/raspicam_cv.dir/raspicam_cv.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing CXX source to CMakeFiles/raspicam_cv.dir/raspicam_cv.cpp.i" + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/src && /usr/bin/c++ $(CXX_DEFINES) $(CXX_FLAGS) -E /home/ubuntu/Nomad/external_src/raspicam-0.1.3/src/raspicam_cv.cpp > CMakeFiles/raspicam_cv.dir/raspicam_cv.cpp.i + +src/CMakeFiles/raspicam_cv.dir/raspicam_cv.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling CXX source to assembly CMakeFiles/raspicam_cv.dir/raspicam_cv.cpp.s" + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/src && /usr/bin/c++ $(CXX_DEFINES) $(CXX_FLAGS) -S /home/ubuntu/Nomad/external_src/raspicam-0.1.3/src/raspicam_cv.cpp -o CMakeFiles/raspicam_cv.dir/raspicam_cv.cpp.s + +src/CMakeFiles/raspicam_cv.dir/raspicam_cv.cpp.o.requires: +.PHONY : src/CMakeFiles/raspicam_cv.dir/raspicam_cv.cpp.o.requires + +src/CMakeFiles/raspicam_cv.dir/raspicam_cv.cpp.o.provides: src/CMakeFiles/raspicam_cv.dir/raspicam_cv.cpp.o.requires + $(MAKE) -f src/CMakeFiles/raspicam_cv.dir/build.make src/CMakeFiles/raspicam_cv.dir/raspicam_cv.cpp.o.provides.build +.PHONY : src/CMakeFiles/raspicam_cv.dir/raspicam_cv.cpp.o.provides + +src/CMakeFiles/raspicam_cv.dir/raspicam_cv.cpp.o.provides.build: src/CMakeFiles/raspicam_cv.dir/raspicam_cv.cpp.o + +src/CMakeFiles/raspicam_cv.dir/raspicam_still_cv.cpp.o: src/CMakeFiles/raspicam_cv.dir/flags.make +src/CMakeFiles/raspicam_cv.dir/raspicam_still_cv.cpp.o: ../src/raspicam_still_cv.cpp + $(CMAKE_COMMAND) -E cmake_progress_report /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/CMakeFiles $(CMAKE_PROGRESS_2) + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Building CXX object src/CMakeFiles/raspicam_cv.dir/raspicam_still_cv.cpp.o" + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/src && /usr/bin/c++ $(CXX_DEFINES) $(CXX_FLAGS) -o CMakeFiles/raspicam_cv.dir/raspicam_still_cv.cpp.o -c /home/ubuntu/Nomad/external_src/raspicam-0.1.3/src/raspicam_still_cv.cpp + +src/CMakeFiles/raspicam_cv.dir/raspicam_still_cv.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing CXX source to CMakeFiles/raspicam_cv.dir/raspicam_still_cv.cpp.i" + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/src && /usr/bin/c++ $(CXX_DEFINES) $(CXX_FLAGS) -E /home/ubuntu/Nomad/external_src/raspicam-0.1.3/src/raspicam_still_cv.cpp > CMakeFiles/raspicam_cv.dir/raspicam_still_cv.cpp.i + +src/CMakeFiles/raspicam_cv.dir/raspicam_still_cv.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling CXX source to assembly CMakeFiles/raspicam_cv.dir/raspicam_still_cv.cpp.s" + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/src && /usr/bin/c++ $(CXX_DEFINES) $(CXX_FLAGS) -S /home/ubuntu/Nomad/external_src/raspicam-0.1.3/src/raspicam_still_cv.cpp -o CMakeFiles/raspicam_cv.dir/raspicam_still_cv.cpp.s + +src/CMakeFiles/raspicam_cv.dir/raspicam_still_cv.cpp.o.requires: +.PHONY : src/CMakeFiles/raspicam_cv.dir/raspicam_still_cv.cpp.o.requires + +src/CMakeFiles/raspicam_cv.dir/raspicam_still_cv.cpp.o.provides: src/CMakeFiles/raspicam_cv.dir/raspicam_still_cv.cpp.o.requires + $(MAKE) -f src/CMakeFiles/raspicam_cv.dir/build.make src/CMakeFiles/raspicam_cv.dir/raspicam_still_cv.cpp.o.provides.build +.PHONY : src/CMakeFiles/raspicam_cv.dir/raspicam_still_cv.cpp.o.provides + +src/CMakeFiles/raspicam_cv.dir/raspicam_still_cv.cpp.o.provides.build: src/CMakeFiles/raspicam_cv.dir/raspicam_still_cv.cpp.o + +# Object files for target raspicam_cv +raspicam_cv_OBJECTS = \ +"CMakeFiles/raspicam_cv.dir/raspicam_cv.cpp.o" \ +"CMakeFiles/raspicam_cv.dir/raspicam_still_cv.cpp.o" + +# External object files for target raspicam_cv +raspicam_cv_EXTERNAL_OBJECTS = + +src/libraspicam_cv.so: src/CMakeFiles/raspicam_cv.dir/raspicam_cv.cpp.o +src/libraspicam_cv.so: src/CMakeFiles/raspicam_cv.dir/raspicam_still_cv.cpp.o +src/libraspicam_cv.so: src/CMakeFiles/raspicam_cv.dir/build.make +src/libraspicam_cv.so: /opt/vc/lib/libmmal_core.so +src/libraspicam_cv.so: /opt/vc/lib/libmmal_util.so +src/libraspicam_cv.so: /opt/vc/lib/libmmal.so +src/libraspicam_cv.so: /usr/local/lib/libopencv_videostab.so.3.0.0 +src/libraspicam_cv.so: /usr/local/lib/libopencv_videoio.so.3.0.0 +src/libraspicam_cv.so: /usr/local/lib/libopencv_video.so.3.0.0 +src/libraspicam_cv.so: /usr/local/lib/libopencv_superres.so.3.0.0 +src/libraspicam_cv.so: /usr/local/lib/libopencv_stitching.so.3.0.0 +src/libraspicam_cv.so: /usr/local/lib/libopencv_shape.so.3.0.0 +src/libraspicam_cv.so: /usr/local/lib/libopencv_photo.so.3.0.0 +src/libraspicam_cv.so: /usr/local/lib/libopencv_objdetect.so.3.0.0 +src/libraspicam_cv.so: /usr/local/lib/libopencv_ml.so.3.0.0 +src/libraspicam_cv.so: /usr/local/lib/libopencv_imgproc.so.3.0.0 +src/libraspicam_cv.so: /usr/local/lib/libopencv_imgcodecs.so.3.0.0 +src/libraspicam_cv.so: /usr/local/lib/libopencv_highgui.so.3.0.0 +src/libraspicam_cv.so: /usr/local/lib/libopencv_hal.a +src/libraspicam_cv.so: /usr/local/lib/libopencv_flann.so.3.0.0 +src/libraspicam_cv.so: /usr/local/lib/libopencv_features2d.so.3.0.0 +src/libraspicam_cv.so: /usr/local/lib/libopencv_core.so.3.0.0 +src/libraspicam_cv.so: /usr/local/lib/libopencv_calib3d.so.3.0.0 +src/libraspicam_cv.so: /usr/local/lib/libopencv_features2d.so.3.0.0 +src/libraspicam_cv.so: /usr/local/lib/libopencv_ml.so.3.0.0 +src/libraspicam_cv.so: /usr/local/lib/libopencv_highgui.so.3.0.0 +src/libraspicam_cv.so: /usr/local/lib/libopencv_videoio.so.3.0.0 +src/libraspicam_cv.so: /usr/local/lib/libopencv_imgcodecs.so.3.0.0 +src/libraspicam_cv.so: /usr/local/lib/libopencv_flann.so.3.0.0 +src/libraspicam_cv.so: /usr/local/lib/libopencv_video.so.3.0.0 +src/libraspicam_cv.so: /usr/local/lib/libopencv_imgproc.so.3.0.0 +src/libraspicam_cv.so: /usr/local/lib/libopencv_core.so.3.0.0 +src/libraspicam_cv.so: /usr/local/lib/libopencv_hal.a +src/libraspicam_cv.so: src/CMakeFiles/raspicam_cv.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --red --bold "Linking CXX shared library libraspicam_cv.so" + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/src && $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/raspicam_cv.dir/link.txt --verbose=$(VERBOSE) + +# Rule to build all files generated by this target. +src/CMakeFiles/raspicam_cv.dir/build: src/libraspicam_cv.so +.PHONY : src/CMakeFiles/raspicam_cv.dir/build + +src/CMakeFiles/raspicam_cv.dir/requires: src/CMakeFiles/raspicam_cv.dir/raspicam_cv.cpp.o.requires +src/CMakeFiles/raspicam_cv.dir/requires: src/CMakeFiles/raspicam_cv.dir/raspicam_still_cv.cpp.o.requires +.PHONY : src/CMakeFiles/raspicam_cv.dir/requires + +src/CMakeFiles/raspicam_cv.dir/clean: + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/src && $(CMAKE_COMMAND) -P CMakeFiles/raspicam_cv.dir/cmake_clean.cmake +.PHONY : src/CMakeFiles/raspicam_cv.dir/clean + +src/CMakeFiles/raspicam_cv.dir/depend: + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/ubuntu/Nomad/external_src/raspicam-0.1.3 /home/ubuntu/Nomad/external_src/raspicam-0.1.3/src /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/src /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/src/CMakeFiles/raspicam_cv.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : src/CMakeFiles/raspicam_cv.dir/depend + diff --git a/external_src/raspicam-0.1.3/build/src/CMakeFiles/raspicam_cv.dir/cmake_clean.cmake b/external_src/raspicam-0.1.3/build/src/CMakeFiles/raspicam_cv.dir/cmake_clean.cmake new file mode 100644 index 0000000..b485852 --- /dev/null +++ b/external_src/raspicam-0.1.3/build/src/CMakeFiles/raspicam_cv.dir/cmake_clean.cmake @@ -0,0 +1,11 @@ +FILE(REMOVE_RECURSE + "CMakeFiles/raspicam_cv.dir/raspicam_cv.cpp.o" + "CMakeFiles/raspicam_cv.dir/raspicam_still_cv.cpp.o" + "libraspicam_cv.pdb" + "libraspicam_cv.so" +) + +# Per-language clean rules from dependency scanning. +FOREACH(lang CXX) + INCLUDE(CMakeFiles/raspicam_cv.dir/cmake_clean_${lang}.cmake OPTIONAL) +ENDFOREACH(lang) diff --git a/external_src/raspicam-0.1.3/build/src/CMakeFiles/raspicam_cv.dir/depend.make b/external_src/raspicam-0.1.3/build/src/CMakeFiles/raspicam_cv.dir/depend.make new file mode 100644 index 0000000..3e54adb --- /dev/null +++ b/external_src/raspicam-0.1.3/build/src/CMakeFiles/raspicam_cv.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for raspicam_cv. +# This may be replaced when dependencies are built. diff --git a/external_src/raspicam-0.1.3/build/src/CMakeFiles/raspicam_cv.dir/flags.make b/external_src/raspicam-0.1.3/build/src/CMakeFiles/raspicam_cv.dir/flags.make new file mode 100644 index 0000000..62522a7 --- /dev/null +++ b/external_src/raspicam-0.1.3/build/src/CMakeFiles/raspicam_cv.dir/flags.make @@ -0,0 +1,8 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +# compile CXX with /usr/bin/c++ +CXX_FLAGS = -std=c++0x -Wl,--no-as-needed -Wall -ffunction-sections -fomit-frame-pointer -O2 -ffast-math -DNDEBUG -lpthread -fPIC -I/home/ubuntu/Nomad/external_src/raspicam-0.1.3/dependencies -I/home/ubuntu/Nomad/external_src/raspicam-0.1.3/dependencies/mmal -I/home/ubuntu/Nomad/external_src/raspicam-0.1.3/dependencies/vcos -I/usr/local/include/opencv -I/usr/local/include -I/home/ubuntu/Nomad/external_src/raspicam-0.1.3/src/. -I/home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/src + +CXX_DEFINES = -Draspicam_cv_EXPORTS + diff --git a/external_src/raspicam-0.1.3/build/src/CMakeFiles/raspicam_cv.dir/link.txt b/external_src/raspicam-0.1.3/build/src/CMakeFiles/raspicam_cv.dir/link.txt new file mode 100644 index 0000000..966b7a8 --- /dev/null +++ b/external_src/raspicam-0.1.3/build/src/CMakeFiles/raspicam_cv.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fPIC -std=c++0x -Wl,--no-as-needed -Wall -ffunction-sections -fomit-frame-pointer -O2 -ffast-math -DNDEBUG -lpthread -shared -Wl,-soname,libraspicam_cv.so -o libraspicam_cv.so CMakeFiles/raspicam_cv.dir/raspicam_cv.cpp.o CMakeFiles/raspicam_cv.dir/raspicam_still_cv.cpp.o /opt/vc/lib/libmmal_core.so /opt/vc/lib/libmmal_util.so /opt/vc/lib/libmmal.so /usr/local/lib/libopencv_videostab.so.3.0.0 /usr/local/lib/libopencv_videoio.so.3.0.0 /usr/local/lib/libopencv_video.so.3.0.0 /usr/local/lib/libopencv_superres.so.3.0.0 /usr/local/lib/libopencv_stitching.so.3.0.0 /usr/local/lib/libopencv_shape.so.3.0.0 /usr/local/lib/libopencv_photo.so.3.0.0 /usr/local/lib/libopencv_objdetect.so.3.0.0 /usr/local/lib/libopencv_ml.so.3.0.0 /usr/local/lib/libopencv_imgproc.so.3.0.0 /usr/local/lib/libopencv_imgcodecs.so.3.0.0 /usr/local/lib/libopencv_highgui.so.3.0.0 /usr/local/lib/libopencv_hal.a /usr/local/lib/libopencv_flann.so.3.0.0 /usr/local/lib/libopencv_features2d.so.3.0.0 /usr/local/lib/libopencv_core.so.3.0.0 /usr/local/lib/libopencv_calib3d.so.3.0.0 /usr/local/lib/libopencv_features2d.so.3.0.0 /usr/local/lib/libopencv_ml.so.3.0.0 /usr/local/lib/libopencv_highgui.so.3.0.0 /usr/local/lib/libopencv_videoio.so.3.0.0 /usr/local/lib/libopencv_imgcodecs.so.3.0.0 /usr/local/lib/libopencv_flann.so.3.0.0 /usr/local/lib/libopencv_video.so.3.0.0 /usr/local/lib/libopencv_imgproc.so.3.0.0 /usr/local/lib/libopencv_core.so.3.0.0 /usr/local/lib/libopencv_hal.a -ldl -lm -lpthread -lrt -Wl,-rpath,/opt/vc/lib:/usr/local/lib: diff --git a/external_src/raspicam-0.1.3/build/src/CMakeFiles/raspicam_cv.dir/progress.make b/external_src/raspicam-0.1.3/build/src/CMakeFiles/raspicam_cv.dir/progress.make new file mode 100644 index 0000000..8808896 --- /dev/null +++ b/external_src/raspicam-0.1.3/build/src/CMakeFiles/raspicam_cv.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = 6 +CMAKE_PROGRESS_2 = 7 + diff --git a/external_src/raspicam-0.1.3/build/src/Makefile b/external_src/raspicam-0.1.3/build/src/Makefile new file mode 100644 index 0000000..26c30cd --- /dev/null +++ b/external_src/raspicam-0.1.3/build/src/Makefile @@ -0,0 +1,386 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +# Default target executed when no arguments are given to make. +default_target: all +.PHONY : default_target + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/ubuntu/Nomad/external_src/raspicam-0.1.3 + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build + +#============================================================================= +# Targets provided globally by CMake. + +# Special rule for the target edit_cache +edit_cache: + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running interactive CMake command-line interface..." + /usr/bin/cmake -i . +.PHONY : edit_cache + +# Special rule for the target edit_cache +edit_cache/fast: edit_cache +.PHONY : edit_cache/fast + +# Special rule for the target install +install: preinstall + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Install the project..." + /usr/bin/cmake -P cmake_install.cmake +.PHONY : install + +# Special rule for the target install +install/fast: preinstall/fast + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Install the project..." + /usr/bin/cmake -P cmake_install.cmake +.PHONY : install/fast + +# Special rule for the target install/local +install/local: preinstall + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Installing only the local directory..." + /usr/bin/cmake -DCMAKE_INSTALL_LOCAL_ONLY=1 -P cmake_install.cmake +.PHONY : install/local + +# Special rule for the target install/local +install/local/fast: install/local +.PHONY : install/local/fast + +# Special rule for the target install/strip +install/strip: preinstall + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Installing the project stripped..." + /usr/bin/cmake -DCMAKE_INSTALL_DO_STRIP=1 -P cmake_install.cmake +.PHONY : install/strip + +# Special rule for the target install/strip +install/strip/fast: install/strip +.PHONY : install/strip/fast + +# Special rule for the target list_install_components +list_install_components: + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Available install components are: \"Unspecified\" \"main\"" +.PHONY : list_install_components + +# Special rule for the target list_install_components +list_install_components/fast: list_install_components +.PHONY : list_install_components/fast + +# Special rule for the target rebuild_cache +rebuild_cache: + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running CMake to regenerate build system..." + /usr/bin/cmake -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) +.PHONY : rebuild_cache + +# Special rule for the target rebuild_cache +rebuild_cache/fast: rebuild_cache +.PHONY : rebuild_cache/fast + +# The main all target +all: cmake_check_build_system + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build && $(CMAKE_COMMAND) -E cmake_progress_start /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/CMakeFiles /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/src/CMakeFiles/progress.marks + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build && $(MAKE) -f CMakeFiles/Makefile2 src/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/CMakeFiles 0 +.PHONY : all + +# The main clean target +clean: + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build && $(MAKE) -f CMakeFiles/Makefile2 src/clean +.PHONY : clean + +# The main clean target +clean/fast: clean +.PHONY : clean/fast + +# Prepare targets for installation. +preinstall: all + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build && $(MAKE) -f CMakeFiles/Makefile2 src/preinstall +.PHONY : preinstall + +# Prepare targets for installation. +preinstall/fast: + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build && $(MAKE) -f CMakeFiles/Makefile2 src/preinstall +.PHONY : preinstall/fast + +# clear depends +depend: + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build && $(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 1 +.PHONY : depend + +# Convenience name for target. +src/CMakeFiles/raspicam.dir/rule: + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build && $(MAKE) -f CMakeFiles/Makefile2 src/CMakeFiles/raspicam.dir/rule +.PHONY : src/CMakeFiles/raspicam.dir/rule + +# Convenience name for target. +raspicam: src/CMakeFiles/raspicam.dir/rule +.PHONY : raspicam + +# fast build rule for target. +raspicam/fast: + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build && $(MAKE) -f src/CMakeFiles/raspicam.dir/build.make src/CMakeFiles/raspicam.dir/build +.PHONY : raspicam/fast + +# Convenience name for target. +src/CMakeFiles/raspicam_cv.dir/rule: + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build && $(MAKE) -f CMakeFiles/Makefile2 src/CMakeFiles/raspicam_cv.dir/rule +.PHONY : src/CMakeFiles/raspicam_cv.dir/rule + +# Convenience name for target. +raspicam_cv: src/CMakeFiles/raspicam_cv.dir/rule +.PHONY : raspicam_cv + +# fast build rule for target. +raspicam_cv/fast: + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build && $(MAKE) -f src/CMakeFiles/raspicam_cv.dir/build.make src/CMakeFiles/raspicam_cv.dir/build +.PHONY : raspicam_cv/fast + +private/private_impl.o: private/private_impl.cpp.o +.PHONY : private/private_impl.o + +# target to build an object file +private/private_impl.cpp.o: + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build && $(MAKE) -f src/CMakeFiles/raspicam.dir/build.make src/CMakeFiles/raspicam.dir/private/private_impl.cpp.o +.PHONY : private/private_impl.cpp.o + +private/private_impl.i: private/private_impl.cpp.i +.PHONY : private/private_impl.i + +# target to preprocess a source file +private/private_impl.cpp.i: + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build && $(MAKE) -f src/CMakeFiles/raspicam.dir/build.make src/CMakeFiles/raspicam.dir/private/private_impl.cpp.i +.PHONY : private/private_impl.cpp.i + +private/private_impl.s: private/private_impl.cpp.s +.PHONY : private/private_impl.s + +# target to generate assembly for a file +private/private_impl.cpp.s: + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build && $(MAKE) -f src/CMakeFiles/raspicam.dir/build.make src/CMakeFiles/raspicam.dir/private/private_impl.cpp.s +.PHONY : private/private_impl.cpp.s + +private/threadcondition.o: private/threadcondition.cpp.o +.PHONY : private/threadcondition.o + +# target to build an object file +private/threadcondition.cpp.o: + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build && $(MAKE) -f src/CMakeFiles/raspicam.dir/build.make src/CMakeFiles/raspicam.dir/private/threadcondition.cpp.o +.PHONY : private/threadcondition.cpp.o + +private/threadcondition.i: private/threadcondition.cpp.i +.PHONY : private/threadcondition.i + +# target to preprocess a source file +private/threadcondition.cpp.i: + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build && $(MAKE) -f src/CMakeFiles/raspicam.dir/build.make src/CMakeFiles/raspicam.dir/private/threadcondition.cpp.i +.PHONY : private/threadcondition.cpp.i + +private/threadcondition.s: private/threadcondition.cpp.s +.PHONY : private/threadcondition.s + +# target to generate assembly for a file +private/threadcondition.cpp.s: + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build && $(MAKE) -f src/CMakeFiles/raspicam.dir/build.make src/CMakeFiles/raspicam.dir/private/threadcondition.cpp.s +.PHONY : private/threadcondition.cpp.s + +private_still/private_still_impl.o: private_still/private_still_impl.cpp.o +.PHONY : private_still/private_still_impl.o + +# target to build an object file +private_still/private_still_impl.cpp.o: + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build && $(MAKE) -f src/CMakeFiles/raspicam.dir/build.make src/CMakeFiles/raspicam.dir/private_still/private_still_impl.cpp.o +.PHONY : private_still/private_still_impl.cpp.o + +private_still/private_still_impl.i: private_still/private_still_impl.cpp.i +.PHONY : private_still/private_still_impl.i + +# target to preprocess a source file +private_still/private_still_impl.cpp.i: + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build && $(MAKE) -f src/CMakeFiles/raspicam.dir/build.make src/CMakeFiles/raspicam.dir/private_still/private_still_impl.cpp.i +.PHONY : private_still/private_still_impl.cpp.i + +private_still/private_still_impl.s: private_still/private_still_impl.cpp.s +.PHONY : private_still/private_still_impl.s + +# target to generate assembly for a file +private_still/private_still_impl.cpp.s: + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build && $(MAKE) -f src/CMakeFiles/raspicam.dir/build.make src/CMakeFiles/raspicam.dir/private_still/private_still_impl.cpp.s +.PHONY : private_still/private_still_impl.cpp.s + +raspicam.o: raspicam.cpp.o +.PHONY : raspicam.o + +# target to build an object file +raspicam.cpp.o: + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build && $(MAKE) -f src/CMakeFiles/raspicam.dir/build.make src/CMakeFiles/raspicam.dir/raspicam.cpp.o +.PHONY : raspicam.cpp.o + +raspicam.i: raspicam.cpp.i +.PHONY : raspicam.i + +# target to preprocess a source file +raspicam.cpp.i: + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build && $(MAKE) -f src/CMakeFiles/raspicam.dir/build.make src/CMakeFiles/raspicam.dir/raspicam.cpp.i +.PHONY : raspicam.cpp.i + +raspicam.s: raspicam.cpp.s +.PHONY : raspicam.s + +# target to generate assembly for a file +raspicam.cpp.s: + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build && $(MAKE) -f src/CMakeFiles/raspicam.dir/build.make src/CMakeFiles/raspicam.dir/raspicam.cpp.s +.PHONY : raspicam.cpp.s + +raspicam_cv.o: raspicam_cv.cpp.o +.PHONY : raspicam_cv.o + +# target to build an object file +raspicam_cv.cpp.o: + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build && $(MAKE) -f src/CMakeFiles/raspicam_cv.dir/build.make src/CMakeFiles/raspicam_cv.dir/raspicam_cv.cpp.o +.PHONY : raspicam_cv.cpp.o + +raspicam_cv.i: raspicam_cv.cpp.i +.PHONY : raspicam_cv.i + +# target to preprocess a source file +raspicam_cv.cpp.i: + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build && $(MAKE) -f src/CMakeFiles/raspicam_cv.dir/build.make src/CMakeFiles/raspicam_cv.dir/raspicam_cv.cpp.i +.PHONY : raspicam_cv.cpp.i + +raspicam_cv.s: raspicam_cv.cpp.s +.PHONY : raspicam_cv.s + +# target to generate assembly for a file +raspicam_cv.cpp.s: + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build && $(MAKE) -f src/CMakeFiles/raspicam_cv.dir/build.make src/CMakeFiles/raspicam_cv.dir/raspicam_cv.cpp.s +.PHONY : raspicam_cv.cpp.s + +raspicam_still.o: raspicam_still.cpp.o +.PHONY : raspicam_still.o + +# target to build an object file +raspicam_still.cpp.o: + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build && $(MAKE) -f src/CMakeFiles/raspicam.dir/build.make src/CMakeFiles/raspicam.dir/raspicam_still.cpp.o +.PHONY : raspicam_still.cpp.o + +raspicam_still.i: raspicam_still.cpp.i +.PHONY : raspicam_still.i + +# target to preprocess a source file +raspicam_still.cpp.i: + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build && $(MAKE) -f src/CMakeFiles/raspicam.dir/build.make src/CMakeFiles/raspicam.dir/raspicam_still.cpp.i +.PHONY : raspicam_still.cpp.i + +raspicam_still.s: raspicam_still.cpp.s +.PHONY : raspicam_still.s + +# target to generate assembly for a file +raspicam_still.cpp.s: + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build && $(MAKE) -f src/CMakeFiles/raspicam.dir/build.make src/CMakeFiles/raspicam.dir/raspicam_still.cpp.s +.PHONY : raspicam_still.cpp.s + +raspicam_still_cv.o: raspicam_still_cv.cpp.o +.PHONY : raspicam_still_cv.o + +# target to build an object file +raspicam_still_cv.cpp.o: + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build && $(MAKE) -f src/CMakeFiles/raspicam_cv.dir/build.make src/CMakeFiles/raspicam_cv.dir/raspicam_still_cv.cpp.o +.PHONY : raspicam_still_cv.cpp.o + +raspicam_still_cv.i: raspicam_still_cv.cpp.i +.PHONY : raspicam_still_cv.i + +# target to preprocess a source file +raspicam_still_cv.cpp.i: + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build && $(MAKE) -f src/CMakeFiles/raspicam_cv.dir/build.make src/CMakeFiles/raspicam_cv.dir/raspicam_still_cv.cpp.i +.PHONY : raspicam_still_cv.cpp.i + +raspicam_still_cv.s: raspicam_still_cv.cpp.s +.PHONY : raspicam_still_cv.s + +# target to generate assembly for a file +raspicam_still_cv.cpp.s: + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build && $(MAKE) -f src/CMakeFiles/raspicam_cv.dir/build.make src/CMakeFiles/raspicam_cv.dir/raspicam_still_cv.cpp.s +.PHONY : raspicam_still_cv.cpp.s + +# Help Target +help: + @echo "The following are some of the valid targets for this Makefile:" + @echo "... all (the default if no target is provided)" + @echo "... clean" + @echo "... depend" + @echo "... edit_cache" + @echo "... install" + @echo "... install/local" + @echo "... install/strip" + @echo "... list_install_components" + @echo "... raspicam" + @echo "... raspicam_cv" + @echo "... rebuild_cache" + @echo "... private/private_impl.o" + @echo "... private/private_impl.i" + @echo "... private/private_impl.s" + @echo "... private/threadcondition.o" + @echo "... private/threadcondition.i" + @echo "... private/threadcondition.s" + @echo "... private_still/private_still_impl.o" + @echo "... private_still/private_still_impl.i" + @echo "... private_still/private_still_impl.s" + @echo "... raspicam.o" + @echo "... raspicam.i" + @echo "... raspicam.s" + @echo "... raspicam_cv.o" + @echo "... raspicam_cv.i" + @echo "... raspicam_cv.s" + @echo "... raspicam_still.o" + @echo "... raspicam_still.i" + @echo "... raspicam_still.s" + @echo "... raspicam_still_cv.o" + @echo "... raspicam_still_cv.i" + @echo "... raspicam_still_cv.s" +.PHONY : help + + + +#============================================================================= +# Special targets to cleanup operation of make. + +# Special rule to run CMake to check the build system integrity. +# No rule that depends on this can have commands that come from listfiles +# because they might be regenerated. +cmake_check_build_system: + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build && $(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 0 +.PHONY : cmake_check_build_system + diff --git a/external_src/raspicam-0.1.3/build/src/cmake_install.cmake b/external_src/raspicam-0.1.3/build/src/cmake_install.cmake new file mode 100644 index 0000000..9be51a1 --- /dev/null +++ b/external_src/raspicam-0.1.3/build/src/cmake_install.cmake @@ -0,0 +1,95 @@ +# Install script for directory: /home/ubuntu/Nomad/external_src/raspicam-0.1.3/src + +# Set the install prefix +IF(NOT DEFINED CMAKE_INSTALL_PREFIX) + SET(CMAKE_INSTALL_PREFIX "/usr/local") +ENDIF(NOT DEFINED CMAKE_INSTALL_PREFIX) +STRING(REGEX REPLACE "/$" "" CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}") + +# Set the install configuration name. +IF(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME) + IF(BUILD_TYPE) + STRING(REGEX REPLACE "^[^A-Za-z0-9_]+" "" + CMAKE_INSTALL_CONFIG_NAME "${BUILD_TYPE}") + ELSE(BUILD_TYPE) + SET(CMAKE_INSTALL_CONFIG_NAME "Release") + ENDIF(BUILD_TYPE) + MESSAGE(STATUS "Install configuration: \"${CMAKE_INSTALL_CONFIG_NAME}\"") +ENDIF(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME) + +# Set the component getting installed. +IF(NOT CMAKE_INSTALL_COMPONENT) + IF(COMPONENT) + MESSAGE(STATUS "Install component: \"${COMPONENT}\"") + SET(CMAKE_INSTALL_COMPONENT "${COMPONENT}") + ELSE(COMPONENT) + SET(CMAKE_INSTALL_COMPONENT) + ENDIF(COMPONENT) +ENDIF(NOT CMAKE_INSTALL_COMPONENT) + +# Install shared libraries without execute permission? +IF(NOT DEFINED CMAKE_INSTALL_SO_NO_EXE) + SET(CMAKE_INSTALL_SO_NO_EXE "1") +ENDIF(NOT DEFINED CMAKE_INSTALL_SO_NO_EXE) + +IF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "main") + FOREACH(file + "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/lib/libraspicam.so.0.1.2" + "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/lib/libraspicam.so.0.1" + "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/lib/libraspicam.so" + ) + IF(EXISTS "${file}" AND + NOT IS_SYMLINK "${file}") + FILE(RPATH_CHECK + FILE "${file}" + RPATH "") + ENDIF() + ENDFOREACH() + FILE(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/lib" TYPE SHARED_LIBRARY PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE FILES + "/home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/src/libraspicam.so.0.1.2" + "/home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/src/libraspicam.so.0.1" + "/home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/src/libraspicam.so" + ) + FOREACH(file + "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/lib/libraspicam.so.0.1.2" + "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/lib/libraspicam.so.0.1" + "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/lib/libraspicam.so" + ) + IF(EXISTS "${file}" AND + NOT IS_SYMLINK "${file}") + FILE(RPATH_REMOVE + FILE "${file}") + IF(CMAKE_INSTALL_DO_STRIP) + EXECUTE_PROCESS(COMMAND "/usr/bin/strip" "${file}") + ENDIF(CMAKE_INSTALL_DO_STRIP) + ENDIF() + ENDFOREACH() +ENDIF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "main") + +IF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "main") + IF(EXISTS "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/lib/libraspicam_cv.so" AND + NOT IS_SYMLINK "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/lib/libraspicam_cv.so") + FILE(RPATH_CHECK + FILE "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/lib/libraspicam_cv.so" + RPATH "") + ENDIF() + FILE(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/lib" TYPE SHARED_LIBRARY PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE FILES "/home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/src/libraspicam_cv.so") + IF(EXISTS "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/lib/libraspicam_cv.so" AND + NOT IS_SYMLINK "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/lib/libraspicam_cv.so") + FILE(RPATH_REMOVE + FILE "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/lib/libraspicam_cv.so") + IF(CMAKE_INSTALL_DO_STRIP) + EXECUTE_PROCESS(COMMAND "/usr/bin/strip" "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/lib/libraspicam_cv.so") + ENDIF(CMAKE_INSTALL_DO_STRIP) + ENDIF() +ENDIF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "main") + +IF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "main") + FILE(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/include/raspicam" TYPE FILE FILES + "/home/ubuntu/Nomad/external_src/raspicam-0.1.3/src/raspicamtypes.h" + "/home/ubuntu/Nomad/external_src/raspicam-0.1.3/src/raspicam.h" + "/home/ubuntu/Nomad/external_src/raspicam-0.1.3/src/raspicam_cv.h" + "/home/ubuntu/Nomad/external_src/raspicam-0.1.3/src/raspicam_still_cv.h" + ) +ENDIF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "main") + diff --git a/external_src/raspicam-0.1.3/build/utils/CMakeFiles/CMakeDirectoryInformation.cmake b/external_src/raspicam-0.1.3/build/utils/CMakeFiles/CMakeDirectoryInformation.cmake new file mode 100644 index 0000000..24120d7 --- /dev/null +++ b/external_src/raspicam-0.1.3/build/utils/CMakeFiles/CMakeDirectoryInformation.cmake @@ -0,0 +1,16 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +# Relative path conversion top directories. +SET(CMAKE_RELATIVE_PATH_TOP_SOURCE "/home/ubuntu/Nomad/external_src/raspicam-0.1.3") +SET(CMAKE_RELATIVE_PATH_TOP_BINARY "/home/ubuntu/Nomad/external_src/raspicam-0.1.3/build") + +# Force unix paths in dependencies. +SET(CMAKE_FORCE_UNIX_PATHS 1) + + +# The C and CXX include file regular expressions for this directory. +SET(CMAKE_C_INCLUDE_REGEX_SCAN "^.*$") +SET(CMAKE_C_INCLUDE_REGEX_COMPLAIN "^$") +SET(CMAKE_CXX_INCLUDE_REGEX_SCAN ${CMAKE_C_INCLUDE_REGEX_SCAN}) +SET(CMAKE_CXX_INCLUDE_REGEX_COMPLAIN ${CMAKE_C_INCLUDE_REGEX_COMPLAIN}) diff --git a/external_src/raspicam-0.1.3/build/utils/CMakeFiles/progress.marks b/external_src/raspicam-0.1.3/build/utils/CMakeFiles/progress.marks new file mode 100644 index 0000000..b4de394 --- /dev/null +++ b/external_src/raspicam-0.1.3/build/utils/CMakeFiles/progress.marks @@ -0,0 +1 @@ +11 diff --git a/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_cv_still_test.dir/DependInfo.cmake b/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_cv_still_test.dir/DependInfo.cmake new file mode 100644 index 0000000..d6e3d31 --- /dev/null +++ b/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_cv_still_test.dir/DependInfo.cmake @@ -0,0 +1,28 @@ +# The set of languages for which implicit dependencies are needed: +SET(CMAKE_DEPENDS_LANGUAGES + "CXX" + ) +# The set of files for implicit dependencies of each language: +SET(CMAKE_DEPENDS_CHECK_CXX + "/home/ubuntu/Nomad/external_src/raspicam-0.1.3/utils/raspicam_cv_still_test.cpp" "/home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_cv_still_test.dir/raspicam_cv_still_test.cpp.o" + ) +SET(CMAKE_CXX_COMPILER_ID "GNU") + +# Targets to which this target links. +SET(CMAKE_TARGET_LINKED_INFO_FILES + "/home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/src/CMakeFiles/raspicam.dir/DependInfo.cmake" + "/home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/src/CMakeFiles/raspicam_cv.dir/DependInfo.cmake" + ) + +# The include file search paths: +SET(CMAKE_C_TARGET_INCLUDE_PATH + "../dependencies" + "../dependencies/mmal" + "../dependencies/vcos" + "/usr/local/include/opencv" + "/usr/local/include" + "../src" + ) +SET(CMAKE_CXX_TARGET_INCLUDE_PATH ${CMAKE_C_TARGET_INCLUDE_PATH}) +SET(CMAKE_Fortran_TARGET_INCLUDE_PATH ${CMAKE_C_TARGET_INCLUDE_PATH}) +SET(CMAKE_ASM_TARGET_INCLUDE_PATH ${CMAKE_C_TARGET_INCLUDE_PATH}) diff --git a/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_cv_still_test.dir/build.make b/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_cv_still_test.dir/build.make new file mode 100644 index 0000000..6322cd7 --- /dev/null +++ b/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_cv_still_test.dir/build.make @@ -0,0 +1,124 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/ubuntu/Nomad/external_src/raspicam-0.1.3 + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build + +# Include any dependencies generated for this target. +include utils/CMakeFiles/raspicam_cv_still_test.dir/depend.make + +# Include the progress variables for this target. +include utils/CMakeFiles/raspicam_cv_still_test.dir/progress.make + +# Include the compile flags for this target's objects. +include utils/CMakeFiles/raspicam_cv_still_test.dir/flags.make + +utils/CMakeFiles/raspicam_cv_still_test.dir/raspicam_cv_still_test.cpp.o: utils/CMakeFiles/raspicam_cv_still_test.dir/flags.make +utils/CMakeFiles/raspicam_cv_still_test.dir/raspicam_cv_still_test.cpp.o: ../utils/raspicam_cv_still_test.cpp + $(CMAKE_COMMAND) -E cmake_progress_report /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/CMakeFiles $(CMAKE_PROGRESS_1) + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Building CXX object utils/CMakeFiles/raspicam_cv_still_test.dir/raspicam_cv_still_test.cpp.o" + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/utils && /usr/bin/c++ $(CXX_DEFINES) $(CXX_FLAGS) -o CMakeFiles/raspicam_cv_still_test.dir/raspicam_cv_still_test.cpp.o -c /home/ubuntu/Nomad/external_src/raspicam-0.1.3/utils/raspicam_cv_still_test.cpp + +utils/CMakeFiles/raspicam_cv_still_test.dir/raspicam_cv_still_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing CXX source to CMakeFiles/raspicam_cv_still_test.dir/raspicam_cv_still_test.cpp.i" + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/utils && /usr/bin/c++ $(CXX_DEFINES) $(CXX_FLAGS) -E /home/ubuntu/Nomad/external_src/raspicam-0.1.3/utils/raspicam_cv_still_test.cpp > CMakeFiles/raspicam_cv_still_test.dir/raspicam_cv_still_test.cpp.i + +utils/CMakeFiles/raspicam_cv_still_test.dir/raspicam_cv_still_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling CXX source to assembly CMakeFiles/raspicam_cv_still_test.dir/raspicam_cv_still_test.cpp.s" + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/utils && /usr/bin/c++ $(CXX_DEFINES) $(CXX_FLAGS) -S /home/ubuntu/Nomad/external_src/raspicam-0.1.3/utils/raspicam_cv_still_test.cpp -o CMakeFiles/raspicam_cv_still_test.dir/raspicam_cv_still_test.cpp.s + +utils/CMakeFiles/raspicam_cv_still_test.dir/raspicam_cv_still_test.cpp.o.requires: +.PHONY : utils/CMakeFiles/raspicam_cv_still_test.dir/raspicam_cv_still_test.cpp.o.requires + +utils/CMakeFiles/raspicam_cv_still_test.dir/raspicam_cv_still_test.cpp.o.provides: utils/CMakeFiles/raspicam_cv_still_test.dir/raspicam_cv_still_test.cpp.o.requires + $(MAKE) -f utils/CMakeFiles/raspicam_cv_still_test.dir/build.make utils/CMakeFiles/raspicam_cv_still_test.dir/raspicam_cv_still_test.cpp.o.provides.build +.PHONY : utils/CMakeFiles/raspicam_cv_still_test.dir/raspicam_cv_still_test.cpp.o.provides + +utils/CMakeFiles/raspicam_cv_still_test.dir/raspicam_cv_still_test.cpp.o.provides.build: utils/CMakeFiles/raspicam_cv_still_test.dir/raspicam_cv_still_test.cpp.o + +# Object files for target raspicam_cv_still_test +raspicam_cv_still_test_OBJECTS = \ +"CMakeFiles/raspicam_cv_still_test.dir/raspicam_cv_still_test.cpp.o" + +# External object files for target raspicam_cv_still_test +raspicam_cv_still_test_EXTERNAL_OBJECTS = + +utils/raspicam_cv_still_test: utils/CMakeFiles/raspicam_cv_still_test.dir/raspicam_cv_still_test.cpp.o +utils/raspicam_cv_still_test: utils/CMakeFiles/raspicam_cv_still_test.dir/build.make +utils/raspicam_cv_still_test: src/libraspicam.so.0.1.2 +utils/raspicam_cv_still_test: src/libraspicam_cv.so +utils/raspicam_cv_still_test: /opt/vc/lib/libmmal_core.so +utils/raspicam_cv_still_test: /opt/vc/lib/libmmal_util.so +utils/raspicam_cv_still_test: /opt/vc/lib/libmmal.so +utils/raspicam_cv_still_test: /usr/local/lib/libopencv_videostab.so.3.0.0 +utils/raspicam_cv_still_test: /usr/local/lib/libopencv_superres.so.3.0.0 +utils/raspicam_cv_still_test: /usr/local/lib/libopencv_stitching.so.3.0.0 +utils/raspicam_cv_still_test: /usr/local/lib/libopencv_shape.so.3.0.0 +utils/raspicam_cv_still_test: /usr/local/lib/libopencv_video.so.3.0.0 +utils/raspicam_cv_still_test: /usr/local/lib/libopencv_photo.so.3.0.0 +utils/raspicam_cv_still_test: /usr/local/lib/libopencv_objdetect.so.3.0.0 +utils/raspicam_cv_still_test: /usr/local/lib/libopencv_calib3d.so.3.0.0 +utils/raspicam_cv_still_test: /usr/local/lib/libopencv_features2d.so.3.0.0 +utils/raspicam_cv_still_test: /usr/local/lib/libopencv_ml.so.3.0.0 +utils/raspicam_cv_still_test: /usr/local/lib/libopencv_highgui.so.3.0.0 +utils/raspicam_cv_still_test: /usr/local/lib/libopencv_videoio.so.3.0.0 +utils/raspicam_cv_still_test: /usr/local/lib/libopencv_imgcodecs.so.3.0.0 +utils/raspicam_cv_still_test: /usr/local/lib/libopencv_imgproc.so.3.0.0 +utils/raspicam_cv_still_test: /usr/local/lib/libopencv_flann.so.3.0.0 +utils/raspicam_cv_still_test: /usr/local/lib/libopencv_core.so.3.0.0 +utils/raspicam_cv_still_test: /usr/local/lib/libopencv_hal.a +utils/raspicam_cv_still_test: utils/CMakeFiles/raspicam_cv_still_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --red --bold "Linking CXX executable raspicam_cv_still_test" + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/utils && $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/raspicam_cv_still_test.dir/link.txt --verbose=$(VERBOSE) + +# Rule to build all files generated by this target. +utils/CMakeFiles/raspicam_cv_still_test.dir/build: utils/raspicam_cv_still_test +.PHONY : utils/CMakeFiles/raspicam_cv_still_test.dir/build + +utils/CMakeFiles/raspicam_cv_still_test.dir/requires: utils/CMakeFiles/raspicam_cv_still_test.dir/raspicam_cv_still_test.cpp.o.requires +.PHONY : utils/CMakeFiles/raspicam_cv_still_test.dir/requires + +utils/CMakeFiles/raspicam_cv_still_test.dir/clean: + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/utils && $(CMAKE_COMMAND) -P CMakeFiles/raspicam_cv_still_test.dir/cmake_clean.cmake +.PHONY : utils/CMakeFiles/raspicam_cv_still_test.dir/clean + +utils/CMakeFiles/raspicam_cv_still_test.dir/depend: + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/ubuntu/Nomad/external_src/raspicam-0.1.3 /home/ubuntu/Nomad/external_src/raspicam-0.1.3/utils /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/utils /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_cv_still_test.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : utils/CMakeFiles/raspicam_cv_still_test.dir/depend + diff --git a/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_cv_still_test.dir/cmake_clean.cmake b/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_cv_still_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..816a88f --- /dev/null +++ b/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_cv_still_test.dir/cmake_clean.cmake @@ -0,0 +1,10 @@ +FILE(REMOVE_RECURSE + "CMakeFiles/raspicam_cv_still_test.dir/raspicam_cv_still_test.cpp.o" + "raspicam_cv_still_test.pdb" + "raspicam_cv_still_test" +) + +# Per-language clean rules from dependency scanning. +FOREACH(lang CXX) + INCLUDE(CMakeFiles/raspicam_cv_still_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +ENDFOREACH(lang) diff --git a/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_cv_still_test.dir/depend.make b/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_cv_still_test.dir/depend.make new file mode 100644 index 0000000..501f120 --- /dev/null +++ b/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_cv_still_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for raspicam_cv_still_test. +# This may be replaced when dependencies are built. diff --git a/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_cv_still_test.dir/flags.make b/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_cv_still_test.dir/flags.make new file mode 100644 index 0000000..1b59b72 --- /dev/null +++ b/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_cv_still_test.dir/flags.make @@ -0,0 +1,8 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +# compile CXX with /usr/bin/c++ +CXX_FLAGS = -std=c++0x -Wl,--no-as-needed -Wall -ffunction-sections -fomit-frame-pointer -O2 -ffast-math -DNDEBUG -lpthread -I/home/ubuntu/Nomad/external_src/raspicam-0.1.3/dependencies -I/home/ubuntu/Nomad/external_src/raspicam-0.1.3/dependencies/mmal -I/home/ubuntu/Nomad/external_src/raspicam-0.1.3/dependencies/vcos -I/usr/local/include/opencv -I/usr/local/include -I/home/ubuntu/Nomad/external_src/raspicam-0.1.3/src + +CXX_DEFINES = + diff --git a/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_cv_still_test.dir/link.txt b/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_cv_still_test.dir/link.txt new file mode 100644 index 0000000..12b3f94 --- /dev/null +++ b/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_cv_still_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -std=c++0x -Wl,--no-as-needed -Wall -ffunction-sections -fomit-frame-pointer -O2 -ffast-math -DNDEBUG -lpthread CMakeFiles/raspicam_cv_still_test.dir/raspicam_cv_still_test.cpp.o -o raspicam_cv_still_test -rdynamic ../src/libraspicam.so.0.1.2 ../src/libraspicam_cv.so /opt/vc/lib/libmmal_core.so /opt/vc/lib/libmmal_util.so /opt/vc/lib/libmmal.so /usr/local/lib/libopencv_videostab.so.3.0.0 /usr/local/lib/libopencv_superres.so.3.0.0 /usr/local/lib/libopencv_stitching.so.3.0.0 /usr/local/lib/libopencv_shape.so.3.0.0 /usr/local/lib/libopencv_video.so.3.0.0 /usr/local/lib/libopencv_photo.so.3.0.0 /usr/local/lib/libopencv_objdetect.so.3.0.0 /usr/local/lib/libopencv_calib3d.so.3.0.0 /usr/local/lib/libopencv_features2d.so.3.0.0 /usr/local/lib/libopencv_ml.so.3.0.0 /usr/local/lib/libopencv_highgui.so.3.0.0 /usr/local/lib/libopencv_videoio.so.3.0.0 /usr/local/lib/libopencv_imgcodecs.so.3.0.0 /usr/local/lib/libopencv_imgproc.so.3.0.0 /usr/local/lib/libopencv_flann.so.3.0.0 /usr/local/lib/libopencv_core.so.3.0.0 /usr/local/lib/libopencv_hal.a -ldl -lm -lpthread -lrt -Wl,-rpath,/home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/src:/opt/vc/lib:/usr/local/lib: diff --git a/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_cv_still_test.dir/progress.make b/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_cv_still_test.dir/progress.make new file mode 100644 index 0000000..c561fca --- /dev/null +++ b/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_cv_still_test.dir/progress.make @@ -0,0 +1,2 @@ +CMAKE_PROGRESS_1 = 8 + diff --git a/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_cv_test.dir/DependInfo.cmake b/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_cv_test.dir/DependInfo.cmake new file mode 100644 index 0000000..dfa6818 --- /dev/null +++ b/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_cv_test.dir/DependInfo.cmake @@ -0,0 +1,28 @@ +# The set of languages for which implicit dependencies are needed: +SET(CMAKE_DEPENDS_LANGUAGES + "CXX" + ) +# The set of files for implicit dependencies of each language: +SET(CMAKE_DEPENDS_CHECK_CXX + "/home/ubuntu/Nomad/external_src/raspicam-0.1.3/utils/raspicam_cv_test.cpp" "/home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_cv_test.dir/raspicam_cv_test.cpp.o" + ) +SET(CMAKE_CXX_COMPILER_ID "GNU") + +# Targets to which this target links. +SET(CMAKE_TARGET_LINKED_INFO_FILES + "/home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/src/CMakeFiles/raspicam.dir/DependInfo.cmake" + "/home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/src/CMakeFiles/raspicam_cv.dir/DependInfo.cmake" + ) + +# The include file search paths: +SET(CMAKE_C_TARGET_INCLUDE_PATH + "../dependencies" + "../dependencies/mmal" + "../dependencies/vcos" + "/usr/local/include/opencv" + "/usr/local/include" + "../src" + ) +SET(CMAKE_CXX_TARGET_INCLUDE_PATH ${CMAKE_C_TARGET_INCLUDE_PATH}) +SET(CMAKE_Fortran_TARGET_INCLUDE_PATH ${CMAKE_C_TARGET_INCLUDE_PATH}) +SET(CMAKE_ASM_TARGET_INCLUDE_PATH ${CMAKE_C_TARGET_INCLUDE_PATH}) diff --git a/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_cv_test.dir/build.make b/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_cv_test.dir/build.make new file mode 100644 index 0000000..23fa3ab --- /dev/null +++ b/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_cv_test.dir/build.make @@ -0,0 +1,124 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/ubuntu/Nomad/external_src/raspicam-0.1.3 + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build + +# Include any dependencies generated for this target. +include utils/CMakeFiles/raspicam_cv_test.dir/depend.make + +# Include the progress variables for this target. +include utils/CMakeFiles/raspicam_cv_test.dir/progress.make + +# Include the compile flags for this target's objects. +include utils/CMakeFiles/raspicam_cv_test.dir/flags.make + +utils/CMakeFiles/raspicam_cv_test.dir/raspicam_cv_test.cpp.o: utils/CMakeFiles/raspicam_cv_test.dir/flags.make +utils/CMakeFiles/raspicam_cv_test.dir/raspicam_cv_test.cpp.o: ../utils/raspicam_cv_test.cpp + $(CMAKE_COMMAND) -E cmake_progress_report /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/CMakeFiles $(CMAKE_PROGRESS_1) + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Building CXX object utils/CMakeFiles/raspicam_cv_test.dir/raspicam_cv_test.cpp.o" + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/utils && /usr/bin/c++ $(CXX_DEFINES) $(CXX_FLAGS) -o CMakeFiles/raspicam_cv_test.dir/raspicam_cv_test.cpp.o -c /home/ubuntu/Nomad/external_src/raspicam-0.1.3/utils/raspicam_cv_test.cpp + +utils/CMakeFiles/raspicam_cv_test.dir/raspicam_cv_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing CXX source to CMakeFiles/raspicam_cv_test.dir/raspicam_cv_test.cpp.i" + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/utils && /usr/bin/c++ $(CXX_DEFINES) $(CXX_FLAGS) -E /home/ubuntu/Nomad/external_src/raspicam-0.1.3/utils/raspicam_cv_test.cpp > CMakeFiles/raspicam_cv_test.dir/raspicam_cv_test.cpp.i + +utils/CMakeFiles/raspicam_cv_test.dir/raspicam_cv_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling CXX source to assembly CMakeFiles/raspicam_cv_test.dir/raspicam_cv_test.cpp.s" + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/utils && /usr/bin/c++ $(CXX_DEFINES) $(CXX_FLAGS) -S /home/ubuntu/Nomad/external_src/raspicam-0.1.3/utils/raspicam_cv_test.cpp -o CMakeFiles/raspicam_cv_test.dir/raspicam_cv_test.cpp.s + +utils/CMakeFiles/raspicam_cv_test.dir/raspicam_cv_test.cpp.o.requires: +.PHONY : utils/CMakeFiles/raspicam_cv_test.dir/raspicam_cv_test.cpp.o.requires + +utils/CMakeFiles/raspicam_cv_test.dir/raspicam_cv_test.cpp.o.provides: utils/CMakeFiles/raspicam_cv_test.dir/raspicam_cv_test.cpp.o.requires + $(MAKE) -f utils/CMakeFiles/raspicam_cv_test.dir/build.make utils/CMakeFiles/raspicam_cv_test.dir/raspicam_cv_test.cpp.o.provides.build +.PHONY : utils/CMakeFiles/raspicam_cv_test.dir/raspicam_cv_test.cpp.o.provides + +utils/CMakeFiles/raspicam_cv_test.dir/raspicam_cv_test.cpp.o.provides.build: utils/CMakeFiles/raspicam_cv_test.dir/raspicam_cv_test.cpp.o + +# Object files for target raspicam_cv_test +raspicam_cv_test_OBJECTS = \ +"CMakeFiles/raspicam_cv_test.dir/raspicam_cv_test.cpp.o" + +# External object files for target raspicam_cv_test +raspicam_cv_test_EXTERNAL_OBJECTS = + +utils/raspicam_cv_test: utils/CMakeFiles/raspicam_cv_test.dir/raspicam_cv_test.cpp.o +utils/raspicam_cv_test: utils/CMakeFiles/raspicam_cv_test.dir/build.make +utils/raspicam_cv_test: src/libraspicam.so.0.1.2 +utils/raspicam_cv_test: src/libraspicam_cv.so +utils/raspicam_cv_test: /opt/vc/lib/libmmal_core.so +utils/raspicam_cv_test: /opt/vc/lib/libmmal_util.so +utils/raspicam_cv_test: /opt/vc/lib/libmmal.so +utils/raspicam_cv_test: /usr/local/lib/libopencv_videostab.so.3.0.0 +utils/raspicam_cv_test: /usr/local/lib/libopencv_superres.so.3.0.0 +utils/raspicam_cv_test: /usr/local/lib/libopencv_stitching.so.3.0.0 +utils/raspicam_cv_test: /usr/local/lib/libopencv_shape.so.3.0.0 +utils/raspicam_cv_test: /usr/local/lib/libopencv_video.so.3.0.0 +utils/raspicam_cv_test: /usr/local/lib/libopencv_photo.so.3.0.0 +utils/raspicam_cv_test: /usr/local/lib/libopencv_objdetect.so.3.0.0 +utils/raspicam_cv_test: /usr/local/lib/libopencv_calib3d.so.3.0.0 +utils/raspicam_cv_test: /usr/local/lib/libopencv_features2d.so.3.0.0 +utils/raspicam_cv_test: /usr/local/lib/libopencv_ml.so.3.0.0 +utils/raspicam_cv_test: /usr/local/lib/libopencv_highgui.so.3.0.0 +utils/raspicam_cv_test: /usr/local/lib/libopencv_videoio.so.3.0.0 +utils/raspicam_cv_test: /usr/local/lib/libopencv_imgcodecs.so.3.0.0 +utils/raspicam_cv_test: /usr/local/lib/libopencv_imgproc.so.3.0.0 +utils/raspicam_cv_test: /usr/local/lib/libopencv_flann.so.3.0.0 +utils/raspicam_cv_test: /usr/local/lib/libopencv_core.so.3.0.0 +utils/raspicam_cv_test: /usr/local/lib/libopencv_hal.a +utils/raspicam_cv_test: utils/CMakeFiles/raspicam_cv_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --red --bold "Linking CXX executable raspicam_cv_test" + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/utils && $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/raspicam_cv_test.dir/link.txt --verbose=$(VERBOSE) + +# Rule to build all files generated by this target. +utils/CMakeFiles/raspicam_cv_test.dir/build: utils/raspicam_cv_test +.PHONY : utils/CMakeFiles/raspicam_cv_test.dir/build + +utils/CMakeFiles/raspicam_cv_test.dir/requires: utils/CMakeFiles/raspicam_cv_test.dir/raspicam_cv_test.cpp.o.requires +.PHONY : utils/CMakeFiles/raspicam_cv_test.dir/requires + +utils/CMakeFiles/raspicam_cv_test.dir/clean: + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/utils && $(CMAKE_COMMAND) -P CMakeFiles/raspicam_cv_test.dir/cmake_clean.cmake +.PHONY : utils/CMakeFiles/raspicam_cv_test.dir/clean + +utils/CMakeFiles/raspicam_cv_test.dir/depend: + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/ubuntu/Nomad/external_src/raspicam-0.1.3 /home/ubuntu/Nomad/external_src/raspicam-0.1.3/utils /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/utils /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_cv_test.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : utils/CMakeFiles/raspicam_cv_test.dir/depend + diff --git a/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_cv_test.dir/cmake_clean.cmake b/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_cv_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..b3dac4d --- /dev/null +++ b/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_cv_test.dir/cmake_clean.cmake @@ -0,0 +1,10 @@ +FILE(REMOVE_RECURSE + "CMakeFiles/raspicam_cv_test.dir/raspicam_cv_test.cpp.o" + "raspicam_cv_test.pdb" + "raspicam_cv_test" +) + +# Per-language clean rules from dependency scanning. +FOREACH(lang CXX) + INCLUDE(CMakeFiles/raspicam_cv_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +ENDFOREACH(lang) diff --git a/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_cv_test.dir/depend.make b/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_cv_test.dir/depend.make new file mode 100644 index 0000000..e21c676 --- /dev/null +++ b/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_cv_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for raspicam_cv_test. +# This may be replaced when dependencies are built. diff --git a/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_cv_test.dir/flags.make b/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_cv_test.dir/flags.make new file mode 100644 index 0000000..1b59b72 --- /dev/null +++ b/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_cv_test.dir/flags.make @@ -0,0 +1,8 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +# compile CXX with /usr/bin/c++ +CXX_FLAGS = -std=c++0x -Wl,--no-as-needed -Wall -ffunction-sections -fomit-frame-pointer -O2 -ffast-math -DNDEBUG -lpthread -I/home/ubuntu/Nomad/external_src/raspicam-0.1.3/dependencies -I/home/ubuntu/Nomad/external_src/raspicam-0.1.3/dependencies/mmal -I/home/ubuntu/Nomad/external_src/raspicam-0.1.3/dependencies/vcos -I/usr/local/include/opencv -I/usr/local/include -I/home/ubuntu/Nomad/external_src/raspicam-0.1.3/src + +CXX_DEFINES = + diff --git a/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_cv_test.dir/link.txt b/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_cv_test.dir/link.txt new file mode 100644 index 0000000..5e6bb08 --- /dev/null +++ b/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_cv_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -std=c++0x -Wl,--no-as-needed -Wall -ffunction-sections -fomit-frame-pointer -O2 -ffast-math -DNDEBUG -lpthread CMakeFiles/raspicam_cv_test.dir/raspicam_cv_test.cpp.o -o raspicam_cv_test -rdynamic ../src/libraspicam.so.0.1.2 ../src/libraspicam_cv.so /opt/vc/lib/libmmal_core.so /opt/vc/lib/libmmal_util.so /opt/vc/lib/libmmal.so /usr/local/lib/libopencv_videostab.so.3.0.0 /usr/local/lib/libopencv_superres.so.3.0.0 /usr/local/lib/libopencv_stitching.so.3.0.0 /usr/local/lib/libopencv_shape.so.3.0.0 /usr/local/lib/libopencv_video.so.3.0.0 /usr/local/lib/libopencv_photo.so.3.0.0 /usr/local/lib/libopencv_objdetect.so.3.0.0 /usr/local/lib/libopencv_calib3d.so.3.0.0 /usr/local/lib/libopencv_features2d.so.3.0.0 /usr/local/lib/libopencv_ml.so.3.0.0 /usr/local/lib/libopencv_highgui.so.3.0.0 /usr/local/lib/libopencv_videoio.so.3.0.0 /usr/local/lib/libopencv_imgcodecs.so.3.0.0 /usr/local/lib/libopencv_imgproc.so.3.0.0 /usr/local/lib/libopencv_flann.so.3.0.0 /usr/local/lib/libopencv_core.so.3.0.0 /usr/local/lib/libopencv_hal.a -ldl -lm -lpthread -lrt -Wl,-rpath,/home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/src:/opt/vc/lib:/usr/local/lib: diff --git a/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_cv_test.dir/progress.make b/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_cv_test.dir/progress.make new file mode 100644 index 0000000..153b0f2 --- /dev/null +++ b/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_cv_test.dir/progress.make @@ -0,0 +1,2 @@ +CMAKE_PROGRESS_1 = 9 + diff --git a/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_still_test.dir/DependInfo.cmake b/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_still_test.dir/DependInfo.cmake new file mode 100644 index 0000000..79de009 --- /dev/null +++ b/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_still_test.dir/DependInfo.cmake @@ -0,0 +1,27 @@ +# The set of languages for which implicit dependencies are needed: +SET(CMAKE_DEPENDS_LANGUAGES + "CXX" + ) +# The set of files for implicit dependencies of each language: +SET(CMAKE_DEPENDS_CHECK_CXX + "/home/ubuntu/Nomad/external_src/raspicam-0.1.3/utils/raspicam_still_test.cpp" "/home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_still_test.dir/raspicam_still_test.cpp.o" + ) +SET(CMAKE_CXX_COMPILER_ID "GNU") + +# Targets to which this target links. +SET(CMAKE_TARGET_LINKED_INFO_FILES + "/home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/src/CMakeFiles/raspicam.dir/DependInfo.cmake" + ) + +# The include file search paths: +SET(CMAKE_C_TARGET_INCLUDE_PATH + "../dependencies" + "../dependencies/mmal" + "../dependencies/vcos" + "/usr/local/include/opencv" + "/usr/local/include" + "../src" + ) +SET(CMAKE_CXX_TARGET_INCLUDE_PATH ${CMAKE_C_TARGET_INCLUDE_PATH}) +SET(CMAKE_Fortran_TARGET_INCLUDE_PATH ${CMAKE_C_TARGET_INCLUDE_PATH}) +SET(CMAKE_ASM_TARGET_INCLUDE_PATH ${CMAKE_C_TARGET_INCLUDE_PATH}) diff --git a/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_still_test.dir/build.make b/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_still_test.dir/build.make new file mode 100644 index 0000000..45975a5 --- /dev/null +++ b/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_still_test.dir/build.make @@ -0,0 +1,106 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/ubuntu/Nomad/external_src/raspicam-0.1.3 + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build + +# Include any dependencies generated for this target. +include utils/CMakeFiles/raspicam_still_test.dir/depend.make + +# Include the progress variables for this target. +include utils/CMakeFiles/raspicam_still_test.dir/progress.make + +# Include the compile flags for this target's objects. +include utils/CMakeFiles/raspicam_still_test.dir/flags.make + +utils/CMakeFiles/raspicam_still_test.dir/raspicam_still_test.cpp.o: utils/CMakeFiles/raspicam_still_test.dir/flags.make +utils/CMakeFiles/raspicam_still_test.dir/raspicam_still_test.cpp.o: ../utils/raspicam_still_test.cpp + $(CMAKE_COMMAND) -E cmake_progress_report /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/CMakeFiles $(CMAKE_PROGRESS_1) + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Building CXX object utils/CMakeFiles/raspicam_still_test.dir/raspicam_still_test.cpp.o" + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/utils && /usr/bin/c++ $(CXX_DEFINES) $(CXX_FLAGS) -o CMakeFiles/raspicam_still_test.dir/raspicam_still_test.cpp.o -c /home/ubuntu/Nomad/external_src/raspicam-0.1.3/utils/raspicam_still_test.cpp + +utils/CMakeFiles/raspicam_still_test.dir/raspicam_still_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing CXX source to CMakeFiles/raspicam_still_test.dir/raspicam_still_test.cpp.i" + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/utils && /usr/bin/c++ $(CXX_DEFINES) $(CXX_FLAGS) -E /home/ubuntu/Nomad/external_src/raspicam-0.1.3/utils/raspicam_still_test.cpp > CMakeFiles/raspicam_still_test.dir/raspicam_still_test.cpp.i + +utils/CMakeFiles/raspicam_still_test.dir/raspicam_still_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling CXX source to assembly CMakeFiles/raspicam_still_test.dir/raspicam_still_test.cpp.s" + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/utils && /usr/bin/c++ $(CXX_DEFINES) $(CXX_FLAGS) -S /home/ubuntu/Nomad/external_src/raspicam-0.1.3/utils/raspicam_still_test.cpp -o CMakeFiles/raspicam_still_test.dir/raspicam_still_test.cpp.s + +utils/CMakeFiles/raspicam_still_test.dir/raspicam_still_test.cpp.o.requires: +.PHONY : utils/CMakeFiles/raspicam_still_test.dir/raspicam_still_test.cpp.o.requires + +utils/CMakeFiles/raspicam_still_test.dir/raspicam_still_test.cpp.o.provides: utils/CMakeFiles/raspicam_still_test.dir/raspicam_still_test.cpp.o.requires + $(MAKE) -f utils/CMakeFiles/raspicam_still_test.dir/build.make utils/CMakeFiles/raspicam_still_test.dir/raspicam_still_test.cpp.o.provides.build +.PHONY : utils/CMakeFiles/raspicam_still_test.dir/raspicam_still_test.cpp.o.provides + +utils/CMakeFiles/raspicam_still_test.dir/raspicam_still_test.cpp.o.provides.build: utils/CMakeFiles/raspicam_still_test.dir/raspicam_still_test.cpp.o + +# Object files for target raspicam_still_test +raspicam_still_test_OBJECTS = \ +"CMakeFiles/raspicam_still_test.dir/raspicam_still_test.cpp.o" + +# External object files for target raspicam_still_test +raspicam_still_test_EXTERNAL_OBJECTS = + +utils/raspicam_still_test: utils/CMakeFiles/raspicam_still_test.dir/raspicam_still_test.cpp.o +utils/raspicam_still_test: utils/CMakeFiles/raspicam_still_test.dir/build.make +utils/raspicam_still_test: src/libraspicam.so.0.1.2 +utils/raspicam_still_test: /opt/vc/lib/libmmal_core.so +utils/raspicam_still_test: /opt/vc/lib/libmmal_util.so +utils/raspicam_still_test: /opt/vc/lib/libmmal.so +utils/raspicam_still_test: utils/CMakeFiles/raspicam_still_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --red --bold "Linking CXX executable raspicam_still_test" + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/utils && $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/raspicam_still_test.dir/link.txt --verbose=$(VERBOSE) + +# Rule to build all files generated by this target. +utils/CMakeFiles/raspicam_still_test.dir/build: utils/raspicam_still_test +.PHONY : utils/CMakeFiles/raspicam_still_test.dir/build + +utils/CMakeFiles/raspicam_still_test.dir/requires: utils/CMakeFiles/raspicam_still_test.dir/raspicam_still_test.cpp.o.requires +.PHONY : utils/CMakeFiles/raspicam_still_test.dir/requires + +utils/CMakeFiles/raspicam_still_test.dir/clean: + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/utils && $(CMAKE_COMMAND) -P CMakeFiles/raspicam_still_test.dir/cmake_clean.cmake +.PHONY : utils/CMakeFiles/raspicam_still_test.dir/clean + +utils/CMakeFiles/raspicam_still_test.dir/depend: + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/ubuntu/Nomad/external_src/raspicam-0.1.3 /home/ubuntu/Nomad/external_src/raspicam-0.1.3/utils /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/utils /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_still_test.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : utils/CMakeFiles/raspicam_still_test.dir/depend + diff --git a/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_still_test.dir/cmake_clean.cmake b/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_still_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..c9a2551 --- /dev/null +++ b/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_still_test.dir/cmake_clean.cmake @@ -0,0 +1,10 @@ +FILE(REMOVE_RECURSE + "CMakeFiles/raspicam_still_test.dir/raspicam_still_test.cpp.o" + "raspicam_still_test.pdb" + "raspicam_still_test" +) + +# Per-language clean rules from dependency scanning. +FOREACH(lang CXX) + INCLUDE(CMakeFiles/raspicam_still_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +ENDFOREACH(lang) diff --git a/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_still_test.dir/depend.make b/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_still_test.dir/depend.make new file mode 100644 index 0000000..8f85649 --- /dev/null +++ b/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_still_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for raspicam_still_test. +# This may be replaced when dependencies are built. diff --git a/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_still_test.dir/flags.make b/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_still_test.dir/flags.make new file mode 100644 index 0000000..1b59b72 --- /dev/null +++ b/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_still_test.dir/flags.make @@ -0,0 +1,8 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +# compile CXX with /usr/bin/c++ +CXX_FLAGS = -std=c++0x -Wl,--no-as-needed -Wall -ffunction-sections -fomit-frame-pointer -O2 -ffast-math -DNDEBUG -lpthread -I/home/ubuntu/Nomad/external_src/raspicam-0.1.3/dependencies -I/home/ubuntu/Nomad/external_src/raspicam-0.1.3/dependencies/mmal -I/home/ubuntu/Nomad/external_src/raspicam-0.1.3/dependencies/vcos -I/usr/local/include/opencv -I/usr/local/include -I/home/ubuntu/Nomad/external_src/raspicam-0.1.3/src + +CXX_DEFINES = + diff --git a/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_still_test.dir/link.txt b/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_still_test.dir/link.txt new file mode 100644 index 0000000..9884f02 --- /dev/null +++ b/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_still_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -std=c++0x -Wl,--no-as-needed -Wall -ffunction-sections -fomit-frame-pointer -O2 -ffast-math -DNDEBUG -lpthread CMakeFiles/raspicam_still_test.dir/raspicam_still_test.cpp.o -o raspicam_still_test -rdynamic ../src/libraspicam.so.0.1.2 /opt/vc/lib/libmmal_core.so /opt/vc/lib/libmmal_util.so /opt/vc/lib/libmmal.so -Wl,-rpath,/home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/src:/opt/vc/lib: diff --git a/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_still_test.dir/progress.make b/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_still_test.dir/progress.make new file mode 100644 index 0000000..d61796b --- /dev/null +++ b/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_still_test.dir/progress.make @@ -0,0 +1,2 @@ +CMAKE_PROGRESS_1 = 10 + diff --git a/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_test.dir/DependInfo.cmake b/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_test.dir/DependInfo.cmake new file mode 100644 index 0000000..7922c37 --- /dev/null +++ b/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_test.dir/DependInfo.cmake @@ -0,0 +1,27 @@ +# The set of languages for which implicit dependencies are needed: +SET(CMAKE_DEPENDS_LANGUAGES + "CXX" + ) +# The set of files for implicit dependencies of each language: +SET(CMAKE_DEPENDS_CHECK_CXX + "/home/ubuntu/Nomad/external_src/raspicam-0.1.3/utils/raspicam_test.cpp" "/home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_test.dir/raspicam_test.cpp.o" + ) +SET(CMAKE_CXX_COMPILER_ID "GNU") + +# Targets to which this target links. +SET(CMAKE_TARGET_LINKED_INFO_FILES + "/home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/src/CMakeFiles/raspicam.dir/DependInfo.cmake" + ) + +# The include file search paths: +SET(CMAKE_C_TARGET_INCLUDE_PATH + "../dependencies" + "../dependencies/mmal" + "../dependencies/vcos" + "/usr/local/include/opencv" + "/usr/local/include" + "../src" + ) +SET(CMAKE_CXX_TARGET_INCLUDE_PATH ${CMAKE_C_TARGET_INCLUDE_PATH}) +SET(CMAKE_Fortran_TARGET_INCLUDE_PATH ${CMAKE_C_TARGET_INCLUDE_PATH}) +SET(CMAKE_ASM_TARGET_INCLUDE_PATH ${CMAKE_C_TARGET_INCLUDE_PATH}) diff --git a/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_test.dir/build.make b/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_test.dir/build.make new file mode 100644 index 0000000..97c77a0 --- /dev/null +++ b/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_test.dir/build.make @@ -0,0 +1,106 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/ubuntu/Nomad/external_src/raspicam-0.1.3 + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build + +# Include any dependencies generated for this target. +include utils/CMakeFiles/raspicam_test.dir/depend.make + +# Include the progress variables for this target. +include utils/CMakeFiles/raspicam_test.dir/progress.make + +# Include the compile flags for this target's objects. +include utils/CMakeFiles/raspicam_test.dir/flags.make + +utils/CMakeFiles/raspicam_test.dir/raspicam_test.cpp.o: utils/CMakeFiles/raspicam_test.dir/flags.make +utils/CMakeFiles/raspicam_test.dir/raspicam_test.cpp.o: ../utils/raspicam_test.cpp + $(CMAKE_COMMAND) -E cmake_progress_report /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/CMakeFiles $(CMAKE_PROGRESS_1) + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Building CXX object utils/CMakeFiles/raspicam_test.dir/raspicam_test.cpp.o" + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/utils && /usr/bin/c++ $(CXX_DEFINES) $(CXX_FLAGS) -o CMakeFiles/raspicam_test.dir/raspicam_test.cpp.o -c /home/ubuntu/Nomad/external_src/raspicam-0.1.3/utils/raspicam_test.cpp + +utils/CMakeFiles/raspicam_test.dir/raspicam_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing CXX source to CMakeFiles/raspicam_test.dir/raspicam_test.cpp.i" + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/utils && /usr/bin/c++ $(CXX_DEFINES) $(CXX_FLAGS) -E /home/ubuntu/Nomad/external_src/raspicam-0.1.3/utils/raspicam_test.cpp > CMakeFiles/raspicam_test.dir/raspicam_test.cpp.i + +utils/CMakeFiles/raspicam_test.dir/raspicam_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling CXX source to assembly CMakeFiles/raspicam_test.dir/raspicam_test.cpp.s" + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/utils && /usr/bin/c++ $(CXX_DEFINES) $(CXX_FLAGS) -S /home/ubuntu/Nomad/external_src/raspicam-0.1.3/utils/raspicam_test.cpp -o CMakeFiles/raspicam_test.dir/raspicam_test.cpp.s + +utils/CMakeFiles/raspicam_test.dir/raspicam_test.cpp.o.requires: +.PHONY : utils/CMakeFiles/raspicam_test.dir/raspicam_test.cpp.o.requires + +utils/CMakeFiles/raspicam_test.dir/raspicam_test.cpp.o.provides: utils/CMakeFiles/raspicam_test.dir/raspicam_test.cpp.o.requires + $(MAKE) -f utils/CMakeFiles/raspicam_test.dir/build.make utils/CMakeFiles/raspicam_test.dir/raspicam_test.cpp.o.provides.build +.PHONY : utils/CMakeFiles/raspicam_test.dir/raspicam_test.cpp.o.provides + +utils/CMakeFiles/raspicam_test.dir/raspicam_test.cpp.o.provides.build: utils/CMakeFiles/raspicam_test.dir/raspicam_test.cpp.o + +# Object files for target raspicam_test +raspicam_test_OBJECTS = \ +"CMakeFiles/raspicam_test.dir/raspicam_test.cpp.o" + +# External object files for target raspicam_test +raspicam_test_EXTERNAL_OBJECTS = + +utils/raspicam_test: utils/CMakeFiles/raspicam_test.dir/raspicam_test.cpp.o +utils/raspicam_test: utils/CMakeFiles/raspicam_test.dir/build.make +utils/raspicam_test: src/libraspicam.so.0.1.2 +utils/raspicam_test: /opt/vc/lib/libmmal_core.so +utils/raspicam_test: /opt/vc/lib/libmmal_util.so +utils/raspicam_test: /opt/vc/lib/libmmal.so +utils/raspicam_test: utils/CMakeFiles/raspicam_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --red --bold "Linking CXX executable raspicam_test" + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/utils && $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/raspicam_test.dir/link.txt --verbose=$(VERBOSE) + +# Rule to build all files generated by this target. +utils/CMakeFiles/raspicam_test.dir/build: utils/raspicam_test +.PHONY : utils/CMakeFiles/raspicam_test.dir/build + +utils/CMakeFiles/raspicam_test.dir/requires: utils/CMakeFiles/raspicam_test.dir/raspicam_test.cpp.o.requires +.PHONY : utils/CMakeFiles/raspicam_test.dir/requires + +utils/CMakeFiles/raspicam_test.dir/clean: + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/utils && $(CMAKE_COMMAND) -P CMakeFiles/raspicam_test.dir/cmake_clean.cmake +.PHONY : utils/CMakeFiles/raspicam_test.dir/clean + +utils/CMakeFiles/raspicam_test.dir/depend: + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/ubuntu/Nomad/external_src/raspicam-0.1.3 /home/ubuntu/Nomad/external_src/raspicam-0.1.3/utils /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/utils /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_test.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : utils/CMakeFiles/raspicam_test.dir/depend + diff --git a/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_test.dir/cmake_clean.cmake b/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..bf9094c --- /dev/null +++ b/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_test.dir/cmake_clean.cmake @@ -0,0 +1,10 @@ +FILE(REMOVE_RECURSE + "CMakeFiles/raspicam_test.dir/raspicam_test.cpp.o" + "raspicam_test.pdb" + "raspicam_test" +) + +# Per-language clean rules from dependency scanning. +FOREACH(lang CXX) + INCLUDE(CMakeFiles/raspicam_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +ENDFOREACH(lang) diff --git a/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_test.dir/depend.make b/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_test.dir/depend.make new file mode 100644 index 0000000..cc48ce0 --- /dev/null +++ b/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for raspicam_test. +# This may be replaced when dependencies are built. diff --git a/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_test.dir/flags.make b/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_test.dir/flags.make new file mode 100644 index 0000000..1b59b72 --- /dev/null +++ b/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_test.dir/flags.make @@ -0,0 +1,8 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +# compile CXX with /usr/bin/c++ +CXX_FLAGS = -std=c++0x -Wl,--no-as-needed -Wall -ffunction-sections -fomit-frame-pointer -O2 -ffast-math -DNDEBUG -lpthread -I/home/ubuntu/Nomad/external_src/raspicam-0.1.3/dependencies -I/home/ubuntu/Nomad/external_src/raspicam-0.1.3/dependencies/mmal -I/home/ubuntu/Nomad/external_src/raspicam-0.1.3/dependencies/vcos -I/usr/local/include/opencv -I/usr/local/include -I/home/ubuntu/Nomad/external_src/raspicam-0.1.3/src + +CXX_DEFINES = + diff --git a/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_test.dir/link.txt b/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_test.dir/link.txt new file mode 100644 index 0000000..52b1d53 --- /dev/null +++ b/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -std=c++0x -Wl,--no-as-needed -Wall -ffunction-sections -fomit-frame-pointer -O2 -ffast-math -DNDEBUG -lpthread CMakeFiles/raspicam_test.dir/raspicam_test.cpp.o -o raspicam_test -rdynamic ../src/libraspicam.so.0.1.2 /opt/vc/lib/libmmal_core.so /opt/vc/lib/libmmal_util.so /opt/vc/lib/libmmal.so -Wl,-rpath,/home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/src:/opt/vc/lib: diff --git a/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_test.dir/progress.make b/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_test.dir/progress.make new file mode 100644 index 0000000..27952ed --- /dev/null +++ b/external_src/raspicam-0.1.3/build/utils/CMakeFiles/raspicam_test.dir/progress.make @@ -0,0 +1,2 @@ +CMAKE_PROGRESS_1 = 11 + diff --git a/external_src/raspicam-0.1.3/build/utils/Makefile b/external_src/raspicam-0.1.3/build/utils/Makefile new file mode 100644 index 0000000..0bdf7c4 --- /dev/null +++ b/external_src/raspicam-0.1.3/build/utils/Makefile @@ -0,0 +1,335 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +# Default target executed when no arguments are given to make. +default_target: all +.PHONY : default_target + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/ubuntu/Nomad/external_src/raspicam-0.1.3 + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build + +#============================================================================= +# Targets provided globally by CMake. + +# Special rule for the target edit_cache +edit_cache: + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running interactive CMake command-line interface..." + /usr/bin/cmake -i . +.PHONY : edit_cache + +# Special rule for the target edit_cache +edit_cache/fast: edit_cache +.PHONY : edit_cache/fast + +# Special rule for the target install +install: preinstall + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Install the project..." + /usr/bin/cmake -P cmake_install.cmake +.PHONY : install + +# Special rule for the target install +install/fast: preinstall/fast + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Install the project..." + /usr/bin/cmake -P cmake_install.cmake +.PHONY : install/fast + +# Special rule for the target install/local +install/local: preinstall + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Installing only the local directory..." + /usr/bin/cmake -DCMAKE_INSTALL_LOCAL_ONLY=1 -P cmake_install.cmake +.PHONY : install/local + +# Special rule for the target install/local +install/local/fast: install/local +.PHONY : install/local/fast + +# Special rule for the target install/strip +install/strip: preinstall + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Installing the project stripped..." + /usr/bin/cmake -DCMAKE_INSTALL_DO_STRIP=1 -P cmake_install.cmake +.PHONY : install/strip + +# Special rule for the target install/strip +install/strip/fast: install/strip +.PHONY : install/strip/fast + +# Special rule for the target list_install_components +list_install_components: + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Available install components are: \"Unspecified\" \"main\"" +.PHONY : list_install_components + +# Special rule for the target list_install_components +list_install_components/fast: list_install_components +.PHONY : list_install_components/fast + +# Special rule for the target rebuild_cache +rebuild_cache: + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running CMake to regenerate build system..." + /usr/bin/cmake -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) +.PHONY : rebuild_cache + +# Special rule for the target rebuild_cache +rebuild_cache/fast: rebuild_cache +.PHONY : rebuild_cache/fast + +# The main all target +all: cmake_check_build_system + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build && $(CMAKE_COMMAND) -E cmake_progress_start /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/CMakeFiles /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/utils/CMakeFiles/progress.marks + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build && $(MAKE) -f CMakeFiles/Makefile2 utils/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/CMakeFiles 0 +.PHONY : all + +# The main clean target +clean: + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build && $(MAKE) -f CMakeFiles/Makefile2 utils/clean +.PHONY : clean + +# The main clean target +clean/fast: clean +.PHONY : clean/fast + +# Prepare targets for installation. +preinstall: all + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build && $(MAKE) -f CMakeFiles/Makefile2 utils/preinstall +.PHONY : preinstall + +# Prepare targets for installation. +preinstall/fast: + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build && $(MAKE) -f CMakeFiles/Makefile2 utils/preinstall +.PHONY : preinstall/fast + +# clear depends +depend: + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build && $(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 1 +.PHONY : depend + +# Convenience name for target. +utils/CMakeFiles/raspicam_cv_still_test.dir/rule: + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build && $(MAKE) -f CMakeFiles/Makefile2 utils/CMakeFiles/raspicam_cv_still_test.dir/rule +.PHONY : utils/CMakeFiles/raspicam_cv_still_test.dir/rule + +# Convenience name for target. +raspicam_cv_still_test: utils/CMakeFiles/raspicam_cv_still_test.dir/rule +.PHONY : raspicam_cv_still_test + +# fast build rule for target. +raspicam_cv_still_test/fast: + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build && $(MAKE) -f utils/CMakeFiles/raspicam_cv_still_test.dir/build.make utils/CMakeFiles/raspicam_cv_still_test.dir/build +.PHONY : raspicam_cv_still_test/fast + +# Convenience name for target. +utils/CMakeFiles/raspicam_cv_test.dir/rule: + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build && $(MAKE) -f CMakeFiles/Makefile2 utils/CMakeFiles/raspicam_cv_test.dir/rule +.PHONY : utils/CMakeFiles/raspicam_cv_test.dir/rule + +# Convenience name for target. +raspicam_cv_test: utils/CMakeFiles/raspicam_cv_test.dir/rule +.PHONY : raspicam_cv_test + +# fast build rule for target. +raspicam_cv_test/fast: + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build && $(MAKE) -f utils/CMakeFiles/raspicam_cv_test.dir/build.make utils/CMakeFiles/raspicam_cv_test.dir/build +.PHONY : raspicam_cv_test/fast + +# Convenience name for target. +utils/CMakeFiles/raspicam_still_test.dir/rule: + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build && $(MAKE) -f CMakeFiles/Makefile2 utils/CMakeFiles/raspicam_still_test.dir/rule +.PHONY : utils/CMakeFiles/raspicam_still_test.dir/rule + +# Convenience name for target. +raspicam_still_test: utils/CMakeFiles/raspicam_still_test.dir/rule +.PHONY : raspicam_still_test + +# fast build rule for target. +raspicam_still_test/fast: + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build && $(MAKE) -f utils/CMakeFiles/raspicam_still_test.dir/build.make utils/CMakeFiles/raspicam_still_test.dir/build +.PHONY : raspicam_still_test/fast + +# Convenience name for target. +utils/CMakeFiles/raspicam_test.dir/rule: + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build && $(MAKE) -f CMakeFiles/Makefile2 utils/CMakeFiles/raspicam_test.dir/rule +.PHONY : utils/CMakeFiles/raspicam_test.dir/rule + +# Convenience name for target. +raspicam_test: utils/CMakeFiles/raspicam_test.dir/rule +.PHONY : raspicam_test + +# fast build rule for target. +raspicam_test/fast: + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build && $(MAKE) -f utils/CMakeFiles/raspicam_test.dir/build.make utils/CMakeFiles/raspicam_test.dir/build +.PHONY : raspicam_test/fast + +raspicam_cv_still_test.o: raspicam_cv_still_test.cpp.o +.PHONY : raspicam_cv_still_test.o + +# target to build an object file +raspicam_cv_still_test.cpp.o: + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build && $(MAKE) -f utils/CMakeFiles/raspicam_cv_still_test.dir/build.make utils/CMakeFiles/raspicam_cv_still_test.dir/raspicam_cv_still_test.cpp.o +.PHONY : raspicam_cv_still_test.cpp.o + +raspicam_cv_still_test.i: raspicam_cv_still_test.cpp.i +.PHONY : raspicam_cv_still_test.i + +# target to preprocess a source file +raspicam_cv_still_test.cpp.i: + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build && $(MAKE) -f utils/CMakeFiles/raspicam_cv_still_test.dir/build.make utils/CMakeFiles/raspicam_cv_still_test.dir/raspicam_cv_still_test.cpp.i +.PHONY : raspicam_cv_still_test.cpp.i + +raspicam_cv_still_test.s: raspicam_cv_still_test.cpp.s +.PHONY : raspicam_cv_still_test.s + +# target to generate assembly for a file +raspicam_cv_still_test.cpp.s: + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build && $(MAKE) -f utils/CMakeFiles/raspicam_cv_still_test.dir/build.make utils/CMakeFiles/raspicam_cv_still_test.dir/raspicam_cv_still_test.cpp.s +.PHONY : raspicam_cv_still_test.cpp.s + +raspicam_cv_test.o: raspicam_cv_test.cpp.o +.PHONY : raspicam_cv_test.o + +# target to build an object file +raspicam_cv_test.cpp.o: + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build && $(MAKE) -f utils/CMakeFiles/raspicam_cv_test.dir/build.make utils/CMakeFiles/raspicam_cv_test.dir/raspicam_cv_test.cpp.o +.PHONY : raspicam_cv_test.cpp.o + +raspicam_cv_test.i: raspicam_cv_test.cpp.i +.PHONY : raspicam_cv_test.i + +# target to preprocess a source file +raspicam_cv_test.cpp.i: + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build && $(MAKE) -f utils/CMakeFiles/raspicam_cv_test.dir/build.make utils/CMakeFiles/raspicam_cv_test.dir/raspicam_cv_test.cpp.i +.PHONY : raspicam_cv_test.cpp.i + +raspicam_cv_test.s: raspicam_cv_test.cpp.s +.PHONY : raspicam_cv_test.s + +# target to generate assembly for a file +raspicam_cv_test.cpp.s: + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build && $(MAKE) -f utils/CMakeFiles/raspicam_cv_test.dir/build.make utils/CMakeFiles/raspicam_cv_test.dir/raspicam_cv_test.cpp.s +.PHONY : raspicam_cv_test.cpp.s + +raspicam_still_test.o: raspicam_still_test.cpp.o +.PHONY : raspicam_still_test.o + +# target to build an object file +raspicam_still_test.cpp.o: + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build && $(MAKE) -f utils/CMakeFiles/raspicam_still_test.dir/build.make utils/CMakeFiles/raspicam_still_test.dir/raspicam_still_test.cpp.o +.PHONY : raspicam_still_test.cpp.o + +raspicam_still_test.i: raspicam_still_test.cpp.i +.PHONY : raspicam_still_test.i + +# target to preprocess a source file +raspicam_still_test.cpp.i: + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build && $(MAKE) -f utils/CMakeFiles/raspicam_still_test.dir/build.make utils/CMakeFiles/raspicam_still_test.dir/raspicam_still_test.cpp.i +.PHONY : raspicam_still_test.cpp.i + +raspicam_still_test.s: raspicam_still_test.cpp.s +.PHONY : raspicam_still_test.s + +# target to generate assembly for a file +raspicam_still_test.cpp.s: + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build && $(MAKE) -f utils/CMakeFiles/raspicam_still_test.dir/build.make utils/CMakeFiles/raspicam_still_test.dir/raspicam_still_test.cpp.s +.PHONY : raspicam_still_test.cpp.s + +raspicam_test.o: raspicam_test.cpp.o +.PHONY : raspicam_test.o + +# target to build an object file +raspicam_test.cpp.o: + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build && $(MAKE) -f utils/CMakeFiles/raspicam_test.dir/build.make utils/CMakeFiles/raspicam_test.dir/raspicam_test.cpp.o +.PHONY : raspicam_test.cpp.o + +raspicam_test.i: raspicam_test.cpp.i +.PHONY : raspicam_test.i + +# target to preprocess a source file +raspicam_test.cpp.i: + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build && $(MAKE) -f utils/CMakeFiles/raspicam_test.dir/build.make utils/CMakeFiles/raspicam_test.dir/raspicam_test.cpp.i +.PHONY : raspicam_test.cpp.i + +raspicam_test.s: raspicam_test.cpp.s +.PHONY : raspicam_test.s + +# target to generate assembly for a file +raspicam_test.cpp.s: + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build && $(MAKE) -f utils/CMakeFiles/raspicam_test.dir/build.make utils/CMakeFiles/raspicam_test.dir/raspicam_test.cpp.s +.PHONY : raspicam_test.cpp.s + +# Help Target +help: + @echo "The following are some of the valid targets for this Makefile:" + @echo "... all (the default if no target is provided)" + @echo "... clean" + @echo "... depend" + @echo "... edit_cache" + @echo "... install" + @echo "... install/local" + @echo "... install/strip" + @echo "... list_install_components" + @echo "... raspicam_cv_still_test" + @echo "... raspicam_cv_test" + @echo "... raspicam_still_test" + @echo "... raspicam_test" + @echo "... rebuild_cache" + @echo "... raspicam_cv_still_test.o" + @echo "... raspicam_cv_still_test.i" + @echo "... raspicam_cv_still_test.s" + @echo "... raspicam_cv_test.o" + @echo "... raspicam_cv_test.i" + @echo "... raspicam_cv_test.s" + @echo "... raspicam_still_test.o" + @echo "... raspicam_still_test.i" + @echo "... raspicam_still_test.s" + @echo "... raspicam_test.o" + @echo "... raspicam_test.i" + @echo "... raspicam_test.s" +.PHONY : help + + + +#============================================================================= +# Special targets to cleanup operation of make. + +# Special rule to run CMake to check the build system integrity. +# No rule that depends on this can have commands that come from listfiles +# because they might be regenerated. +cmake_check_build_system: + cd /home/ubuntu/Nomad/external_src/raspicam-0.1.3/build && $(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 0 +.PHONY : cmake_check_build_system + diff --git a/external_src/raspicam-0.1.3/build/utils/cmake_install.cmake b/external_src/raspicam-0.1.3/build/utils/cmake_install.cmake new file mode 100644 index 0000000..d04c5a1 --- /dev/null +++ b/external_src/raspicam-0.1.3/build/utils/cmake_install.cmake @@ -0,0 +1,106 @@ +# Install script for directory: /home/ubuntu/Nomad/external_src/raspicam-0.1.3/utils + +# Set the install prefix +IF(NOT DEFINED CMAKE_INSTALL_PREFIX) + SET(CMAKE_INSTALL_PREFIX "/usr/local") +ENDIF(NOT DEFINED CMAKE_INSTALL_PREFIX) +STRING(REGEX REPLACE "/$" "" CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}") + +# Set the install configuration name. +IF(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME) + IF(BUILD_TYPE) + STRING(REGEX REPLACE "^[^A-Za-z0-9_]+" "" + CMAKE_INSTALL_CONFIG_NAME "${BUILD_TYPE}") + ELSE(BUILD_TYPE) + SET(CMAKE_INSTALL_CONFIG_NAME "Release") + ENDIF(BUILD_TYPE) + MESSAGE(STATUS "Install configuration: \"${CMAKE_INSTALL_CONFIG_NAME}\"") +ENDIF(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME) + +# Set the component getting installed. +IF(NOT CMAKE_INSTALL_COMPONENT) + IF(COMPONENT) + MESSAGE(STATUS "Install component: \"${COMPONENT}\"") + SET(CMAKE_INSTALL_COMPONENT "${COMPONENT}") + ELSE(COMPONENT) + SET(CMAKE_INSTALL_COMPONENT) + ENDIF(COMPONENT) +ENDIF(NOT CMAKE_INSTALL_COMPONENT) + +# Install shared libraries without execute permission? +IF(NOT DEFINED CMAKE_INSTALL_SO_NO_EXE) + SET(CMAKE_INSTALL_SO_NO_EXE "1") +ENDIF(NOT DEFINED CMAKE_INSTALL_SO_NO_EXE) + +IF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + IF(EXISTS "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/bin/raspicam_test" AND + NOT IS_SYMLINK "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/bin/raspicam_test") + FILE(RPATH_CHECK + FILE "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/bin/raspicam_test" + RPATH "") + ENDIF() + FILE(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/bin" TYPE EXECUTABLE FILES "/home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/utils/raspicam_test") + IF(EXISTS "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/bin/raspicam_test" AND + NOT IS_SYMLINK "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/bin/raspicam_test") + FILE(RPATH_REMOVE + FILE "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/bin/raspicam_test") + IF(CMAKE_INSTALL_DO_STRIP) + EXECUTE_PROCESS(COMMAND "/usr/bin/strip" "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/bin/raspicam_test") + ENDIF(CMAKE_INSTALL_DO_STRIP) + ENDIF() +ENDIF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + +IF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + IF(EXISTS "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/bin/raspicam_still_test" AND + NOT IS_SYMLINK "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/bin/raspicam_still_test") + FILE(RPATH_CHECK + FILE "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/bin/raspicam_still_test" + RPATH "") + ENDIF() + FILE(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/bin" TYPE EXECUTABLE FILES "/home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/utils/raspicam_still_test") + IF(EXISTS "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/bin/raspicam_still_test" AND + NOT IS_SYMLINK "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/bin/raspicam_still_test") + FILE(RPATH_REMOVE + FILE "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/bin/raspicam_still_test") + IF(CMAKE_INSTALL_DO_STRIP) + EXECUTE_PROCESS(COMMAND "/usr/bin/strip" "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/bin/raspicam_still_test") + ENDIF(CMAKE_INSTALL_DO_STRIP) + ENDIF() +ENDIF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + +IF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + IF(EXISTS "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/bin/raspicam_cv_test" AND + NOT IS_SYMLINK "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/bin/raspicam_cv_test") + FILE(RPATH_CHECK + FILE "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/bin/raspicam_cv_test" + RPATH "") + ENDIF() + FILE(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/bin" TYPE EXECUTABLE FILES "/home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/utils/raspicam_cv_test") + IF(EXISTS "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/bin/raspicam_cv_test" AND + NOT IS_SYMLINK "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/bin/raspicam_cv_test") + FILE(RPATH_REMOVE + FILE "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/bin/raspicam_cv_test") + IF(CMAKE_INSTALL_DO_STRIP) + EXECUTE_PROCESS(COMMAND "/usr/bin/strip" "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/bin/raspicam_cv_test") + ENDIF(CMAKE_INSTALL_DO_STRIP) + ENDIF() +ENDIF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + +IF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + IF(EXISTS "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/bin/raspicam_cv_still_test" AND + NOT IS_SYMLINK "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/bin/raspicam_cv_still_test") + FILE(RPATH_CHECK + FILE "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/bin/raspicam_cv_still_test" + RPATH "") + ENDIF() + FILE(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/bin" TYPE EXECUTABLE FILES "/home/ubuntu/Nomad/external_src/raspicam-0.1.3/build/utils/raspicam_cv_still_test") + IF(EXISTS "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/bin/raspicam_cv_still_test" AND + NOT IS_SYMLINK "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/bin/raspicam_cv_still_test") + FILE(RPATH_REMOVE + FILE "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/bin/raspicam_cv_still_test") + IF(CMAKE_INSTALL_DO_STRIP) + EXECUTE_PROCESS(COMMAND "/usr/bin/strip" "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/bin/raspicam_cv_still_test") + ENDIF(CMAKE_INSTALL_DO_STRIP) + ENDIF() +ENDIF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + diff --git a/external_src/raspicam-0.1.3/cmake_uninstall.cmake.in b/external_src/raspicam-0.1.3/cmake_uninstall.cmake.in new file mode 100644 index 0000000..81482da --- /dev/null +++ b/external_src/raspicam-0.1.3/cmake_uninstall.cmake.in @@ -0,0 +1,28 @@ +# ----------------------------------------------- +# File that provides "make uninstall" target +# We use the file 'install_manifest.txt' +# ----------------------------------------------- +IF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") + MESSAGE(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\"") +ENDIF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") + +FILE(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files) +STRING(REGEX REPLACE "\n" ";" files "${files}") +FOREACH(file ${files}) + MESSAGE(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"") +# IF(EXISTS "$ENV{DESTDIR}${file}") +# EXEC_PROGRAM( +# "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" +# OUTPUT_VARIABLE rm_out +# RETURN_VALUE rm_retval +# ) + EXECUTE_PROCESS(COMMAND rm $ENV{DESTDIR}${file}) +# IF(NOT "${rm_retval}" STREQUAL 0) +# MESSAGE(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"") +# ENDIF(NOT "${rm_retval}" STREQUAL 0) +# ELSE(EXISTS "$ENV{DESTDIR}${file}") +# MESSAGE(STATUS "File \"$ENV{DESTDIR}${file}\" does not exist.") +# ENDIF(EXISTS "$ENV{DESTDIR}${file}") +ENDFOREACH(file) + + diff --git a/external_src/raspicam-0.1.3/config.cmake.in b/external_src/raspicam-0.1.3/config.cmake.in new file mode 100644 index 0000000..48aa39b --- /dev/null +++ b/external_src/raspicam-0.1.3/config.cmake.in @@ -0,0 +1,34 @@ +# =================================================================================== +# @PROJECT_NAME@ CMake configuration file +# +# ** File generated automatically, do not modify ** +# +# Usage from an external project: +# In your CMakeLists.txt, add these lines: +# +# FIND_PACKAGE(@PROJECT_NAME@ REQUIRED ) +# TARGET_LINK_LIBRARIES(MY_TARGET_NAME ${@PROJECT_NAME@_LIBS}) +# +# This file will define the following variables: +# - @PROJECT_NAME@_LIBS : The list of libraries to links against. +# - @PROJECT_NAME@_LIB_DIR : The directory where lib files are. Calling LINK_DIRECTORIES +# with this path is NOT needed. +# - @PROJECT_NAME@_VERSION : The version of this PROJECT_NAME build. Example: "1.2.0" +# - @PROJECT_NAME@_VERSION_MAJOR : Major version part of VERSION. Example: "1" +# - @PROJECT_NAME@_VERSION_MINOR : Minor version part of VERSION. Example: "2" +# - @PROJECT_NAME@_VERSION_PATCH : Patch version part of VERSION. Example: "0" +# +# =================================================================================== +INCLUDE_DIRECTORIES(@REQUIRED_INC_DIR@;@CMAKE_INSTALL_PREFIX@/include) +LINK_DIRECTORIES("@CMAKE_INSTALL_PREFIX@/lib") + +SET(@PROJECT_NAME@_LIBS @REQUIRED_LIBRARIES@ @PROJECT_NAME@@PROJECT_DLLVERSION@) +SET(@PROJECT_NAME@_FOUND "YES") + +SET(@PROJECT_NAME@_CV_FOUND "@PROJECT_CV_CREATED_FLAG@") +SET(@PROJECT_NAME@_CV_LIBS @REQUIRED_LIBRARIES@ @PROJECT_NAME@@PROJECT_DLLVERSION@ @OpenCV_LIBS@ @PROJECT_NAME@_cv@PROJECT_DLLVERSION@) + +SET(@PROJECT_NAME@_VERSION @PROJECT_VERSION@) +SET(@PROJECT_NAME@_VERSION_MAJOR @PROJECT_VERSION_MAJOR@) +SET(@PROJECT_NAME@_VERSION_MINOR @PROJECT_VERSION_MINOR@) +SET(@PROJECT_NAME@_VERSION_PATCH @PROJECT_VERSION_PATCH@) diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/CMakeLists.txt b/external_src/raspicam-0.1.3/dependencies/mmal/CMakeLists.txt new file mode 100644 index 0000000..37ae757 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/CMakeLists.txt @@ -0,0 +1,46 @@ +# We support building both static and shared libraries +if (NOT DEFINED LIBRARY_TYPE) +set(LIBRARY_TYPE SHARED) +endif (NOT DEFINED LIBRARY_TYPE) + +add_definitions(-Wall -Werror) + +add_library(mmal SHARED util/mmal_util.c) + +add_subdirectory(core) +add_subdirectory(util) +add_subdirectory(vc) +add_subdirectory(components) +add_subdirectory(openmaxil) +add_subdirectory(client) + +target_link_libraries(mmal mmal_core mmal_util mmal_vc_client vcos mmal_components) + +install(TARGETS mmal DESTINATION lib) +install(FILES + mmal.h + mmal_buffer.h + mmal_clock.h + mmal_common.h + mmal_component.h + mmal_encodings.h + mmal_events.h + mmal_format.h + mmal_logging.h + mmal_metadata.h + mmal_parameters.h + mmal_parameters_audio.h + mmal_parameters_camera.h + mmal_parameters_clock.h + mmal_parameters_common.h + mmal_parameters_video.h + mmal_pool.h mmal_port.h + mmal_queue.h + mmal_types.h + DESTINATION include/interface/mmal +) + +# Test apps +if(BUILD_MMAL_APPS) +add_subdirectory(test) +endif(BUILD_MMAL_APPS) diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/client/CMakeLists.txt b/external_src/raspicam-0.1.3/dependencies/mmal/client/CMakeLists.txt new file mode 100644 index 0000000..58bdaed --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/client/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(brcmjpeg) diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/client/brcmjpeg/CMakeLists.txt b/external_src/raspicam-0.1.3/dependencies/mmal/client/brcmjpeg/CMakeLists.txt new file mode 100644 index 0000000..342a182 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/client/brcmjpeg/CMakeLists.txt @@ -0,0 +1,6 @@ +add_library(brcmjpeg SHARED brcmjpeg.c) +target_link_libraries(brcmjpeg mmal_core mmal_util mmal_vc_client) + +include_directories(../../../../host_applications/linux/libs/sm) +add_executable(brcmjpeg_test brcmjpeg_test.c) +target_link_libraries(brcmjpeg_test brcmjpeg vcsm vcos) diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/client/brcmjpeg/brcmjpeg.c b/external_src/raspicam-0.1.3/dependencies/mmal/client/brcmjpeg/brcmjpeg.c new file mode 100644 index 0000000..1fc4220 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/client/brcmjpeg/brcmjpeg.c @@ -0,0 +1,914 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. +*/ + +/** \file + * Jpeg encoder and decoder library using the hardware jpeg codec + */ + +#include "mmal.h" +#include "util/mmal_component_wrapper.h" +#include "util/mmal_util_params.h" +#include "mmal_logging.h" +#include "brcmjpeg.h" + +/******************************************************************************* +* Defines +*******************************************************************************/ +#define MMAL_COMPONENT_IMAGE_DECODE "vc.aggregator.pipeline:ril.image_decode:video_convert" +#define MMAL_COMPONENT_IMAGE_ENCODE "vc.ril.image_encode" + +#define ENABLE_SLICE_MODE 0 + +#define CHECK_MMAL_STATUS(status, jerr, msg, ...) \ + if (status != MMAL_SUCCESS) {LOG_ERROR(msg, ## __VA_ARGS__); \ + err = BRCMJPEG_ERROR_##jerr; goto error;} + +/******************************************************************************* +* Type definitions +*******************************************************************************/ +struct BRCMJPEG_T +{ + BRCMJPEG_TYPE_T type; + unsigned int ref_count; + unsigned int init; + + MMAL_WRAPPER_T *mmal; + unsigned int slice_height; + + VCOS_MUTEX_T lock; + VCOS_MUTEX_T process_lock; + VCOS_SEMAPHORE_T sema; +}; + +/******************************************************************************* +* Local prototypes +*******************************************************************************/ +static BRCMJPEG_STATUS_T brcmjpeg_init_encoder(BRCMJPEG_T *); +static BRCMJPEG_STATUS_T brcmjpeg_init_decoder(BRCMJPEG_T *); +static BRCMJPEG_STATUS_T brcmjpeg_configure_encoder(BRCMJPEG_T *, BRCMJPEG_REQUEST_T *); +static BRCMJPEG_STATUS_T brcmjpeg_configure_decoder(BRCMJPEG_T *, BRCMJPEG_REQUEST_T *); +static BRCMJPEG_STATUS_T brcmjpeg_encode(BRCMJPEG_T *, BRCMJPEG_REQUEST_T *); +static BRCMJPEG_STATUS_T brcmjpeg_decode(BRCMJPEG_T *, BRCMJPEG_REQUEST_T *); +static void brcmjpeg_destroy(BRCMJPEG_T *); + +static MMAL_FOURCC_T brcmjpeg_pixfmt_to_encoding(BRCMJPEG_PIXEL_FORMAT_T); +static unsigned int brcmjpeg_copy_pixels(uint8_t *out, unsigned int out_size, + const uint8_t *in, unsigned int in_size, BRCMJPEG_PIXEL_FORMAT_T fmt, + unsigned int out_width, unsigned int out_height, + unsigned int in_width, unsigned int in_height, + unsigned int line_offset, unsigned int convert_from); + +static BRCMJPEG_T *brcmjpeg_encoder = NULL; +static BRCMJPEG_T *brcmjpeg_decoder = NULL; + +/******************************************************************************* +* Platform specific code +*******************************************************************************/ +static VCOS_ONCE_T once = VCOS_ONCE_INIT; +static VCOS_MUTEX_T brcmjpeg_lock; + +static void brcmjpeg_init_once(void) +{ + vcos_mutex_create(&brcmjpeg_lock, VCOS_FUNCTION); +} + +#define LOCK() vcos_mutex_lock(&brcmjpeg_lock) +#define UNLOCK() vcos_mutex_unlock(&brcmjpeg_lock) +#define LOCK_COMP(ctx) vcos_mutex_lock(&(ctx)->lock) +#define UNLOCK_COMP(ctx) vcos_mutex_unlock(&(ctx)->lock) +#define LOCK_PROCESS(ctx) vcos_mutex_lock(&(ctx)->process_lock) +#define UNLOCK_PROCESS(ctx) vcos_mutex_unlock(&(ctx)->process_lock) +#define WAIT(ctx) vcos_semaphore_wait(&(ctx)->sema) +#define SIGNAL(ctx) vcos_semaphore_post(&(ctx)->sema) + +/******************************************************************************* +* Implementation +*******************************************************************************/ + +BRCMJPEG_STATUS_T brcmjpeg_create(BRCMJPEG_TYPE_T type, BRCMJPEG_T **ctx) +{ + BRCMJPEG_STATUS_T status = BRCMJPEG_SUCCESS; + BRCMJPEG_T **comp; + + if (type == BRCMJPEG_TYPE_ENCODER) + comp = &brcmjpeg_encoder; + else + comp = &brcmjpeg_decoder; + + vcos_once(&once, brcmjpeg_init_once); + LOCK(); + if (!*comp) + { + int init1, init2, init3; + *comp = calloc(sizeof(BRCMJPEG_T), 1); + if (!*comp) + { + UNLOCK(); + return BRCMJPEG_ERROR_NOMEM; + } + (*comp)->type = type; + init1 = vcos_mutex_create(&(*comp)->lock, "brcmjpeg lock") != VCOS_SUCCESS; + init2 = vcos_mutex_create(&(*comp)->process_lock, "brcmjpeg process lock") != VCOS_SUCCESS; + init3 = vcos_semaphore_create(&(*comp)->sema, "brcmjpeg sema", 0) != VCOS_SUCCESS; + if (init1 | init2 | init3) + { + if (init1) vcos_mutex_delete(&(*comp)->lock); + if (init2) vcos_mutex_delete(&(*comp)->process_lock); + if (init3) vcos_semaphore_delete(&(*comp)->sema); + free(comp); + UNLOCK(); + return BRCMJPEG_ERROR_NOMEM; + } + } + (*comp)->ref_count++; + UNLOCK(); + + LOCK_COMP(*comp); + if (!(*comp)->init) + { + if (type == BRCMJPEG_TYPE_ENCODER) + status = brcmjpeg_init_encoder(*comp); + else + status = brcmjpeg_init_decoder(*comp); + + (*comp)->init = status == BRCMJPEG_SUCCESS; + } + UNLOCK_COMP(*comp); + + if (status != BRCMJPEG_SUCCESS) + brcmjpeg_release(*comp); + + *ctx = *comp; + return status; +} + +void brcmjpeg_acquire(BRCMJPEG_T *ctx) +{ + LOCK_COMP(ctx); + ctx->ref_count++; + UNLOCK_COMP(ctx); +} + +void brcmjpeg_release(BRCMJPEG_T *ctx) +{ + LOCK_COMP(ctx); + if (--ctx->ref_count) + { + UNLOCK_COMP(ctx); + return; + } + + LOCK(); + if (ctx->type == BRCMJPEG_TYPE_ENCODER) + brcmjpeg_encoder = NULL; + else + brcmjpeg_decoder = NULL; + UNLOCK(); + UNLOCK_COMP(ctx); + + brcmjpeg_destroy(ctx); + return; +} + +BRCMJPEG_STATUS_T brcmjpeg_process(BRCMJPEG_T *ctx, BRCMJPEG_REQUEST_T *req) +{ + BRCMJPEG_STATUS_T status; + + /* Sanity check */ + if ((req->input && req->input_handle) || + (req->output && req->output_handle)) + { + LOG_ERROR("buffer pointer and handle both set (%p/%u %p/%u)", + req->input, req->input_handle, req->output, req->output_handle); + return BRCMJPEG_ERROR_REQUEST; + } + + LOCK_PROCESS(ctx); + if (ctx->type == BRCMJPEG_TYPE_ENCODER) + status = brcmjpeg_encode(ctx, req); + else + status = brcmjpeg_decode(ctx, req); + UNLOCK_PROCESS(ctx); + + return status; +} + +static void brcmjpeg_destroy(BRCMJPEG_T *ctx) +{ + if (ctx->mmal) + mmal_wrapper_destroy(ctx->mmal); + vcos_mutex_delete(&ctx->lock); + vcos_mutex_delete(&ctx->process_lock); + vcos_semaphore_delete(&ctx->sema); + free(ctx); +} + +static void brcmjpeg_mmal_cb(MMAL_WRAPPER_T *wrapper) +{ + BRCMJPEG_T *ctx = wrapper->user_data; + SIGNAL(ctx); +} + +static BRCMJPEG_STATUS_T brcmjpeg_init_encoder(BRCMJPEG_T *ctx) +{ + MMAL_STATUS_T status; + BRCMJPEG_STATUS_T err = BRCMJPEG_SUCCESS; + + /* Create encoder component */ + status = mmal_wrapper_create(&ctx->mmal, MMAL_COMPONENT_IMAGE_ENCODE); + CHECK_MMAL_STATUS(status, INIT, "failed to create encoder"); + ctx->mmal->user_data = ctx; + ctx->mmal->callback = brcmjpeg_mmal_cb; + + /* Configure things that won't change from encode to encode */ + mmal_port_parameter_set_boolean(ctx->mmal->control, + MMAL_PARAMETER_EXIF_DISABLE, MMAL_TRUE); + + ctx->mmal->output[0]->format->encoding = MMAL_ENCODING_JPEG; + status = mmal_port_format_commit(ctx->mmal->output[0]); + CHECK_MMAL_STATUS(status, INIT, "failed to commit output port format"); + + ctx->mmal->output[0]->buffer_size = ctx->mmal->output[0]->buffer_size_min; + ctx->mmal->output[0]->buffer_num = 3; + status = mmal_wrapper_port_enable(ctx->mmal->output[0], 0); + CHECK_MMAL_STATUS(status, INIT, "failed to enable output port"); + + LOG_DEBUG("encoder initialised (output chunk size %i)", + ctx->mmal->output[0]->buffer_size); + return BRCMJPEG_SUCCESS; + + error: + return err; +} + +static BRCMJPEG_STATUS_T brcmjpeg_init_decoder(BRCMJPEG_T *ctx) +{ + MMAL_STATUS_T status; + BRCMJPEG_STATUS_T err = BRCMJPEG_SUCCESS; + + /* Create decoder component */ + status = mmal_wrapper_create(&ctx->mmal, MMAL_COMPONENT_IMAGE_DECODE); + CHECK_MMAL_STATUS(status, INIT, "failed to create decoder"); + ctx->mmal->user_data = ctx; + ctx->mmal->callback = brcmjpeg_mmal_cb; + + /* Configure things that won't change from decode to decode */ + ctx->mmal->input[0]->format->encoding = MMAL_ENCODING_JPEG; + status = mmal_port_format_commit(ctx->mmal->input[0]); + CHECK_MMAL_STATUS(status, INIT, "failed to commit input port format"); + + ctx->mmal->input[0]->buffer_size = ctx->mmal->input[0]->buffer_size_min; + ctx->mmal->input[0]->buffer_num = 3; + status = mmal_wrapper_port_enable(ctx->mmal->input[0], 0); + CHECK_MMAL_STATUS(status, INIT, "failed to enable input port"); + + LOG_DEBUG("decoder initialised (input chunk size %i)", + ctx->mmal->input[0]->buffer_size); + return BRCMJPEG_SUCCESS; + + error: + return BRCMJPEG_ERROR_INIT; +} + +/* Configuration which needs to be done on a per encode basis */ +static BRCMJPEG_STATUS_T brcmjpeg_configure_encoder(BRCMJPEG_T *ctx, + BRCMJPEG_REQUEST_T *req) +{ + MMAL_STATUS_T status = MMAL_SUCCESS; + MMAL_FOURCC_T encoding = brcmjpeg_pixfmt_to_encoding(req->pixel_format); + MMAL_PORT_T *port_in; + BRCMJPEG_STATUS_T err = BRCMJPEG_SUCCESS; + MMAL_BOOL_T slice_mode = MMAL_FALSE; + + if (encoding == MMAL_ENCODING_UNKNOWN) + status = MMAL_EINVAL; + CHECK_MMAL_STATUS(status, INPUT_FORMAT, "format not supported (%i)", + req->pixel_format); + + if (!req->buffer_width) + req->buffer_width = req->width; + if (!req->buffer_height) + req->buffer_height = req->height; + if (req->buffer_width < req->width || req->buffer_height < req->height) + status = MMAL_EINVAL; + CHECK_MMAL_STATUS(status, INPUT_FORMAT, "invalid buffer width/height " + "(%i<=%i %i<=%i)", req->buffer_width, req->width, req->buffer_height, + req->height); + + ctx->slice_height = 0; + ctx->mmal->status = MMAL_SUCCESS; + port_in = ctx->mmal->input[0]; + + /* The input port needs to be re-configured to take into account + * the properties of the new frame to encode */ + if (port_in->is_enabled) + { + status = mmal_wrapper_port_disable(port_in); + CHECK_MMAL_STATUS(status, EXECUTE, "failed to disable input port"); + } + + port_in->format->encoding = encoding; + port_in->format->es->video.width = + port_in->format->es->video.crop.width = req->width; + port_in->format->es->video.height = + port_in->format->es->video.crop.height = req->height; + port_in->buffer_num = 1; + + if (!req->input_handle && + (port_in->format->encoding == MMAL_ENCODING_I420 || + port_in->format->encoding == MMAL_ENCODING_I422)) + { + if (port_in->format->encoding == MMAL_ENCODING_I420) + port_in->format->encoding = MMAL_ENCODING_I420_SLICE; + else if (port_in->format->encoding == MMAL_ENCODING_I422) + port_in->format->encoding = MMAL_ENCODING_I422_SLICE; + slice_mode = MMAL_TRUE; + port_in->buffer_num = 3; + } + + status = mmal_port_format_commit(port_in); + CHECK_MMAL_STATUS(status, INPUT_FORMAT, "failed to commit input port format"); + + ctx->slice_height = slice_mode ? 16 : port_in->format->es->video.height; + port_in->buffer_size = port_in->buffer_size_min; + + if (req->input_handle) + status = mmal_wrapper_port_enable(port_in, MMAL_WRAPPER_FLAG_PAYLOAD_USE_SHARED_MEMORY); + else + status = mmal_wrapper_port_enable(port_in, MMAL_WRAPPER_FLAG_PAYLOAD_ALLOCATE); + CHECK_MMAL_STATUS(status, EXECUTE, "failed to enable input port"); + + mmal_port_parameter_set_uint32(ctx->mmal->output[0], + MMAL_PARAMETER_JPEG_Q_FACTOR, req->quality); + + if (!ctx->mmal->output[0]->is_enabled) + { + status = mmal_wrapper_port_enable(ctx->mmal->output[0], 0); + CHECK_MMAL_STATUS(status, EXECUTE, "failed to enable output port"); + } + + LOG_DEBUG("encoder configured (%4.4s:%ux%u|%ux%u slice: %u)", + (char *)&port_in->format->encoding, + port_in->format->es->video.crop.width, port_in->format->es->video.crop.height, + port_in->format->es->video.width, port_in->format->es->video.height, + ctx->slice_height); + return BRCMJPEG_SUCCESS; + + error: + return err; +} + +/* Configuration which needs to be done on a per decode basis */ +static BRCMJPEG_STATUS_T brcmjpeg_configure_decoder(BRCMJPEG_T *ctx, + BRCMJPEG_REQUEST_T *req) +{ + MMAL_STATUS_T status = MMAL_SUCCESS; + MMAL_FOURCC_T encoding = brcmjpeg_pixfmt_to_encoding(req->pixel_format); + MMAL_PORT_T *port_out; + BRCMJPEG_STATUS_T err = BRCMJPEG_SUCCESS; + + if (encoding != MMAL_ENCODING_I420 && + encoding != MMAL_ENCODING_I422 && + encoding != MMAL_ENCODING_RGBA) + status = MMAL_EINVAL; + CHECK_MMAL_STATUS(status, OUTPUT_FORMAT, "format not supported"); + + ctx->slice_height = 0; + ctx->mmal->status = MMAL_SUCCESS; + port_out = ctx->mmal->output[0]; + + /* The input port needs to be re-configured to take into account + * the properties of the new frame to decode */ + if (port_out->is_enabled) + { + status = mmal_wrapper_port_disable(port_out); + CHECK_MMAL_STATUS(status, EXECUTE, "failed to disable output port"); + } + + /* We assume that we do not know the format of the new jpeg to be decoded + * and configure the input port for autodetecting the new format */ + port_out->format->encoding = encoding; + port_out->format->es->video.width = + port_out->format->es->video.crop.width = 0; + port_out->format->es->video.height = + port_out->format->es->video.crop.height = 0; + status = mmal_port_format_commit(port_out); + CHECK_MMAL_STATUS(status, OUTPUT_FORMAT, "failed to commit output port format"); + + port_out->buffer_num = 1; + if (req->output_handle) + status = mmal_wrapper_port_enable(port_out, MMAL_WRAPPER_FLAG_PAYLOAD_USE_SHARED_MEMORY); + else + status = mmal_wrapper_port_enable(port_out, MMAL_WRAPPER_FLAG_PAYLOAD_ALLOCATE); + CHECK_MMAL_STATUS(status, EXECUTE, "failed to enable output port"); + + LOG_DEBUG("decoder configured (%4.4s:%ux%u|%ux%u)", (char *)&port_out->format->encoding, + port_out->format->es->video.crop.width, port_out->format->es->video.crop.height, + port_out->format->es->video.width, port_out->format->es->video.height); + return BRCMJPEG_SUCCESS; + + error: + return err; +} + +static BRCMJPEG_STATUS_T brcmjpeg_encode(BRCMJPEG_T *ctx, + BRCMJPEG_REQUEST_T *je) +{ + BRCMJPEG_STATUS_T err; + MMAL_STATUS_T status = MMAL_SUCCESS; + MMAL_BUFFER_HEADER_T *in, *out; + MMAL_BOOL_T eos = MMAL_FALSE; + const uint8_t *outBuf = je->output; + unsigned int loop = 0, slices = 0, outBufSize = je->output_alloc_size; + MMAL_PORT_T *port_in = ctx->mmal->input[0]; + MMAL_PORT_T *port_out = ctx->mmal->output[0]; + + je->output_size = 0; + err = brcmjpeg_configure_encoder(ctx, je); + if (err != BRCMJPEG_SUCCESS) + return err; + + /* Then we read the encoded data back from the encoder */ + + while (!eos && status == MMAL_SUCCESS) + { + /* send buffers to be filled */ + while (mmal_wrapper_buffer_get_empty(port_out, &out, 0) == MMAL_SUCCESS) + { + out->data = (uint8_t *)outBuf; + out->alloc_size = MMAL_MIN(port_out->buffer_size, outBufSize); + outBufSize -= out->alloc_size; + outBuf += out->alloc_size; + status = mmal_port_send_buffer(port_out, out); + CHECK_MMAL_STATUS(status, EXECUTE, "failed to send buffer"); + } + + /* Send slices to be encoded */ + if (slices * ctx->slice_height < port_in->format->es->video.height && + mmal_wrapper_buffer_get_empty(port_in, &in, 0) == MMAL_SUCCESS) + { + if (je->input_handle) + { + in->data = (uint8_t *)je->input_handle; + in->length = in->alloc_size = je->input_size; + } + else + { + in->length = brcmjpeg_copy_pixels(in->data, in->alloc_size, + je->input, je->input_size, je->pixel_format, + port_in->format->es->video.width, + ctx->slice_height, je->buffer_width, je->buffer_height, + slices * ctx->slice_height, 1); + if (!in->length) + status = MMAL_EINVAL; + CHECK_MMAL_STATUS(status, INPUT_BUFFER, "input buffer too small"); + } + + slices++; + if (slices * ctx->slice_height >= port_in->format->es->video.height) + in->flags = MMAL_BUFFER_HEADER_FLAG_EOS; + status = mmal_port_send_buffer(port_in, in); + CHECK_MMAL_STATUS(status, EXECUTE, "failed to send buffer"); + } + + status = mmal_wrapper_buffer_get_full(port_out, &out, 0); + if (status == MMAL_EAGAIN) + { + status = MMAL_SUCCESS; + WAIT(ctx); + continue; + } + CHECK_MMAL_STATUS(status, EXECUTE, "failed to get full buffer"); + + LOG_DEBUG("received %i bytes", out->length); + je->output_size += out->length; + eos = out->flags & MMAL_BUFFER_HEADER_FLAG_EOS; + + /* Detect when the encoder is running out of space for its output */ + if (++loop >= port_out->buffer_num && !eos && !out->length) + { + LOG_ERROR("no more output space for encoder"); + status = MMAL_EINVAL; + } + + mmal_buffer_header_release(out); + } + + /* Check if buffer was too small */ + CHECK_MMAL_STATUS(status, OUTPUT_BUFFER, "output buffer too small"); + + LOG_DEBUG("encoded W:%ixH:%i:%i (%i bytes) in %i slices", + je->width, je->height, je->pixel_format, je->output_size, slices); + mmal_port_flush(port_out); + return BRCMJPEG_SUCCESS; + + error: + mmal_wrapper_port_disable(port_in); + mmal_wrapper_port_disable(port_out); + return err; +} + +static BRCMJPEG_STATUS_T brcmjpeg_decode(BRCMJPEG_T *ctx, + BRCMJPEG_REQUEST_T *jd) +{ + BRCMJPEG_STATUS_T err; + MMAL_STATUS_T status; + MMAL_BUFFER_HEADER_T *in, *out; + MMAL_BOOL_T eos = MMAL_FALSE; + const uint8_t *inBuf = jd->input; + unsigned int slices = 0, inBufSize = jd->input_size; + MMAL_PORT_T *port_in = ctx->mmal->input[0]; + MMAL_PORT_T *port_out = ctx->mmal->output[0]; + LOG_DEBUG("decode %i bytes", jd->input_size); + + jd->output_size = 0; + err = brcmjpeg_configure_decoder(ctx, jd); + if (err != BRCMJPEG_SUCCESS) + return err; + + while (!eos) + { + /* Send as many chunks of data to decode as we can */ + while (inBufSize) + { + status = mmal_wrapper_buffer_get_empty(port_in, &in, 0); + if (status == MMAL_EAGAIN) + break; + CHECK_MMAL_STATUS(status, EXECUTE, "failed to get empty buffer (%i)", status); + + in->data = (uint8_t *)inBuf; + in->length = MMAL_MIN(port_in->buffer_size, inBufSize); + in->alloc_size = in->length; + inBufSize -= in->length; + inBuf += in->length; + in->flags = inBufSize ? 0 : MMAL_BUFFER_HEADER_FLAG_EOS; + LOG_DEBUG("send decode in (%i bytes)", in->length); + status = mmal_port_send_buffer(port_in, in); + CHECK_MMAL_STATUS(status, EXECUTE, "failed to send input buffer"); + } + + /* Check for decoded data */ + status = mmal_wrapper_buffer_get_full(port_out, &out, 0); + if (status == MMAL_EAGAIN) + { + WAIT(ctx); + continue; + } + CHECK_MMAL_STATUS(status, EXECUTE, "error decoding"); + + /* Check if a new format has been auto-detected by the decoder */ + if (out->cmd == MMAL_EVENT_FORMAT_CHANGED) + { + MMAL_EVENT_FORMAT_CHANGED_T *event = mmal_event_format_changed_get(out); + + if (event) + mmal_format_copy(port_out->format, event->format); + mmal_buffer_header_release(out); + + if (!event) + status = MMAL_EINVAL; + CHECK_MMAL_STATUS(status, EXECUTE, "invalid format change event"); + + LOG_DEBUG("new format (%4.4s:%ux%u|%ux%u)", (char *)&event->format->encoding, + event->format->es->video.crop.width, event->format->es->video.crop.height, + event->format->es->video.width, event->format->es->video.height); + + /* re-setup the output port for the new format */ + status = mmal_wrapper_port_disable(port_out); + CHECK_MMAL_STATUS(status, EXECUTE, "failed to disable output port"); + + ctx->slice_height = event->format->es->video.height; + if (ENABLE_SLICE_MODE && !jd->output_handle) + { + /* setup slice mode */ + if (port_out->format->encoding == MMAL_ENCODING_I420 || + port_out->format->encoding == MMAL_ENCODING_I422) + { + if (port_out->format->encoding == MMAL_ENCODING_I420) + port_out->format->encoding = MMAL_ENCODING_I420_SLICE; + if (port_out->format->encoding == MMAL_ENCODING_I422) + port_out->format->encoding = MMAL_ENCODING_I422_SLICE; + ctx->slice_height = 16; + port_out->buffer_num = 3; + } + } + + LOG_DEBUG("using slice size %u", ctx->slice_height); + status = mmal_port_format_commit(port_out); + CHECK_MMAL_STATUS(status, EXECUTE, "invalid format change event"); + port_out->buffer_size = port_out->buffer_size_min; + if (jd->output_handle) + status = mmal_wrapper_port_enable(port_out, MMAL_WRAPPER_FLAG_PAYLOAD_USE_SHARED_MEMORY); + else + status = mmal_wrapper_port_enable(port_out, MMAL_WRAPPER_FLAG_PAYLOAD_ALLOCATE); + CHECK_MMAL_STATUS(status, EXECUTE, "failed to enable output port"); + + /* send all our output buffers to the decoder */ + while (mmal_wrapper_buffer_get_empty(port_out, &out, 0) == MMAL_SUCCESS) + { + if (jd->output_handle) + { + out->data = (uint8_t*)jd->output_handle; + out->alloc_size = jd->output_alloc_size; + } + status = mmal_port_send_buffer(port_out, out); + CHECK_MMAL_STATUS(status, EXECUTE, "failed to send output buffer"); + } + + continue; + } + + /* We have part of our output frame */ + jd->width = port_out->format->es->video.crop.width; + if (!jd->width) + jd->width = port_out->format->es->video.width; + if (jd->output_handle) + jd->buffer_width = port_out->format->es->video.width; + if (!jd->buffer_width) + jd->buffer_width = jd->width; + jd->height = port_out->format->es->video.crop.height; + if (!jd->height) + jd->height = port_out->format->es->video.height; + if (jd->output_handle) + jd->buffer_height = port_out->format->es->video.height; + if (!jd->buffer_height) + jd->buffer_height = jd->height; + + if (jd->output_handle) + { + jd->output_size += out->length; + } + else + { + jd->output_size = brcmjpeg_copy_pixels(jd->output, jd->output_alloc_size, + out->data, out->length, jd->pixel_format, + jd->buffer_width, jd->buffer_height, + port_out->format->es->video.width, + ctx->slice_height, slices * ctx->slice_height, 0); + slices++; + } + + eos = out->flags & MMAL_BUFFER_HEADER_FLAG_EOS; + out->length = 0; + if (eos) + { + mmal_buffer_header_release(out); + } + else + { + status = mmal_port_send_buffer(port_out, out); + CHECK_MMAL_STATUS(status, EXECUTE, "failed to send output buffer"); + } + + if (!jd->output_size) + status = MMAL_EINVAL; + CHECK_MMAL_STATUS(status, OUTPUT_BUFFER, "invalid output buffer"); + } + + LOG_DEBUG("decoded W:%ixH%i:(W%ixH%i):%i in %i slices", + jd->width, jd->height, jd->buffer_width, jd->buffer_height, + jd->pixel_format, slices); + mmal_port_flush(port_in); + return BRCMJPEG_SUCCESS; + + error: + mmal_port_flush(port_in); + return err; +} + +/*****************************************************************************/ +static struct { + BRCMJPEG_PIXEL_FORMAT_T pixel_format; + MMAL_FOURCC_T encoding; +} mmal_raw_conversion[] = { + {PIXEL_FORMAT_I420, MMAL_ENCODING_I420}, + {PIXEL_FORMAT_YV12, MMAL_ENCODING_I420}, + {PIXEL_FORMAT_I422, MMAL_ENCODING_I422}, + {PIXEL_FORMAT_YV16, MMAL_ENCODING_I422}, + {PIXEL_FORMAT_YUYV, MMAL_ENCODING_I422}, + {PIXEL_FORMAT_RGBA, MMAL_ENCODING_RGBA}, + {PIXEL_FORMAT_UNKNOWN, MMAL_ENCODING_UNKNOWN} }; + +static MMAL_FOURCC_T brcmjpeg_pixfmt_to_encoding(BRCMJPEG_PIXEL_FORMAT_T pixel_format) +{ + unsigned int i; + for (i = 0; mmal_raw_conversion[i].encoding != MMAL_ENCODING_UNKNOWN; i++) + if (mmal_raw_conversion[i].pixel_format == pixel_format) + break; + return mmal_raw_conversion[i].encoding; +} + +// Copy a raw frame from 1 buffer to another, taking care of +// stride / height differences between the input and output buffers. +static unsigned int brcmjpeg_copy_pixels(uint8_t *out, unsigned int out_size, + const uint8_t *in, unsigned int in_size, BRCMJPEG_PIXEL_FORMAT_T fmt, + unsigned int out_width, unsigned int out_height, + unsigned int in_width, unsigned int in_height, + unsigned int line_offset, unsigned int convert_from) +{ + struct { + uint8_t *data; + unsigned int pitch; + unsigned int height; + } planes[2][3]; + unsigned int num_planes = 0; + unsigned int i, size = 0; + unsigned int in_height_full = in_height; + unsigned int out_height_full = out_height; + unsigned int k = convert_from ? 1 : 0; + + // Sanity check line_offset + if (line_offset >= (convert_from ? in_height : out_height)) + return 0; + + if (convert_from) + in_height -= line_offset; + else + out_height -= line_offset; + + if (fmt == PIXEL_FORMAT_I420 || + fmt == PIXEL_FORMAT_YV12) + { + planes[0][0].data = out; + planes[0][0].pitch = out_width; + planes[0][0].height = out_height; + + planes[1][0].data = (uint8_t *)in; + planes[1][0].pitch = in_width; + planes[1][0].height = in_height; + + planes[0][1].pitch = planes[0][2].pitch = out_width / 2; + planes[0][1].height = planes[0][2].height = out_height / 2; + planes[0][1].data = planes[0][0].data + out_width * out_height_full; + planes[0][2].data = planes[0][1].data + out_width * out_height_full / 4; + + planes[1][1].pitch = planes[1][2].pitch = in_width / 2; + planes[1][1].height = planes[1][2].height = in_height / 2; + planes[1][1].data = planes[1][0].data + in_width * in_height_full; + planes[1][2].data = planes[1][1].data + in_width * in_height_full / 4; + + if (fmt == PIXEL_FORMAT_YV12) + { + // We need to swap U and V + uint8_t *tmp = planes[1][2].data; + planes[1][2].data = planes[1][1].data; + planes[1][1].data = tmp; + } + + // Add the line offset + planes[k][0].data += planes[k][0].pitch * line_offset; + planes[k][1].data += planes[k][1].pitch * line_offset/2; + planes[k][2].data += planes[k][2].pitch * line_offset/2; + + num_planes = 3; + size = out_width * out_height_full * 3 / 2; + + if (in_size < in_width * in_height * 3 / 2) + return 0; + + } else if (fmt == PIXEL_FORMAT_I422 || + fmt == PIXEL_FORMAT_YV16 || + fmt == PIXEL_FORMAT_YUYV) + { + planes[0][0].data = out; + planes[0][0].pitch = out_width; + planes[0][0].height = out_height; + + planes[1][0].data = (uint8_t *)in; + planes[1][0].pitch = in_width; + planes[1][0].height = in_height; + + planes[0][1].pitch = planes[0][2].pitch = out_width / 2; + planes[0][1].height = planes[0][2].height = out_height; + planes[0][1].data = planes[0][0].data + out_width * out_height_full; + planes[0][2].data = planes[0][1].data + out_width * out_height_full / 2; + + planes[1][1].pitch = planes[1][2].pitch = in_width / 2; + planes[1][1].height = planes[1][2].height = in_height; + planes[1][1].data = planes[1][0].data + in_width * in_height_full; + planes[1][2].data = planes[1][1].data + in_width * in_height_full / 2; + + // Add the line offset + planes[k][0].data += planes[k][0].pitch * line_offset; + planes[k][1].data += planes[k][1].pitch * line_offset; + planes[k][2].data += planes[k][2].pitch * line_offset; + if (fmt == PIXEL_FORMAT_YUYV) + planes[k][0].data += planes[k][0].pitch * line_offset; + + if (fmt == PIXEL_FORMAT_YV16) + { + // We need to swap U and V + uint8_t *tmp = planes[1][2].data; + planes[1][2].data = planes[1][1].data; + planes[1][1].data = tmp; + } + + num_planes = 3; + size = out_width * out_height_full * 2; + + if (in_size < in_width * in_height * 2) + return 0; + } else if (fmt == PIXEL_FORMAT_RGBA) + { + planes[0][0].data = out; + planes[0][0].pitch = out_width * 4; + planes[0][0].height = out_height; + + planes[1][0].data = (uint8_t *)in; + planes[1][0].pitch = in_width * 4; + planes[1][0].height = in_height; + + // Add the line offset + planes[k][0].data += planes[k][0].pitch * line_offset; + + num_planes = 1; + size = out_width * out_height_full * 4; + + if (in_size < in_width * in_height * 4) + return 0; + } + + if (out_size < size) + return 0; + + // Special case for YUYV where don't just copy but convert to/from I422 + if (fmt == PIXEL_FORMAT_YUYV) + { + unsigned int width = in_width > out_width ? out_width : in_width; + unsigned int height = in_height > out_height ? out_height : in_height; + uint8_t *y = planes[convert_from ? 0 : 1][0].data; + uint8_t *u = planes[convert_from ? 0 : 1][1].data; + uint8_t *v = planes[convert_from ? 0 : 1][2].data; + uint8_t *yuyv = planes[convert_from ? 1 : 0][0].data; + unsigned int y_diff = (convert_from ? out_width : in_width) - width; + unsigned int yuyv_diff = ((convert_from ? in_width : out_width) - width) * 2; + + while (height--) + { + if (convert_from) + for (i = width / 2; i; i--) + { + *y++ = *yuyv++; + *u++ = *yuyv++; + *y++ = *yuyv++; + *v++ = *yuyv++; + } + else + for (i = width / 2; i; i--) + { + *yuyv++ = *y++; + *yuyv++ = *u++; + *yuyv++ = *y++; + *yuyv++ = *v++; + } + + yuyv += yuyv_diff; + y += y_diff; + u += y_diff >> 1; + v += y_diff >> 1; + } + + return size; + } + + for (i = 0; i < num_planes; i++) + { + unsigned int width = MMAL_MIN(planes[0][i].pitch, planes[1][i].pitch); + unsigned int height = MMAL_MIN(planes[0][i].height, planes[1][i].height); + uint8_t *data_out = planes[0][i].data; + uint8_t *data_in = planes[1][i].data; + + while (height--) + { + memcpy(data_out, data_in, width); + data_out += planes[0][i].pitch; + data_in += planes[1][i].pitch; + } + } + + return size; +} diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/client/brcmjpeg/brcmjpeg.h b/external_src/raspicam-0.1.3/dependencies/mmal/client/brcmjpeg/brcmjpeg.h new file mode 100644 index 0000000..d787e99 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/client/brcmjpeg/brcmjpeg.h @@ -0,0 +1,152 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. +*/ + +/** \file + * Jpeg encoder and decoder library using the hardware jpeg codec + */ + +#ifndef BRCM_JPEG_H +#define BRCM_JPEG_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** Status return codes from the API */ +typedef enum +{ + BRCMJPEG_SUCCESS = 0, + BRCMJPEG_ERROR_NOMEM, + BRCMJPEG_ERROR_INIT, + BRCMJPEG_ERROR_INPUT_FORMAT, + BRCMJPEG_ERROR_OUTPUT_FORMAT, + BRCMJPEG_ERROR_INPUT_BUFFER, + BRCMJPEG_ERROR_OUTPUT_BUFFER, + BRCMJPEG_ERROR_EXECUTE, + BRCMJPEG_ERROR_REQUEST, +} BRCMJPEG_STATUS_T; + +/** Type of the codec instance to create */ +typedef enum +{ + BRCMJPEG_TYPE_ENCODER = 0, + BRCMJPEG_TYPE_DECODER +} BRCMJPEG_TYPE_T; + +/** Pixel formats supported by the codec */ +typedef enum +{ + PIXEL_FORMAT_UNKNOWN = 0, + PIXEL_FORMAT_I420, /* planar YUV 4:2:0 */ + PIXEL_FORMAT_YV12, /* planar YVU 4:2:0 */ + PIXEL_FORMAT_I422, /* planar YUV 4:2:2 */ + PIXEL_FORMAT_YV16, /* planar YVU 4:2:2 */ + PIXEL_FORMAT_YUYV, /* interleaved YUV 4:2:2 */ + PIXEL_FORMAT_RGBA, /* interleaved RGBA */ +} BRCMJPEG_PIXEL_FORMAT_T; + +/** Definition of a codec request */ +typedef struct +{ + /** Pointer to the buffer containing the input data + * A client should set input OR input_handle, but not both. */ + const unsigned char *input; + /** Actual size of the input data */ + unsigned int input_size; + /** Handle to input buffer containing input data */ + unsigned int input_handle; + + /** Pointer to the buffer used for the output data + * A client should set output OR output_handle, but not both. */ + unsigned char *output; + /** Total size of the output buffer */ + unsigned int output_alloc_size; + /** Actual size of the output data (this is an output parameter) */ + unsigned int output_size; + /** Handle to the buffer used for the output data */ + unsigned int output_handle; + + /** Width of the raw frame (this is an input parameter for encode) */ + unsigned int width; + /** Height of the raw frame (this is an input parameter for encode) */ + unsigned int height; + /** Pixel format of the raw frame (this is an input parameter) */ + BRCMJPEG_PIXEL_FORMAT_T pixel_format; + + /** Width of the buffer containing the raw frame (input parameter). + * This is optional but if set, is used to specify the actual width + * of the buffer containing the raw frame */ + unsigned int buffer_width; + /** Height of the buffer containing the raw frame (input parameter). + * This is optional but if set, is used to specify the actual height + * of the buffer containing the raw frame */ + unsigned int buffer_height; + + /** Encode quality - 0 to 100 */ + unsigned int quality; +} BRCMJPEG_REQUEST_T; + +/** Type of the codec instance */ +typedef struct BRCMJPEG_T BRCMJPEG_T; + +/** Create an instance of the jpeg codec + * This will actually re-use an existing instance if one is + * available. + * + * @param type type of codec instance required + * @param ctx will point to the newly created instance + * @return BRCMJPEG_SUCCESS on success + */ +BRCMJPEG_STATUS_T brcmjpeg_create(BRCMJPEG_TYPE_T type, BRCMJPEG_T **ctx); + +/** Acquire a new reference on a codec instance + * + * @param ctx instance to acquire a reference on + */ +void brcmjpeg_acquire(BRCMJPEG_T *ctx); + +/** Release an instance of the jpeg codec + * This will only trigger the destruction of the codec instance when + * the last reference to it is being released. + * + * @param ctx instance to release + */ +void brcmjpeg_release(BRCMJPEG_T *ctx); + +/** Process a jpeg codec request + * + * @param ctx instance of codec to use + * @param request codec request to execute + * @return BRCMJPEG_SUCCESS on success + */ +BRCMJPEG_STATUS_T brcmjpeg_process(BRCMJPEG_T *ctx, BRCMJPEG_REQUEST_T *request); + +#ifdef __cplusplus +} +#endif + +#endif /* BRCM_JPEG_H */ diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/client/brcmjpeg/brcmjpeg_test.c b/external_src/raspicam-0.1.3/dependencies/mmal/client/brcmjpeg/brcmjpeg_test.c new file mode 100644 index 0000000..9e249b6 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/client/brcmjpeg/brcmjpeg_test.c @@ -0,0 +1,236 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 "brcmjpeg.h" +#include +#include +#include +#include +#include +#include +#include + +#define MAX_WIDTH 5000 +#define MAX_HEIGHT 5000 +#define MAX_ENCODED (15*1024*1024) +#define MAX_DECODED (MAX_WIDTH*MAX_HEIGHT*2) + +static uint8_t encodedInBuf[MAX_ENCODED]; +static uint8_t encodedOutBuf[MAX_ENCODED]; +static uint8_t decodedBuf[MAX_DECODED]; +static char outFileName[2048]; + +int64_t get_time_microsec(void) +{ + struct timeval now; + gettimeofday(&now, NULL); + return now.tv_sec * 1000000LL + now.tv_usec; +} + +int main(int argc, char **argv) +{ + BRCMJPEG_STATUS_T status; + BRCMJPEG_REQUEST_T enc_request, dec_request; + BRCMJPEG_T *enc = 0, *dec = 0; + int64_t start, stop, time_dec = 0, time_enc = 0; + unsigned int count = 1, format = PIXEL_FORMAT_YUYV; + unsigned int use_vcsm = 0, handle = 0, vc_handle = 0; + int i, arg = 1, help = 0; + + // Parse command line arguments + while (arg < argc && argv[arg][0] == '-') + { + if (!strcmp(argv[arg], "-n")) + { + if (++arg >= argc || sscanf(argv[arg++], "%u", &count) != 1) + arg = argc; + } + else if (!strcmp(argv[arg], "-f")) + { + if (++arg >= argc || sscanf(argv[arg++], "%u", &format) != 1) + arg = argc; + } + else if (!strcmp(argv[arg], "-s")) + { + use_vcsm = 1; + arg++; + } + else if (!strcmp(argv[arg], "-h")) + { + help = 1; + break; + } + else + { + arg = argc; + } + } + + if (arg == argc || help) + { + if (!help) fprintf(stderr, "invalid arguments\n"); + fprintf(stderr, "usage: %s [options] file1 ... fileN\n", argv[0]); + fprintf(stderr, "options list:\n"); + fprintf(stderr, " -h : help\n"); + fprintf(stderr, " -n : process each file N times\n"); + fprintf(stderr, " -f : force color format\n"); + fprintf(stderr, " -s : use shared-memory for intermediate buffer\n"); + return !help; + } + + if (use_vcsm) + { + if (vcsm_init() < 0) + { + fprintf(stderr, "failed to initialise vcsm\n"); + return 1; + } + + handle = vcsm_malloc_cache(MAX_DECODED, VCSM_CACHE_TYPE_HOST, "brcmjpeg-test"); + if (!handle) + { + fprintf(stderr, "failed to alloc vcsm buffer\n"); + vcsm_exit(); + return 1; + } + + vc_handle = vcsm_vc_hdl_from_hdl(handle); + + fprintf(stderr, "decodedBuf handle %u vc_handle %u\n", handle, vc_handle); + } + + // Setup of the dec / enc requests + memset(&enc_request, 0, sizeof(enc_request)); + memset(&dec_request, 0, sizeof(dec_request)); + dec_request.input = encodedInBuf; + dec_request.output = use_vcsm ? NULL : decodedBuf; + dec_request.output_handle = use_vcsm ? vc_handle : 0; + dec_request.output_alloc_size = MAX_DECODED; + enc_request.input = dec_request.output; + enc_request.input_handle = dec_request.output_handle; + enc_request.output = encodedOutBuf; + enc_request.output_alloc_size = sizeof(encodedOutBuf); + enc_request.quality = 75; + enc_request.pixel_format = dec_request.pixel_format = format; + + status = brcmjpeg_create(BRCMJPEG_TYPE_ENCODER, &enc); + if (status != BRCMJPEG_SUCCESS) + { + fprintf(stderr, "could not create encoder\n"); + return 1; + } + status = brcmjpeg_create(BRCMJPEG_TYPE_DECODER, &dec); + if (status != BRCMJPEG_SUCCESS) + { + fprintf(stderr, "could not create decoder\n"); + brcmjpeg_release(enc); + return 1; + } + + for (i = arg; i < argc; i++) + { + unsigned int j; + fprintf(stderr, "processing %s\n", argv[i]); + + FILE *file_in = fopen(argv[i], "rb"); + if (!file_in) { + fprintf(stderr, "could not open file %s\n", argv[i]); + continue; + } + snprintf(outFileName, sizeof(outFileName), "%s.out", argv[i]); + FILE *file_out = fopen(outFileName, "wb+"); + if (!file_out) { + fprintf(stderr, "could not open file %s\n", outFileName); + fclose(file_in); + continue; + } + dec_request.input_size = fread(encodedInBuf, 1, sizeof(encodedInBuf), file_in); + + for (j = 0; j < count; j++) + { + dec_request.buffer_width = 0; + dec_request.buffer_height = 0; + + start = get_time_microsec(); + status = brcmjpeg_process(dec, &dec_request); + stop = get_time_microsec(); + if (status != BRCMJPEG_SUCCESS) { + fprintf(stderr, "could not decode %s\n", argv[i]); + break; + } + + fprintf(stderr, "decoded %ix%i(%ix%i), %i bytes in %lldus\n", + dec_request.width, dec_request.height, + dec_request.buffer_width, dec_request.buffer_height, + dec_request.input_size, stop - start); + time_dec += stop - start; + + enc_request.input_size = dec_request.output_size; + enc_request.width = dec_request.width; + enc_request.height = dec_request.height; + enc_request.buffer_width = dec_request.buffer_width; + enc_request.buffer_height = dec_request.buffer_height; + + start = get_time_microsec(); + status = brcmjpeg_process(enc, &enc_request); + stop = get_time_microsec(); + if (status != BRCMJPEG_SUCCESS) { + fprintf(stderr, "could not encode %s\n", outFileName); + break; + } + + fprintf(stderr, "encoded %ix%i(%ix%i), %i bytes in %lldus\n", + enc_request.width, enc_request.height, + enc_request.buffer_width, enc_request.buffer_height, + enc_request.output_size, stop - start); + time_enc += stop - start; + } + + if (status != BRCMJPEG_SUCCESS) + continue; + + fwrite(enc_request.output, 1, enc_request.output_size, file_out); + fclose(file_out); + fclose(file_in); + + fprintf(stderr, "decode times %lldus (%lldus per run)\n", + time_dec, time_dec / count); + fprintf(stderr, "encode times %lldus (%lldus per run)\n", + time_enc, time_enc / count); + } + + brcmjpeg_release(dec); + brcmjpeg_release(enc); + + if (use_vcsm) + { + vcsm_free(handle); + vcsm_exit(); + } + + return 0; +} diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/components/CMakeLists.txt b/external_src/raspicam-0.1.3/dependencies/mmal/components/CMakeLists.txt new file mode 100644 index 0000000..d65fa37 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/components/CMakeLists.txt @@ -0,0 +1,34 @@ +add_library(mmal_components ${LIBRARY_TYPE} + container_reader.c + null_sink.c + passthrough.c + scheduler.c + splitter.c + copy.c + artificial_camera.c + aggregator.c + clock.c + spdif.c + ) + +set(extra_components_SRCS avcodec_video_decoder.c avcodec_audio_decoder.c + sdl_video_render.c sdl_audio_render.c aaf_audio_render.cpp android_media_codec.cpp) + +#target_link_libraries(mmal_components avcodec avutil) +#target_link_libraries(mmal_components SDL) +#if (WIN32) +#target_link_libraries(mmal_components avcore avutil z) # For avcodec +#target_link_libraries(mmal_components gdi32 winmm) # For SDL +#endif (WIN32) + +add_custom_target(mmal_components_extra ALL + COMMAND touch ${extra_components_SRCS} + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/interface/mmal/components) + +set(container_libs ${container_libs} containers) + +target_link_libraries(mmal_components ${container_libs} mmal_util) +target_link_libraries(mmal_components mmal_core) + +install(TARGETS mmal_components DESTINATION lib) + diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/components/aaf_audio_render.cpp b/external_src/raspicam-0.1.3/dependencies/mmal/components/aaf_audio_render.cpp new file mode 100644 index 0000000..32b5d6d --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/components/aaf_audio_render.cpp @@ -0,0 +1,504 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 "mmal.h" +#include "mmal_logging.h" +#include "core/mmal_component_private.h" +#include "core/mmal_port_private.h" +#include "core/mmal_clock_private.h" + +#include +#include + +using namespace android; + +/* Buffering requirements */ +#define INPUT_MIN_BUFFER_NUM 4 +#define INPUT_RECOMMENDED_BUFFER_NUM 8 + +#define SPDIF_AC3_FRAME_SIZE 6144 + +/*****************************************************************************/ +enum TRACK_STATE_T { + TRACK_STATE_STOPPED, + TRACK_STATE_RUNNING, + TRACK_STATE_PAUSED +}; + +typedef struct MMAL_COMPONENT_MODULE_T +{ + MMAL_STATUS_T status; + MMAL_QUEUE_T *queue; + + android::sp track; + + Mutex *lock; + uint32_t bytes_queued; + + MMAL_BOOL_T is_enabled; + TRACK_STATE_T state; + + MMAL_ES_FORMAT_T *format; /**< format currently configured */ + +} MMAL_COMPONENT_MODULE_T; + +/*****************************************************************************/ + +static void aaf_track_callback(int event, void *user, void *info); + +static struct encoding_table_t { + MMAL_FOURCC_T encoding; + audio_format_t format; +} encoding_list[] = +{ {MMAL_ENCODING_PCM_SIGNED, AUDIO_FORMAT_PCM_16_BIT}, +#ifdef ANDROID_SUPPORTS_AC3 + {MMAL_ENCODING_AC3, AUDIO_FORMAT_AC3_SPDIF}, + {MMAL_ENCODING_EAC3, AUDIO_FORMAT_EAC3_SPDIF}, +#endif + {0, AUDIO_FORMAT_INVALID} +}; + +static audio_format_t encoding_to_audio_format(MMAL_FOURCC_T encoding) +{ + struct encoding_table_t *entry = encoding_list; + + for (entry = encoding_list; entry->encoding; entry++) + if (entry->encoding == encoding) + break; + + return entry->format; +} + +static void aaf_track_destroy(MMAL_COMPONENT_T *component) +{ + MMAL_COMPONENT_MODULE_T *module = component->priv->module; + + if (module->track != NULL) + { + module->track->stop(); + module->track = NULL; + } +} + +static MMAL_STATUS_T aaf_track_create(MMAL_COMPONENT_T *component) +{ + MMAL_COMPONENT_MODULE_T *module = component->priv->module; + MMAL_PORT_T *port = component->input[0]; + audio_channel_mask_t channels_mask; + int frame_count = 256; + + /* Reset track on format change. Can do better than that? */ + if (module->track != NULL) + aaf_track_destroy(component); + + channels_mask = audio_channel_out_mask_from_count(port->format->es->audio.channels); + LOG_INFO("%s(%p) %4.4s, %i Hz, mask %x, chan %i", port->name, port, + (char *)&port->format->encoding, + (int)port->format->es->audio.sample_rate, channels_mask, + (int)port->format->es->audio.channels); + + AudioTrack::getMinFrameCount(&frame_count); + if (port->format->encoding == MMAL_ENCODING_AC3) + frame_count = SPDIF_AC3_FRAME_SIZE; + else if (port->format->encoding == MMAL_ENCODING_EAC3) + frame_count = SPDIF_AC3_FRAME_SIZE * 4; + frame_count *= 2; /* Twice the minimum should be enough */ + + module->track = new AudioTrack(AUDIO_STREAM_MUSIC, + port->format->es->audio.sample_rate, + encoding_to_audio_format(port->format->encoding), channels_mask, + frame_count, port->format->encoding == MMAL_ENCODING_PCM_SIGNED ? + AUDIO_OUTPUT_FLAG_NONE : AUDIO_OUTPUT_FLAG_DIRECT, + &aaf_track_callback, port, 0); + + if (module->track == NULL || module->track->initCheck() != OK) + { + LOG_ERROR("%s(%p): track creation failed", port->name, port); + module->track = NULL; + return MMAL_ENOSYS; + } + + return MMAL_SUCCESS; +} + +static void aaf_track_callback(int event, void *user, void *info) +{ + MMAL_PORT_T *port = (MMAL_PORT_T *)user; + MMAL_COMPONENT_T *component = port->component; + MMAL_COMPONENT_MODULE_T *module = component->priv->module; + MMAL_BUFFER_HEADER_T *buffer; + AudioTrack::Buffer *trackbuf = NULL; + unsigned int bytes, space; + uint8_t *dest; + + if (event == AudioTrack::EVENT_UNDERRUN) + LOG_ERROR("underrun"); + + if (event != AudioTrack::EVENT_MORE_DATA) + return; + + trackbuf = (AudioTrack::Buffer *)info; + space = trackbuf->size; + dest = (uint8_t *)trackbuf->raw; + trackbuf->size = 0; + + if (!mmal_queue_length(module->queue)) + { + LOG_ERROR("no buffers queued"); + return; + } + + while (space > 0) + { + buffer = mmal_queue_get(module->queue); + if (!buffer) + break; + + bytes = MMAL_MIN(buffer->length, space); + memcpy(dest, buffer->data + buffer->offset, bytes); + buffer->offset += bytes; + buffer->length -= bytes; + dest += bytes; + space -= bytes; + trackbuf->size += bytes; + + if (buffer->length) + { + /* Re-queue */ + mmal_queue_put_back(module->queue, buffer); + continue; + } + + /* Handle the EOS */ + if (buffer->flags & MMAL_BUFFER_HEADER_FLAG_EOS) + mmal_event_eos_send(port); + + buffer->offset = 0; + mmal_port_buffer_header_callback(port, buffer); + } + + module->lock->lock(); + module->bytes_queued -= trackbuf->size; + module->lock->unlock(); +} + +static MMAL_STATUS_T aaf_track_state_update(MMAL_COMPONENT_T *component) +{ + MMAL_COMPONENT_MODULE_T *module = component->priv->module; + TRACK_STATE_T new_state = TRACK_STATE_STOPPED; + + if (module->track == NULL) + return MMAL_SUCCESS; + + if (module->is_enabled) + { + MMAL_RATIONAL_T scale = mmal_port_clock_scale_get(component->clock[0]); + new_state = TRACK_STATE_PAUSED; + if (scale.den && scale.den == scale.num) + new_state = TRACK_STATE_RUNNING; + } + + if (new_state == module->state) + return MMAL_SUCCESS; /* Nothing to do */ + + if (module->state == TRACK_STATE_STOPPED && new_state == TRACK_STATE_RUNNING) + { + module->track->start(); + } + else if (module->state == TRACK_STATE_RUNNING) + { + if (new_state == TRACK_STATE_STOPPED) + module->track->stop(); + else if (new_state == TRACK_STATE_PAUSED) + module->track->pause(); + } + else if (module->state == TRACK_STATE_PAUSED) + { + if (new_state == TRACK_STATE_STOPPED) + module->track->stop(); + else if (new_state == TRACK_STATE_RUNNING) + module->track->start(); + } + + module->state = new_state; + return MMAL_SUCCESS; +} + +/** Destroy a previously created component */ +static MMAL_STATUS_T aaf_component_destroy(MMAL_COMPONENT_T *component) +{ + MMAL_COMPONENT_MODULE_T *module = component->priv->module; + + aaf_track_destroy(component); + + if(component->input_num) + mmal_ports_free(component->input, component->input_num); + if(component->clock_num) + mmal_ports_clock_free(component->clock, component->clock_num); + if(module->format) + mmal_format_free(module->format); + if(module->queue) + mmal_queue_destroy(module->queue); + delete module->lock; + vcos_free(module); + return MMAL_SUCCESS; +} + +/** Set format on a port */ +static MMAL_STATUS_T aaf_port_set_format(MMAL_PORT_T *port) +{ + MMAL_COMPONENT_T *component = port->component; + + if (!mmal_format_compare(port->format, component->priv->module->format)) + return MMAL_SUCCESS; + + /* Check the format is supported */ + if (encoding_to_audio_format(port->format->encoding) == AUDIO_FORMAT_INVALID) + { + LOG_ERROR("port does not support '%4.4s'", (char *)&port->format->encoding); + return MMAL_EINVAL; + } + + /* Specific checks for PCM */ + if (port->format->encoding == MMAL_ENCODING_PCM_SIGNED) + { + + if (port->format->es->audio.bits_per_sample != 16 && + port->format->es->audio.bits_per_sample != 32) + { + LOG_ERROR("port does not support '%4.4s' at %ibps", + (char *)&port->format->encoding, + port->format->es->audio.bits_per_sample); + return MMAL_EINVAL; + } + + if (!audio_channel_out_mask_from_count(port->format->es->audio.channels)) + { + LOG_ERROR("%s invalid channels mask from %i", port->name, + (int)port->format->es->audio.channels); + return MMAL_ENOSYS; + } + } + + mmal_format_copy(component->priv->module->format, port->format); + + return aaf_track_create(component); +} + +/** Enable processing on a port */ +static MMAL_STATUS_T aaf_port_enable(MMAL_PORT_T *port, MMAL_PORT_BH_CB_T cb) +{ + MMAL_COMPONENT_T *component = port->component; + MMAL_COMPONENT_MODULE_T *module = component->priv->module; + MMAL_STATUS_T status = MMAL_SUCCESS; + MMAL_PARAM_UNUSED(cb); + + if (module->track == NULL) + status = aaf_port_set_format(port); + if (status != MMAL_SUCCESS) + return status; + + module->is_enabled = MMAL_TRUE; + aaf_track_state_update(component); + return MMAL_SUCCESS; +} + +/** Flush a port */ +static MMAL_STATUS_T aaf_port_flush(MMAL_PORT_T *port) +{ + MMAL_COMPONENT_T *component = port->component; + MMAL_COMPONENT_MODULE_T *module = component->priv->module; + MMAL_BUFFER_HEADER_T *buffer; + + while((buffer = mmal_queue_get(module->queue))) + mmal_port_buffer_header_callback(port, buffer); + + module->lock->lock(); + module->bytes_queued = 0; + module->lock->unlock(); + + if (module->track == NULL) + return MMAL_SUCCESS; + + module->track->stop(); + module->track->flush(); + module->state = TRACK_STATE_STOPPED; + aaf_track_state_update(component); + return MMAL_SUCCESS; +} + +/** Disable processing on a port */ +static MMAL_STATUS_T aaf_port_disable(MMAL_PORT_T *port) +{ + MMAL_COMPONENT_T *component = port->component; + MMAL_COMPONENT_MODULE_T *module = component->priv->module; + + module->is_enabled = MMAL_FALSE; + aaf_track_state_update(component); + + return aaf_port_flush(port); +} + +static MMAL_STATUS_T aaf_port_send(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) +{ + MMAL_COMPONENT_T *component = port->component; + MMAL_COMPONENT_MODULE_T *module = component->priv->module; + unsigned int bits_per_sample, channels, sample_rate; + uint32_t aaf_bytes_queued = 0; + int64_t latency, ts; + + /* Handle event buffers */ + if (buffer->cmd) + { + LOG_ERROR("discarding event %i on port %p", (int)buffer->cmd, port); + buffer->length = 0; + mmal_port_buffer_header_callback(port, buffer); + return MMAL_SUCCESS; + } + + if (module->status != MMAL_SUCCESS) + return module->status; + + bits_per_sample = port->format->es->audio.bits_per_sample; + channels = port->format->es->audio.channels; + sample_rate = port->format->es->audio.sample_rate; + + if (port->format->encoding == MMAL_ENCODING_AC3 || + port->format->encoding == MMAL_ENCODING_EAC3) + { + uint32_t aaf_latency = 0; + AudioSystem::getOutputLatency(&aaf_latency, AUDIO_STREAM_MUSIC); + latency = aaf_latency * 1000LL; + + bits_per_sample = 16; + channels = 2; + if (port->format->encoding == MMAL_ENCODING_EAC3 && + sample_rate <= 48000) + sample_rate *= 4; + aaf_bytes_queued = module->track->frameCount(); + } + else + { + latency = module->track->latency() * 1000LL; + } + + /* Keep aaf_track_callback from sending more samples */ + module->lock->lock(); + + module->bytes_queued += buffer->length; + latency += (module->bytes_queued + aaf_bytes_queued) / channels / + (bits_per_sample / 8) * 1000000LL / sample_rate; + ts = buffer->pts - latency; + + module->lock->unlock(); + + mmal_port_clock_media_time_set(component->clock[0], ts); + + mmal_queue_put(module->queue, buffer); + + return MMAL_SUCCESS; +} + +void aaf_clock_event(MMAL_PORT_T *port, const MMAL_CLOCK_EVENT_T *event) +{ + MMAL_COMPONENT_T *component = port->component; + + switch (event->id) + { + case MMAL_CLOCK_EVENT_SCALE: + aaf_track_state_update(component); + break; + case MMAL_CLOCK_EVENT_TIME: + case MMAL_CLOCK_EVENT_REFERENCE: + case MMAL_CLOCK_EVENT_ACTIVE: + /* nothing to do */ + break; + default: + LOG_DEBUG("unknown event id %4.4s", (char*)&event->id); + break; + } +} + +/** Create an instance of a component */ +static MMAL_STATUS_T mmal_component_create_aaf(const char *name, MMAL_COMPONENT_T *component) +{ + MMAL_COMPONENT_MODULE_T *module; + + /* Check we're the requested component */ + if(strcmp(name, "aaf." MMAL_AUDIO_RENDER)) + return MMAL_ENOENT; + + /* Allocate our module context */ + component->priv->module = module = (MMAL_COMPONENT_MODULE_T *)vcos_calloc(1, sizeof(*module), "mmal module"); + if(!module) + return MMAL_ENOMEM; + module->lock = new Mutex(); + if (!module->lock) + goto error; + + /* Allocate the ports for this component */ + component->input = mmal_ports_alloc(component, 1, MMAL_PORT_TYPE_INPUT, 0); + if(!component->input) + goto error; + component->input_num = 1; + + /* Create the clock port (clock ports are managed by the framework) */ + component->clock = mmal_ports_clock_alloc(component, 1, 0, aaf_clock_event); + if (!component->clock) + goto error; + component->clock_num = 1; + + module->queue = mmal_queue_create(); + if(!module->queue) + goto error; + + module->format = mmal_format_alloc(); + if(!module->format) + goto error; + + component->input[0]->priv->pf_set_format = aaf_port_set_format; + component->input[0]->priv->pf_enable = aaf_port_enable; + component->input[0]->priv->pf_disable = aaf_port_disable; + component->input[0]->priv->pf_flush = aaf_port_flush; + component->input[0]->priv->pf_send = aaf_port_send; + component->input[0]->buffer_num_min = INPUT_MIN_BUFFER_NUM; + component->input[0]->buffer_num_recommended = INPUT_RECOMMENDED_BUFFER_NUM; + component->input[0]->format->type = MMAL_ES_TYPE_AUDIO; + + component->priv->pf_destroy = aaf_component_destroy; + return MMAL_SUCCESS; + + error: + aaf_component_destroy(component); + return MMAL_ENOMEM; +} + +MMAL_CONSTRUCTOR(mmal_register_component_aaf_audio); +void mmal_register_component_aaf_audio(void) +{ + mmal_component_supplier_register("aaf", mmal_component_create_aaf); +} diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/components/aggregator.c b/external_src/raspicam-0.1.3/dependencies/mmal/components/aggregator.c new file mode 100644 index 0000000..fac4596 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/components/aggregator.c @@ -0,0 +1,188 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 "mmal.h" +#include "core/mmal_component_private.h" +#include "core/mmal_port_private.h" +#include "util/mmal_graph.h" +#include "mmal_logging.h" + +#define AGGREGATOR_PREFIX "aggregator" +#define AGGREGATOR_PIPELINE_PREFIX "pipeline" + +typedef struct MMAL_GRAPH_USERDATA_T { + int dummy; +} MMAL_GRAPH_USERDATA_T; + +static MMAL_STATUS_T aggregator_parameter_set(MMAL_GRAPH_T *graph, + MMAL_PORT_T *port, const MMAL_PARAMETER_HEADER_T *param) +{ + MMAL_PARAM_UNUSED(graph); + MMAL_PARAM_UNUSED(port); + MMAL_PARAM_UNUSED(param); + LOG_TRACE("graph %p, port %p, param %p", graph, port, param); + return MMAL_ENOSYS; +} + +static MMAL_STATUS_T aggregator_parameter_get(MMAL_GRAPH_T *graph, + MMAL_PORT_T *port, MMAL_PARAMETER_HEADER_T *param) +{ + MMAL_PARAM_UNUSED(graph); + MMAL_PARAM_UNUSED(port); + MMAL_PARAM_UNUSED(param); + LOG_TRACE("graph %p, port %p, param %p", graph, port, param); + return MMAL_ENOSYS; +} + +/** Create an instance of a component */ +static MMAL_STATUS_T mmal_component_create_aggregator_pipeline(const char *full_name, + const char *component_names, MMAL_COMPONENT_T *component) +{ + MMAL_GRAPH_T *graph = 0; + MMAL_COMPONENT_T *subcomponent[2] = {0}; + MMAL_STATUS_T status = MMAL_ENOMEM; + unsigned int length; + char *orig, *names; + + length = strlen(component_names); + names = orig = vcos_calloc(1, length + 1, "mmal aggregator"); + if (!names) + goto error; + memcpy(names, component_names, length); + + /* We'll build the aggregator using a graph */ + status = mmal_graph_create(&graph, sizeof(MMAL_GRAPH_USERDATA_T)); + if (status != MMAL_SUCCESS) + goto error; + graph->pf_parameter_get = aggregator_parameter_get; + graph->pf_parameter_set = aggregator_parameter_set; + + /* Iterate through all the specified components */ + while (*names) + { + MMAL_CONNECTION_T *connection; + const char *name; + + /* Switch to a new connection */ + if (subcomponent[0]) + mmal_component_destroy(subcomponent[0]); + subcomponent[0] = subcomponent[1]; + subcomponent[1] = 0; + + /* Extract the name of the next component */ + for (name = names; *names && *names != ':'; names++); + + /* Replace the separator */ + if (*names) + *(names++) = 0; + + /* Skip empty strings */ + if (!*name) + continue; + + status = mmal_component_create(name, &subcomponent[1]); + if (status != MMAL_SUCCESS) + goto error; + + status = mmal_graph_add_component(graph, subcomponent[1]); + if (status != MMAL_SUCCESS) + goto error; + + /* Special case for dealing with the first component in the chain */ + if (!subcomponent[0]) + { + /* Add first input port if any */ + if (subcomponent[1]->input_num) + { + status = mmal_graph_add_port(graph, subcomponent[1]->input[0]); + if (status != MMAL_SUCCESS) + goto error; + } + continue; + } + + /* Create connection between the 2 ports */ + if (subcomponent[0]->output_num < 1 || subcomponent[1]->input_num < 1) + goto error; + status = mmal_connection_create(&connection, subcomponent[0]->output[0], + subcomponent[1]->input[0], 0); + if (status != MMAL_SUCCESS) + goto error; + + status = mmal_graph_add_connection(graph, connection); + /* Now the connection is added to the graph we don't care about it anymore */ + mmal_connection_destroy(connection); + if (status != MMAL_SUCCESS) + goto error; + } + + /* Add last output port if any */ + if (subcomponent[1] && subcomponent[1]->output_num && subcomponent[1]->output[0]) + { + status = mmal_graph_add_port(graph, subcomponent[1]->output[0]); + if (status != MMAL_SUCCESS) + goto error; + } + + /* Build the graph */ + component->priv->module = (struct MMAL_COMPONENT_MODULE_T *)graph; + status = mmal_graph_component_constructor(full_name, component); + if (status != MMAL_SUCCESS) + goto error; + + end: + if (subcomponent[0]) + mmal_component_destroy(subcomponent[0]); + if (subcomponent[1]) + mmal_component_destroy(subcomponent[1]); + vcos_free(orig); + return status; + + error: + if (graph) + mmal_graph_destroy(graph); + goto end; +} + +/** Create an instance of a component */ +static MMAL_STATUS_T mmal_component_create_aggregator(const char *name, MMAL_COMPONENT_T *component) +{ + const char *stripped = name + sizeof(AGGREGATOR_PREFIX); + + /* Select the requested aggregator */ + if (!strncmp(stripped, AGGREGATOR_PIPELINE_PREFIX ":", sizeof(AGGREGATOR_PIPELINE_PREFIX))) + return mmal_component_create_aggregator_pipeline(name, + stripped + sizeof(AGGREGATOR_PIPELINE_PREFIX), component); + + return MMAL_ENOSYS; +} + +MMAL_CONSTRUCTOR(mmal_register_component_aggregator); +void mmal_register_component_aggregator(void) +{ + mmal_component_supplier_register(AGGREGATOR_PREFIX, mmal_component_create_aggregator); +} diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/components/android_media_codec.cpp b/external_src/raspicam-0.1.3/dependencies/mmal/components/android_media_codec.cpp new file mode 100644 index 0000000..8877a52 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/components/android_media_codec.cpp @@ -0,0 +1,861 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 "mmal.h" +#include "core/mmal_component_private.h" +#include "core/mmal_port_private.h" +#include "mmal_logging.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace android; + +/* List of variants supported by this component */ +#define AMC_VARIANT_UNKNOWN 0 +#define AMC_VARIANT_AUDIO_DECODE 1 +#define AMC_VARIANT_AUDIO_DECODE_NAME "audio_decode" + +/*****************************************************************************/ +struct AmcHandler : public AHandler +{ + AmcHandler(MMAL_COMPONENT_T *component) : + mComponent(component), mNotificationRequested(false) {} + + void requestNotification(sp &codec) + { + if (mActivityNotify == NULL) + mActivityNotify = new AMessage(0, id()); + + if (!mNotificationRequested) + { + mNotificationRequested = true; + codec->requestActivityNotification(mActivityNotify->dup()); + } + } + + void reset() + { + mNotificationRequested = false; + } + +protected: + virtual void onMessageReceived(const sp &msg) + { + (void)msg; + mNotificationRequested = false; + mmal_component_action_trigger(mComponent); + } + +private: + MMAL_COMPONENT_T *mComponent; + sp mActivityNotify; + bool mNotificationRequested; +}; + +typedef struct MMAL_COMPONENT_MODULE_T +{ + MMAL_STATUS_T status; /**< current status of the component */ + + sp codec; + sp ahandler; + sp alooper; + Vector > input_buffers; /**< list of buffers exported by mediacodec */ + Vector > output_buffers; /**< list of buffers exported by mediacodec */ + +} MMAL_COMPONENT_MODULE_T; + +typedef struct MMAL_PORT_MODULE_T +{ + MMAL_ES_FORMAT_T *format; /**< format currently configured */ + MMAL_QUEUE_T *queue; /**< queue for the buffers sent to the ports */ + MMAL_BOOL_T needs_configuring; /**< port is waiting for a format commit */ + + List *dequeued; /* buffers already dequeued from the codec */ + + const char *mime; + unsigned int actual_channels; + +} MMAL_PORT_MODULE_T; + +static struct encoding_table_t { + const char *mime; + MMAL_FOURCC_T encoding; + MMAL_ES_TYPE_T type; + MMAL_FOURCC_T encoding_variant; +} encoding_list[] = +{ {"audio/3gpp", MMAL_ENCODING_AMRNB, MMAL_ES_TYPE_AUDIO, 0}, + {"audio/amr-wb", MMAL_ENCODING_AMRWB, MMAL_ES_TYPE_AUDIO, 0}, + {"audio/mpeg", MMAL_ENCODING_MPGA, MMAL_ES_TYPE_AUDIO, 0}, + {"audio/mp4a-latm", MMAL_ENCODING_MP4A, MMAL_ES_TYPE_AUDIO, 0}, + {"audio/mp4a-latm", MMAL_ENCODING_MP4A, MMAL_ES_TYPE_AUDIO, MMAL_ENCODING_VARIANT_MP4A_ADTS}, + {"audio/vorbis", MMAL_ENCODING_VORBIS, MMAL_ES_TYPE_AUDIO, 0}, + {"audio/g711-alaw", MMAL_ENCODING_ALAW, MMAL_ES_TYPE_AUDIO, 0}, + {"audio/g711-ulaw", MMAL_ENCODING_MULAW, MMAL_ES_TYPE_AUDIO, 0}, + {"audio/ac3", MMAL_ENCODING_AC3, MMAL_ES_TYPE_AUDIO, 0}, + {"audio/ec3", MMAL_ENCODING_EAC3, MMAL_ES_TYPE_AUDIO, 0}, + {"audio/eac3", MMAL_ENCODING_EAC3, MMAL_ES_TYPE_AUDIO, 0}, + {"audio/raw", MMAL_ENCODING_PCM_SIGNED, MMAL_ES_TYPE_AUDIO, 0}, + {"", MMAL_ENCODING_PCM_SIGNED, MMAL_ES_TYPE_AUDIO, 0}, + { 0, 0, MMAL_ES_TYPE_UNKNOWN, 0} +}; + +static const char *encoding_to_mime(MMAL_ES_TYPE_T type, MMAL_FOURCC_T encoding, + MMAL_FOURCC_T encoding_variant) +{ + struct encoding_table_t *entry = encoding_list; + + for (entry = encoding_list; entry->mime; entry++) + if (entry->encoding == encoding && entry->type == type && + entry->encoding_variant == encoding_variant) + break; + + return entry->mime; +} + +static void mime_to_encoding(const char *mime, + MMAL_ES_TYPE_T *type, MMAL_FOURCC_T *encoding, MMAL_FOURCC_T *encoding_variant) +{ + struct encoding_table_t *entry = encoding_list; + + for (entry = encoding_list; entry->mime; entry++) + if (!strcmp(mime, entry->mime)) + break; + + *encoding = entry->encoding; + *type = entry->type; + *encoding_variant = entry->encoding_variant; +} + +/*****************************************************************************/ + +/** Actual processing functions */ +static MMAL_BOOL_T amc_do_input_processing(MMAL_COMPONENT_T *component, + MMAL_BOOL_T *notification) +{ + MMAL_COMPONENT_MODULE_T *module = component->priv->module; + MMAL_PORT_T *port = component->input[0]; + MMAL_PORT_MODULE_T *port_module = port->priv->module; + MMAL_BUFFER_HEADER_T *in; + status_t astatus; + size_t size, index; + uint32_t flags = 0; + + in = mmal_queue_get(port_module->queue); + + /* Get an input buffer from the codec. We dequeue input buffers even + * if we do not any data to process to make sure that we do not get + * flooded with notifications from the codec that buffers are + * available. */ + if (port_module->dequeued->empty() || !in) + { + astatus = module->codec->dequeueInputBuffer(&index, 0ll); + if (astatus == OK) + { + LOG_TRACE("dequeueInputBuffer %i", index); + port_module->dequeued->push_back(index); + } + else if (astatus != -EAGAIN) + { + LOG_TRACE("dequeueInputBuffer failed (%i)", astatus); + } + } + + /* Check whether we can process data */ + if (!in) + { + return 0; + } + else if (port_module->dequeued->empty()) + { + mmal_queue_put_back(port_module->queue, in); + + /* We have data we want to process so request to be notified as soon + * as the codec is available to process it */ + *notification |= MMAL_TRUE; + + return 0; + } + + /* We have some processing to do */ + + index = *port_module->dequeued->begin(); + sp inBuf = module->input_buffers.itemAt(index); + if (inBuf->capacity() < in->length) + LOG_ERROR("MediaCodec input buffer too small (%i/%i)", + (int)inBuf->capacity(), (int)in->length); + size = MMAL_MIN(inBuf->capacity(), in->length); + + if (in->length) + memcpy(inBuf->data(), in->data + in->offset, size); + if (in->flags & MMAL_BUFFER_HEADER_FLAG_EOS) + flags |= MediaCodec::BUFFER_FLAG_EOS; + if (in->flags & MMAL_BUFFER_HEADER_FLAG_KEYFRAME) + flags |= MediaCodec::BUFFER_FLAG_SYNCFRAME; + if (in->flags & MMAL_BUFFER_HEADER_FLAG_CONFIG) + flags |= MediaCodec::BUFFER_FLAG_CODECCONFIG; + + LOG_TRACE("queueInputBuffer %i %ibytes, %lldus", index, in->length, in->pts); + astatus = module->codec->queueInputBuffer(index, 0, size, in->pts, flags); + if (astatus != OK) + { + LOG_ERROR("queueInputBuffer failed (%i)", astatus); + mmal_event_error_send(component, MMAL_EIO); + module->status = MMAL_EIO; + } + + /* Send buffers back */ + in->length = 0; + mmal_port_buffer_header_callback(port, in); + port_module->dequeued->erase(port_module->dequeued->begin()); + + return 1; +} + +static void amc_output_format_changed(MMAL_COMPONENT_T *component) +{ + MMAL_COMPONENT_MODULE_T *module = component->priv->module; + MMAL_PORT_T *port = component->output[0]; + MMAL_EVENT_FORMAT_CHANGED_T *event; + MMAL_BUFFER_HEADER_T *buffer; + MMAL_STATUS_T status; + int32_t value; + + sp format = new AMessage; + status_t astatus = module->codec->getOutputFormat(&format); + LOG_DEBUG("INFO_FORMAT_CHANGED (%i): %s", astatus, + format->debugString().c_str()); + + /* Get an event buffer */ + status = mmal_port_event_get(port, &buffer, MMAL_EVENT_FORMAT_CHANGED); + if (status != MMAL_SUCCESS) + { + LOG_ERROR("unable to get an event buffer"); + return; + } + event = mmal_event_format_changed_get(buffer); + + AString amime; + format->findString("mime", &amime); + mime_to_encoding(amime.c_str(), + &event->format->type, &event->format->encoding, + &event->format->encoding_variant); + + switch (port->format->type) + { + case MMAL_ES_TYPE_VIDEO: + if (format->findInt32("width", &value)) + event->format->es->video.width = value; + if (format->findInt32("height", &value)) + event->format->es->video.height = value; + break; + case MMAL_ES_TYPE_AUDIO: + if (format->findInt32("channel-count", &value)) + event->format->es->audio.channels = value; + if (format->findInt32("sample-rate", &value)) + event->format->es->audio.sample_rate = value; + if (format->findInt32("bitrate", &value)) + event->format->bitrate = value; + if (event->format->encoding == MMAL_ENCODING_PCM_SIGNED) + event->format->es->audio.bits_per_sample = 16; + break; + default: + break; + } + + /* Work-around for the ril audio_render component which only supports + * power of 2 arrangements */ + if (event->format->type == MMAL_ES_TYPE_AUDIO && + event->format->encoding == MMAL_ENCODING_PCM_SIGNED) + { + port->priv->module->actual_channels = event->format->es->audio.channels; + if (event->format->es->audio.channels == 6) + event->format->es->audio.channels = 8; + } + + /* Update current format */ + mmal_format_copy(port->priv->module->format, event->format); + + /* Pass on the buffer requirements */ + event->buffer_num_min = port->buffer_num_min; + event->buffer_size_min = port->buffer_size_min; + event->buffer_size_recommended = port->buffer_size_recommended; + event->buffer_num_recommended = port->buffer_num_recommended; + + mmal_port_event_send(port, buffer); +} + +static MMAL_BOOL_T amc_do_output_processing(MMAL_COMPONENT_T *component, + MMAL_BOOL_T *notification) +{ + MMAL_COMPONENT_MODULE_T *module = component->priv->module; + MMAL_PORT_T *port_out = component->output[0]; + MMAL_BUFFER_HEADER_T *out; + status_t astatus; + size_t size, offset, index; + int64_t pts; + uint32_t flags; + + if (port_out->priv->module->needs_configuring) + return 0; + + out = mmal_queue_get(port_out->priv->module->queue); + if (!out) + { + /* We do not want notifications in that case. We've already filled + * our output buffers so we should really wait to receive more + * output buffers before resuming the processing */ + *notification = MMAL_FALSE; + return 0; + } + out->flags = 0; + + astatus = module->codec->dequeueOutputBuffer(&index, &offset, &size, &pts, &flags, 0ll); + if (astatus != OK) + { + MMAL_BOOL_T do_more = 0; + + switch (astatus) + { + case INFO_OUTPUT_BUFFERS_CHANGED: + LOG_DEBUG("INFO_OUTPUT_BUFFERS_CHANGED"); + astatus = module->codec->getOutputBuffers(&module->output_buffers); + do_more = MMAL_TRUE; + break; + case INFO_FORMAT_CHANGED: + amc_output_format_changed(component); + port_out->priv->module->needs_configuring = 1; + do_more = MMAL_TRUE; + break; + case -EAGAIN: + /* We have data we want to process so request to be notified as soon + * as the codec is available to process it */ + *notification |= MMAL_TRUE; + break; + default: + LOG_ERROR("dequeueOutputBuffer failed (%i)", astatus); + } + + mmal_queue_put_back(port_out->priv->module->queue, out); + return do_more; + } + + LOG_TRACE("dequeueOutputBuffer %i, %ibytes, %lldus, flags %x", + index, size, pts, flags); + sp outBuf = module->output_buffers.itemAt(index); + + out->flags = 0; + out->offset = 0; + out->pts = pts; + out->dts = 0; + + if (flags & MediaCodec::BUFFER_FLAG_EOS) + out->flags |= MMAL_BUFFER_HEADER_FLAG_EOS; + if (flags & MediaCodec::BUFFER_FLAG_SYNCFRAME) + out->flags |= MMAL_BUFFER_HEADER_FLAG_KEYFRAME; + if (flags & MediaCodec::BUFFER_FLAG_CODECCONFIG) + out->flags |= MMAL_BUFFER_HEADER_FLAG_CONFIG; + + if (out->alloc_size < size) + LOG_ERROR("MediaCodec output buffer too big (%i/%i)", + (int)out->alloc_size, (int)size); + size = MMAL_MIN(out->alloc_size, size); + + /* Audio render only accepts power of 2 channel configurations */ + if (port_out->format->type == MMAL_ES_TYPE_AUDIO && + port_out->format->encoding == MMAL_ENCODING_PCM_SIGNED && + port_out->priv->module->actual_channels != + port_out->format->es->audio.channels) + { + unsigned int valid = port_out->priv->module->actual_channels * 2; + unsigned int pitch = port_out->format->es->audio.channels * 2; + uint8_t *src = outBuf->data() + offset; + uint8_t *dst = out->data; + unsigned int i; + + size = size * port_out->format->es->audio.channels / + port_out->priv->module->actual_channels; + size = MMAL_MIN(out->alloc_size, size); + memset(dst, 0, size); + for (i = size / pitch; i; i--, src += valid, dst += pitch) + memcpy(dst, src, valid); + } + else if (size) + memcpy(out->data, outBuf->data() + offset, size); + out->length = size; + + /* Send buffers back */ + module->codec->releaseOutputBuffer(index); + mmal_port_buffer_header_callback(port_out, out); + + return 1; +} + +static MMAL_BOOL_T amc_do_processing(MMAL_COMPONENT_T *component) +{ + MMAL_COMPONENT_MODULE_T *module = component->priv->module; + MMAL_BOOL_T do_more, request_notification = MMAL_FALSE; + + if (module->codec == NULL) + return 0; + + /* Don't do anything if we've already seen an error */ + if (module->status != MMAL_SUCCESS) + return 0; + + do_more = amc_do_input_processing(component, &request_notification); + do_more |= amc_do_output_processing(component, &request_notification); + + if (request_notification) + module->ahandler->requestNotification(module->codec); + + return do_more; +} + +/*****************************************************************************/ +static void amc_do_processing_loop(MMAL_COMPONENT_T *component) +{ + while (amc_do_processing(component)); +} + +/** Destroy a previously created component */ +static MMAL_STATUS_T amc_component_destroy(MMAL_COMPONENT_T *component) +{ + MMAL_COMPONENT_MODULE_T *module = component->priv->module; + unsigned int i; + + for(i = 0; i < component->input_num; i++) + { + if(component->input[i]->priv->module->queue) + mmal_queue_destroy(component->input[i]->priv->module->queue); + if(component->input[i]->priv->module->format) + mmal_format_free(component->input[i]->priv->module->format); + if(component->input[i]->priv->module->dequeued) + delete component->input[i]->priv->module->dequeued; + } + if(component->input_num) + mmal_ports_free(component->input, component->input_num); + + for(i = 0; i < component->output_num; i++) + { + if(component->output[i]->priv->module->queue) + mmal_queue_destroy(component->output[i]->priv->module->queue); + if(component->output[i]->priv->module->format) + mmal_format_free(component->output[i]->priv->module->format); + } + if(component->output_num) + mmal_ports_free(component->output, component->output_num); + + if (module->codec != NULL) + { + module->codec->stop(); + module->codec->release(); + } + + module->alooper->unregisterHandler(module->ahandler->id()); + module->alooper->stop(); + delete module; + return MMAL_SUCCESS; +} + +static MMAL_STATUS_T amc_codec_start(MMAL_COMPONENT_T *component) +{ + MMAL_COMPONENT_MODULE_T *module = component->priv->module; + MMAL_PORT_T *in = component->input[0]; + sp format = new AMessage; + status_t astatus; + const char *mime; + + mime = encoding_to_mime(in->format->type, in->format->encoding, + in->format->encoding_variant); + if (!mime) + { + LOG_ERROR("cannot match codec %4.4s(%4.4s) with a mime type", + (char *)&in->format->encoding, (char *)&in->format->encoding_variant); + return MMAL_EINVAL; + } + + /* We need to restart MediaCodec when the codec type changes */ + if (module->codec == NULL || mime != in->priv->module->mime) + { + LOG_DEBUG("creating codec for %s", mime); + + /* Start by releasing any instance we've previously created */ + if (module->codec != NULL) + { + module->codec->stop(); + module->codec->release(); + } + + module->codec = MediaCodec::CreateByType(module->alooper, mime, false); + if (module->codec == NULL) + { + LOG_ERROR("cannot instantiate MediaCodec for mime: %s", mime); + return MMAL_EINVAL; + } + + in->priv->module->mime = mime; + module->ahandler->reset(); + LOG_TRACE("creation done"); + } + /* When reusing an existing instance, we just need to stop it */ + else + { + module->codec->stop(); + } + + /* Configure MediaCodec */ + switch (in->format->type) + { + case MMAL_ES_TYPE_VIDEO: + format->setInt32("width", in->format->es->video.width); + format->setInt32("height", in->format->es->video.height); + if (in->format->es->video.frame_rate.num && in->format->es->video.frame_rate.den) + format->setFloat("frame-rate", in->format->es->video.frame_rate.num / + (float)in->format->es->video.frame_rate.den); + break; + case MMAL_ES_TYPE_AUDIO: + format->setInt32("channel-count", in->format->es->audio.channels); + format->setInt32("sample-rate", in->format->es->audio.sample_rate); + format->setInt32("bitrate", in->format->bitrate); + break; + default: + break; + } + + format->setString("mime", mime); + + /* Handle the codec specific data */ + if (in->format->extradata_size) + { + sp csd = new ABuffer(in->format->extradata, + in->format->extradata_size); + csd->meta()->setInt32("csd", true); + csd->meta()->setInt64("timeUs", 0); + format->setBuffer("csd-0", csd); + } + + /* Propagate the buffer size setting of the input port to the + * codec */ + format->setInt32("max-input-size", in->buffer_size); + + LOG_TRACE("configuring: %s", format->debugString().c_str()); + astatus = module->codec->configure(format, NULL, NULL, 0); + if (astatus) + { + LOG_ERROR("configure failed (%i)", astatus); + return MMAL_EINVAL; + } + + LOG_TRACE("starting"); + astatus = module->codec->start(); + if (astatus != OK) + { + LOG_ERROR("failed to start codec (%i)", astatus); + return MMAL_EINVAL; + } + LOG_TRACE("started"); + + return MMAL_SUCCESS; +} + +/** Enable processing on a port */ +static MMAL_STATUS_T amc_input_port_enable(MMAL_PORT_T *port, MMAL_PORT_BH_CB_T cb) +{ + MMAL_COMPONENT_T *component = port->component; + MMAL_COMPONENT_MODULE_T *module = component->priv->module; + MMAL_STATUS_T status; + status_t astatus; + MMAL_PARAM_UNUSED(cb); + + /* Make sure the format as been committed */ + status = port->priv->pf_set_format(port); + if (status != MMAL_SUCCESS) + { + LOG_ERROR("cannot commit port format (%i)", status); + return status; + } + + status = amc_codec_start(component); + if (status != MMAL_SUCCESS) + return status; + + astatus = module->codec->getInputBuffers(&module->input_buffers); + if (astatus != OK) + { + LOG_ERROR("failed to get codec input buffers (%i)", astatus); + return MMAL_EINVAL; + } + + if (module->input_buffers.size()) + LOG_TRACE("%i input buffers of size %i", module->input_buffers.size(), + module->input_buffers.itemAt(0)->capacity()); + + astatus = module->codec->getOutputBuffers(&module->output_buffers); + if (astatus != OK) + { + LOG_ERROR("failed to get codec output buffers (%i)", astatus); + return MMAL_EINVAL; + } + + if (module->output_buffers.size()) + LOG_TRACE("%i output buffers of size %i", module->output_buffers.size(), + module->output_buffers.itemAt(0)->capacity()); + + module->status = MMAL_SUCCESS; + return MMAL_SUCCESS; +} + +static MMAL_STATUS_T amc_output_port_enable(MMAL_PORT_T *port, MMAL_PORT_BH_CB_T cb) +{ + MMAL_PARAM_UNUSED(port); + MMAL_PARAM_UNUSED(cb); + return MMAL_SUCCESS; +} + +/** Flush a port */ +static MMAL_STATUS_T amc_port_flush(MMAL_PORT_T *port) +{ + MMAL_PORT_MODULE_T *port_module = port->priv->module; + MMAL_BUFFER_HEADER_T *buffer; + MMAL_COMPONENT_T *component = port->component; + MMAL_COMPONENT_MODULE_T *module = component->priv->module; + status_t astatus; + + /* Flush buffers that our component is holding on to */ + buffer = mmal_queue_get(port_module->queue); + while(buffer) + { + mmal_port_buffer_header_callback(port, buffer); + buffer = mmal_queue_get(port_module->queue); + } + + if (port_module->dequeued) + port_module->dequeued->clear(); + + /* Flush codec itself */ + if (port->type == MMAL_PORT_TYPE_INPUT && module->codec != NULL) + { + astatus = module->codec->flush(); + if (astatus != OK) + LOG_ERROR("failed to flush codec (%i)", astatus); + } + + return MMAL_SUCCESS; +} + +/** Disable processing on a port */ +static MMAL_STATUS_T amc_port_disable(MMAL_PORT_T *port) +{ + MMAL_COMPONENT_T *component = port->component; + MMAL_COMPONENT_MODULE_T *module = component->priv->module; + status_t astatus; + + if (port->type == MMAL_PORT_TYPE_INPUT) + { + astatus = module->codec->stop(); + if (astatus != OK) + LOG_ERROR("failed to stop codec (%i)", astatus); + module->codec->release(); + module->codec = NULL; + } + + /* We just need to flush our internal queue */ + return amc_port_flush(port); +} + +/** Send a buffer header to a port */ +static MMAL_STATUS_T amc_port_send(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) +{ + mmal_queue_put(port->priv->module->queue, buffer); + mmal_component_action_trigger(port->component); + return MMAL_SUCCESS; +} + +/** Set format on input port */ +static MMAL_STATUS_T amc_input_port_format_commit(MMAL_PORT_T *in) +{ + MMAL_STATUS_T status; + const char *mime; + + if (in->is_enabled) + return MMAL_EINVAL; + + if (!mmal_format_compare(in->format, in->priv->module->format)) + return MMAL_SUCCESS; + + mime = encoding_to_mime(in->format->type, in->format->encoding, + in->format->encoding_variant); + if (!mime) + { + LOG_ERROR("cannot match codec %4.4s(%4.4s) with a mime type", + (char *)&in->format->encoding, (char *)&in->format->encoding_variant); + return MMAL_EINVAL; + } + + /* Note that the MediaCodec object is only created when the input + * port is enabled to avoid deadlocking when we're running inside an + * Android OMX component (you can't create an OMX odec instance while + * you're already instantiating one) */ + + status = mmal_format_full_copy(in->priv->module->format, in->format); + if (status != MMAL_SUCCESS) + return status; + + /* No need to propagate anything to the output port since + * we'll generate a format change event for it later on */ + + return status; +} + +/** Set format on output port */ +static MMAL_STATUS_T amc_output_port_format_commit(MMAL_PORT_T *out) +{ + /* The format of the output port needs to match the output of + * MediaCodec */ + if (mmal_format_compare(out->format, out->priv->module->format)) + return MMAL_EINVAL; + + out->priv->module->needs_configuring = 0; + mmal_component_action_trigger(out->component); + return MMAL_SUCCESS; +} + +/** Create an instance of a component */ +static MMAL_STATUS_T mmal_component_create_android_media_codec(const char *name, MMAL_COMPONENT_T *component) +{ + MMAL_COMPONENT_MODULE_T *module; + MMAL_STATUS_T status = MMAL_ENOMEM; + const char *variant_name = name + sizeof("amc"); + unsigned int variant = AMC_VARIANT_UNKNOWN; + + if (!strcmp(variant_name, AMC_VARIANT_AUDIO_DECODE_NAME)) + variant = AMC_VARIANT_AUDIO_DECODE; + + if (variant == AMC_VARIANT_UNKNOWN) + { + LOG_ERROR("unsupported variant %s", variant_name); + return MMAL_ENOENT; + } + + /* Allocate the context for our module */ + component->priv->module = module = new MMAL_COMPONENT_MODULE_T; + if (!module) + return MMAL_ENOMEM; + + component->priv->pf_destroy = amc_component_destroy; + module->status = MMAL_SUCCESS; + ProcessState::self()->startThreadPool(); + module->ahandler = new AmcHandler(component); + module->alooper = new ALooper; + module->alooper->setName("amc_looper"); + module->alooper->registerHandler(module->ahandler); + module->alooper->start(false); + + /* Allocate and initialise all the ports for this component */ + component->input = mmal_ports_alloc(component, 1, MMAL_PORT_TYPE_INPUT, sizeof(MMAL_PORT_MODULE_T)); + if(!component->input) + goto error; + component->input_num = 1; + component->input[0]->priv->pf_enable = amc_input_port_enable; + component->input[0]->priv->pf_disable = amc_port_disable; + component->input[0]->priv->pf_flush = amc_port_flush; + component->input[0]->priv->pf_send = amc_port_send; + component->input[0]->priv->pf_set_format = amc_input_port_format_commit; + component->input[0]->buffer_num_min = 1; + component->input[0]->buffer_num_recommended = 3; + component->input[0]->priv->module->queue = mmal_queue_create(); + if(!component->input[0]->priv->module->queue) + goto error; + component->input[0]->priv->module->format = mmal_format_alloc(); + if(!component->input[0]->priv->module->format) + goto error; + component->input[0]->priv->module->dequeued = new List; + if(!component->input[0]->priv->module->dequeued) + goto error; + + component->output = mmal_ports_alloc(component, 1, MMAL_PORT_TYPE_OUTPUT, sizeof(MMAL_PORT_MODULE_T)); + if(!component->output) + goto error; + component->output_num = 1; + component->output[0]->priv->pf_enable = amc_output_port_enable; + component->output[0]->priv->pf_disable = amc_port_disable; + component->output[0]->priv->pf_flush = amc_port_flush; + component->output[0]->priv->pf_send = amc_port_send; + component->output[0]->priv->pf_set_format = amc_output_port_format_commit; + component->output[0]->buffer_num_min = 1; + component->output[0]->buffer_num_recommended = 3; + component->output[0]->priv->module->queue = mmal_queue_create(); + if(!component->output[0]->priv->module->queue) + goto error; + component->output[0]->priv->module->format = mmal_format_alloc(); + if(!component->output[0]->priv->module->format) + goto error; + + status = mmal_component_action_register(component, amc_do_processing_loop); + if (status != MMAL_SUCCESS) + goto error; + + /* Setup ports according to selected variant */ + if (variant == AMC_VARIANT_AUDIO_DECODE) + { + component->input[0]->format->type = MMAL_ES_TYPE_AUDIO; + component->input[0]->format->encoding = MMAL_ENCODING_EAC3; + component->input[0]->format->es->audio.sample_rate = 48000; + component->input[0]->format->es->audio.channels = 2; + component->input[0]->buffer_size_min = 4 * 1024; + + component->output[0]->format->type = MMAL_ES_TYPE_AUDIO; + component->output[0]->format->encoding = MMAL_ENCODING_PCM_SIGNED; + component->output[0]->format->es->audio.sample_rate = 48000; + component->output[0]->format->es->audio.channels = 2; + component->output[0]->format->es->audio.bits_per_sample = 16; + component->output[0]->buffer_size_min = 32 * 1024; + } + + /* Update our current view of the output format */ + mmal_format_copy(component->output[0]->priv->module->format, + component->output[0]->format); + + return MMAL_SUCCESS; + + error: + amc_component_destroy(component); + return status; +} + +MMAL_CONSTRUCTOR(mmal_register_component_android_media_codec); +void mmal_register_component_android_media_codec(void) +{ + mmal_component_supplier_register("amc", mmal_component_create_android_media_codec); +} diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/components/artificial_camera.c b/external_src/raspicam-0.1.3/dependencies/mmal/components/artificial_camera.c new file mode 100644 index 0000000..e883f53 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/components/artificial_camera.c @@ -0,0 +1,287 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 "mmal.h" +#include "core/mmal_component_private.h" +#include "core/mmal_port_private.h" +#include "mmal_logging.h" + +#define ARTIFICIAL_CAMERA_PORTS_NUM 3 + +/* Buffering requirements */ +#define OUTPUT_MIN_BUFFER_NUM 1 +#define OUTPUT_RECOMMENDED_BUFFER_NUM 4 + +#define DEFAULT_WIDTH 320 +#define DEFAULT_HEIGHT 240 + +/*****************************************************************************/ +typedef struct MMAL_PORT_MODULE_T +{ + MMAL_BUFFER_HEADER_VIDEO_SPECIFIC_T frame; + unsigned int frame_size; + int count; + + MMAL_QUEUE_T *queue; + +} MMAL_PORT_MODULE_T; + +typedef struct MMAL_COMPONENT_MODULE_T +{ + MMAL_STATUS_T status; + +} MMAL_COMPONENT_MODULE_T; + +/*****************************************************************************/ +static void artificial_camera_do_processing(MMAL_COMPONENT_T *component) +{ + MMAL_COMPONENT_MODULE_T *module = component->priv->module; + MMAL_BUFFER_HEADER_T *buffer; + unsigned int i; + + if (module->status != MMAL_SUCCESS) + return; + + /* Loop through all the ports */ + for (i = 0; i < component->output_num; i++) + { + MMAL_PORT_T *port = component->output[i]; + + buffer = mmal_queue_get(port->priv->module->queue); + if (!buffer) + continue; + + /* Sanity check the buffer size */ + if (buffer->alloc_size < port->priv->module->frame_size) + { + LOG_ERROR("buffer too small (%i/%i)", + buffer->alloc_size, port->priv->module->frame_size); + module->status = MMAL_EINVAL; + mmal_queue_put_back(port->priv->module->queue, buffer); + mmal_event_error_send(component, module->status); + return; + } + module->status = mmal_buffer_header_mem_lock(buffer); + if (module->status != MMAL_SUCCESS) + { + LOG_ERROR("invalid buffer (%p, %p)", buffer, buffer->data); + mmal_queue_put_back(port->priv->module->queue, buffer); + mmal_event_error_send(component, module->status); + return; + } + + buffer->offset = 0; + buffer->length = port->priv->module->frame_size; + buffer->type->video = port->priv->module->frame; + + memset(buffer->data, 0xff, buffer->length); + if (buffer->type->video.planes > 1) + memset(buffer->data + buffer->type->video.offset[1], + 0x7f - port->priv->module->count++, + buffer->length - buffer->type->video.offset[1]); + + mmal_buffer_header_mem_unlock(buffer); + mmal_port_buffer_header_callback(port, buffer); + } + + vcos_sleep(10); /* Make sure we don't peg all the resources */ +} + +/** Destroy a previously created component */ +static MMAL_STATUS_T artificial_camera_component_destroy(MMAL_COMPONENT_T *component) +{ + unsigned int i; + + for (i = 0; i < component->output_num; i++) + if (component->output[i]->priv->module->queue) + mmal_queue_destroy(component->output[i]->priv->module->queue); + + if(component->output_num) + mmal_ports_free(component->output, component->output_num); + + vcos_free(component->priv->module); + return MMAL_SUCCESS; +} + +/** Enable processing on a port */ +static MMAL_STATUS_T artificial_camera_port_enable(MMAL_PORT_T *port, MMAL_PORT_BH_CB_T cb) +{ + MMAL_PARAM_UNUSED(port); + MMAL_PARAM_UNUSED(cb); + return MMAL_SUCCESS; +} + +/** Flush a port */ +static MMAL_STATUS_T artificial_camera_port_flush(MMAL_PORT_T *port) +{ + MMAL_PARAM_UNUSED(port); + return MMAL_SUCCESS; +} + +/** Disable processing on a port */ +static MMAL_STATUS_T artificial_camera_port_disable(MMAL_PORT_T *port) +{ + MMAL_PARAM_UNUSED(port); + return MMAL_SUCCESS; +} + +/** Send a buffer header to a port */ +static MMAL_STATUS_T artificial_camera_port_send(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) +{ + /* Just queue the buffer */ + mmal_queue_put(port->priv->module->queue, buffer); + mmal_component_action_trigger(port->component); + return MMAL_SUCCESS; +} + +/** Set format on a port */ +static MMAL_STATUS_T artificial_camera_port_format_commit(MMAL_PORT_T *port) +{ + MMAL_PORT_MODULE_T *port_module = port->priv->module; + unsigned int width = port->format->es->video.width; + unsigned int height = port->format->es->video.height; + width = (width + 31) & ~31; + height = (height + 15) & ~15; + + /* We only support a few formats */ + switch(port->format->encoding) + { + case MMAL_ENCODING_I420: + port_module->frame_size = width * height * 3 / 2; + port_module->frame.planes = 3; + port_module->frame.pitch[0] = width; + port_module->frame.offset[1] = port_module->frame.pitch[0] * height; + port_module->frame.pitch[1] = width / 2; + port_module->frame.offset[2] = port_module->frame.offset[1] + port_module->frame.pitch[1] * height / 2; + port_module->frame.pitch[2] = width / 2; + break; + case MMAL_ENCODING_NV21: + port_module->frame_size = width * height * 3 / 2; + port_module->frame.planes = 2; + port_module->frame.pitch[0] = width; + port_module->frame.offset[1] = port_module->frame.pitch[0] * height; + port_module->frame.pitch[1] = width; + break; + case MMAL_ENCODING_I422: + port_module->frame_size = width * height * 2; + port_module->frame.planes = 3; + port_module->frame.pitch[0] = width; + port_module->frame.offset[1] = port_module->frame.pitch[0] * height; + port_module->frame.pitch[1] = width / 2; + port_module->frame.offset[2] = port_module->frame.offset[1] + port_module->frame.pitch[1] * height; + port_module->frame.pitch[2] = width / 2; + break; + default: + return MMAL_ENOSYS; + } + + port->buffer_size_min = port->buffer_size_recommended = port_module->frame_size; + return MMAL_SUCCESS; +} + +/** Set parameter on a port */ +static MMAL_STATUS_T artificial_port_parameter_set(MMAL_PORT_T *port, const MMAL_PARAMETER_HEADER_T *param) +{ + MMAL_PARAM_UNUSED(port); + switch (param->id) + { + default: + return MMAL_ENOSYS; + } +} + +/** Get parameter on a port */ +static MMAL_STATUS_T artificial_port_parameter_get(MMAL_PORT_T *port, MMAL_PARAMETER_HEADER_T *param) +{ + MMAL_PARAM_UNUSED(port); + switch (param->id) + { + default: + return MMAL_ENOSYS; + } +} + +/** Create an instance of a component */ +static MMAL_STATUS_T mmal_component_create_artificial_camera(const char *name, MMAL_COMPONENT_T *component) +{ + MMAL_STATUS_T status = MMAL_ENOMEM; + unsigned int i; + MMAL_PARAM_UNUSED(name); + + /* Allocate our module context */ + component->priv->module = vcos_calloc(1, sizeof(*component->priv->module), "mmal module"); + if (!component->priv->module) + return MMAL_ENOMEM; + + component->priv->pf_destroy = artificial_camera_component_destroy; + + /* Allocate all the ports for this component */ + component->output = mmal_ports_alloc(component, ARTIFICIAL_CAMERA_PORTS_NUM, MMAL_PORT_TYPE_OUTPUT, + sizeof(MMAL_PORT_MODULE_T)); + if(!component->output) + goto error; + component->output_num = ARTIFICIAL_CAMERA_PORTS_NUM; + + for (i = 0; i < component->output_num; i++) + { + component->output[i]->priv->pf_enable = artificial_camera_port_enable; + component->output[i]->priv->pf_disable = artificial_camera_port_disable; + component->output[i]->priv->pf_flush = artificial_camera_port_flush; + component->output[i]->priv->pf_send = artificial_camera_port_send; + component->output[i]->priv->pf_send = artificial_camera_port_send; + component->output[i]->priv->pf_set_format = artificial_camera_port_format_commit; + component->output[i]->priv->pf_parameter_set = artificial_port_parameter_set; + component->output[i]->priv->pf_parameter_get = artificial_port_parameter_get; + component->output[i]->format->type = MMAL_ES_TYPE_VIDEO; + component->output[i]->format->encoding = MMAL_ENCODING_I420; + component->output[i]->format->es->video.width = DEFAULT_WIDTH; + component->output[i]->format->es->video.height = DEFAULT_HEIGHT; + component->output[i]->buffer_num_min = OUTPUT_MIN_BUFFER_NUM; + component->output[i]->buffer_num_recommended = OUTPUT_RECOMMENDED_BUFFER_NUM; + artificial_camera_port_format_commit(component->output[i]); + + component->output[i]->priv->module->queue = mmal_queue_create(); + if (!component->output[i]->priv->module->queue) + goto error; + } + + status = mmal_component_action_register(component, artificial_camera_do_processing); + if (status != MMAL_SUCCESS) + goto error; + + return MMAL_SUCCESS; + + error: + artificial_camera_component_destroy(component); + return status; +} + +MMAL_CONSTRUCTOR(mmal_register_component_artificial_camera); +void mmal_register_component_artificial_camera(void) +{ + mmal_component_supplier_register("artificial_camera", mmal_component_create_artificial_camera); +} diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/components/avcodec_audio_decoder.c b/external_src/raspicam-0.1.3/dependencies/mmal/components/avcodec_audio_decoder.c new file mode 100644 index 0000000..20f6192 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/components/avcodec_audio_decoder.c @@ -0,0 +1,607 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 "mmal.h" +#include "core/mmal_component_private.h" +#include "core/mmal_port_private.h" +#include "mmal_logging.h" + +#include "libavcodec/avcodec.h" +#include "libavutil/mathematics.h" +#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT( 52, 23, 0 ) +# include "libavformat/avformat.h" + static AVPacket null_packet = {AV_NOPTS_VALUE, AV_NOPTS_VALUE}; +# define av_init_packet(a) *(a) = null_packet +#endif + +#if LIBAVCODEC_VERSION_MAJOR < 53 +# define avcodec_decode_audio3(a,b,c,d) avcodec_decode_audio2(a,b,c,(d)->data,(d)->size) +#endif + +#if LIBAVCODEC_VERSION_MAJOR < 54 +#define AVSampleFormat SampleFormat +#define AV_SAMPLE_FMT_NONE SAMPLE_FMT_NONE +#define AV_SAMPLE_FMT_U8 SAMPLE_FMT_U8 +#define AV_SAMPLE_FMT_S16 SAMPLE_FMT_S16 +#define AV_SAMPLE_FMT_S32 SAMPLE_FMT_S32 +#define AV_SAMPLE_FMT_FLT SAMPLE_FMT_FLT +#define AV_SAMPLE_FMT_DBL SAMPLE_FMT_DBL +#endif + +/* Buffering requirements */ +#define INPUT_MIN_BUFFER_SIZE (4*1024) +#define INPUT_MIN_BUFFER_NUM 1 +#define INPUT_RECOMMENDED_BUFFER_SIZE INPUT_MIN_BUFFER_SIZE +#define INPUT_RECOMMENDED_BUFFER_NUM 10 +#define OUTPUT_MIN_BUFFER_NUM 1 +#define OUTPUT_RECOMMENDED_BUFFER_NUM 4 +#define OUTPUT_MIN_BUFFER_SIZE 512 +#define OUTPUT_RECOMMENDED_BUFFER_SIZE 4096 + +static uint32_t encoding_to_codecid(uint32_t encoding); +static uint32_t samplefmt_to_encoding(enum AVSampleFormat); +static unsigned int samplefmt_to_sample_size(enum AVSampleFormat samplefmt); + +/****************************/ +typedef struct MMAL_COMPONENT_MODULE_T +{ + MMAL_STATUS_T status; + + MMAL_QUEUE_T *queue_in; + MMAL_QUEUE_T *queue_out; + + int64_t pts; + + int64_t last_pts; + int64_t samples_since_last_pts; + + int output_buffer_size; + uint8_t *output_buffer; + + uint8_t *output; + int output_size; + AVCodecContext *codec_context; + AVCodec *codec; + + enum AVSampleFormat sample_fmt; + int channels; + int sample_rate; + int bits_per_sample; + + MMAL_BOOL_T output_needs_configuring; + +} MMAL_COMPONENT_MODULE_T; + +/** Destroy a previously created component */ +static MMAL_STATUS_T avcodec_component_destroy(MMAL_COMPONENT_T *component) +{ + MMAL_COMPONENT_MODULE_T *module = component->priv->module; + + if (module->codec_context) + { + if (module->codec_context->extradata) + vcos_free(module->codec_context->extradata); + if (module->codec_context->codec) + avcodec_close(module->codec_context); + av_free(module->codec_context); + } + if (module->output_buffer) + av_free(module->output_buffer); + + if (module->queue_in) + mmal_queue_destroy(module->queue_in); + if (module->queue_out) + mmal_queue_destroy(module->queue_out); + vcos_free(module); + if (component->input_num) + mmal_ports_free(component->input, 1); + if (component->output_num) + mmal_ports_free(component->output, 1); + return MMAL_SUCCESS; +} + +/** Set format on a port */ +static MMAL_STATUS_T avcodec_input_port_set_format(MMAL_PORT_T *port) +{ + MMAL_COMPONENT_T *component = port->component; + MMAL_COMPONENT_MODULE_T *module = component->priv->module; + enum CodecID codec_id; + AVCodec *codec; + + codec_id = encoding_to_codecid(port->format->encoding); + if (codec_id == CODEC_ID_NONE || + !(codec = avcodec_find_decoder(codec_id))) + { + LOG_ERROR("ffmpeg codec id %d (for %4.4s) not recognized", + codec_id, (char *)&port->format->encoding); + return MMAL_ENXIO; + } + + module->output_buffer_size = AVCODEC_MAX_AUDIO_FRAME_SIZE; + if (module->output_buffer) + av_free(module->output_buffer); + module->output_buffer = av_malloc(module->output_buffer_size); + + module->codec_context->sample_rate = port->format->es->audio.sample_rate; + module->codec_context->channels = port->format->es->audio.channels; + module->codec_context->block_align = port->format->es->audio.block_align; + module->codec_context->bit_rate = port->format->bitrate; + module->codec_context->bits_per_coded_sample = port->format->es->audio.bits_per_sample; + module->codec_context->extradata_size = port->format->extradata_size; + module->codec_context->extradata = + vcos_calloc(1, port->format->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE, + "avcodec extradata"); + if (module->codec_context->extradata) + memcpy(module->codec_context->extradata, port->format->extradata, + port->format->extradata_size); + + if (codec->capabilities & CODEC_CAP_TRUNCATED) + module->codec_context->flags |= CODEC_FLAG_TRUNCATED; + + if (avcodec_open(module->codec_context, codec) < 0) + { + LOG_ERROR("could not open codec"); + return MMAL_EIO; + } + + /* Set a default format */ + if (module->codec_context->sample_fmt == AV_SAMPLE_FMT_NONE) + module->codec_context->sample_fmt = AV_SAMPLE_FMT_S16; + + /* Copy format to output */ + mmal_format_copy(component->output[0]->format, port->format); + LOG_DEBUG("avcodec output format %i", module->codec_context->sample_fmt); + component->output[0]->format->encoding = samplefmt_to_encoding(module->codec_context->sample_fmt); + component->output[0]->format->es->audio.bits_per_sample = + samplefmt_to_sample_size(module->codec_context->sample_fmt); + + component->output[0]->priv->pf_set_format(component->output[0]); + return MMAL_SUCCESS; +} + +/** Set format on a port */ +static MMAL_STATUS_T avcodec_output_port_set_format(MMAL_PORT_T *port) +{ + MMAL_COMPONENT_T *component = port->component; + MMAL_COMPONENT_MODULE_T *module = component->priv->module; + + /* Format can only be set to what is output by the codec */ + if (samplefmt_to_encoding(module->codec_context->sample_fmt) != port->format->encoding || + samplefmt_to_sample_size(module->codec_context->sample_fmt) != port->format->es->audio.bits_per_sample) + return MMAL_EINVAL; + + if (!port->format->es->audio.sample_rate || !port->format->es->audio.channels) + return MMAL_EINVAL; + + module->sample_fmt = module->codec_context->sample_fmt; + module->sample_rate = port->format->es->audio.sample_rate; + module->channels = port->format->es->audio.channels; + module->bits_per_sample = port->format->es->audio.bits_per_sample; + + port->component->priv->module->output_needs_configuring = 0; + mmal_component_action_trigger(port->component); + + return MMAL_SUCCESS; +} + +/** Enable processing on a port */ +static MMAL_STATUS_T avcodec_port_enable(MMAL_PORT_T *port, MMAL_PORT_BH_CB_T cb) +{ + MMAL_PARAM_UNUSED(port); + MMAL_PARAM_UNUSED(cb); + return MMAL_SUCCESS; +} + +/** Flush a port */ +static MMAL_STATUS_T avcodec_port_flush(MMAL_PORT_T *port) +{ + MMAL_COMPONENT_T *component = port->component; + MMAL_COMPONENT_MODULE_T *module = component->priv->module; + MMAL_BUFFER_HEADER_T *buffer; + MMAL_QUEUE_T *queue; + + if(port->type == MMAL_PORT_TYPE_OUTPUT) + queue = module->queue_out; + else if(port->type == MMAL_PORT_TYPE_INPUT) + queue = module->queue_in; + else + return MMAL_EINVAL; + + /* Flush buffers that our component is holding on to. + * If the reading thread is holding onto a buffer it will send it back ASAP as well + * so no need to care about that. */ + while((buffer = mmal_queue_get(queue))) + mmal_port_buffer_header_callback(port, buffer); + + return MMAL_SUCCESS; +} + +/** Disable processing on a port */ +static MMAL_STATUS_T avcodec_port_disable(MMAL_PORT_T *port) +{ + MMAL_STATUS_T status; + + /* Actions are prevented from running at that point so a flush + * will return all buffers. */ + status = avcodec_port_flush(port); + if(status != MMAL_SUCCESS) + return status; + + return MMAL_SUCCESS; +} + +/*****************************************************************************/ +static void avcodec_send_event_format_changed(MMAL_COMPONENT_T *component, MMAL_PORT_T *port) +{ + MMAL_COMPONENT_MODULE_T *module = component->priv->module; + MMAL_BUFFER_HEADER_T *buffer = NULL; + MMAL_EVENT_FORMAT_CHANGED_T *event; + + /* Get an event buffer */ + module->status = mmal_port_event_get(port, &buffer, MMAL_EVENT_FORMAT_CHANGED); + if (module->status != MMAL_SUCCESS) + { + LOG_ERROR("unable to get an event buffer"); + return; + } + event = mmal_event_format_changed_get(buffer); + + /* Fill in the new format */ + mmal_format_copy(event->format, port->format); + event->format->es->audio.sample_rate = module->codec_context->sample_rate; + event->format->es->audio.channels = module->codec_context->channels; + event->format->encoding = samplefmt_to_encoding(module->codec_context->sample_fmt); + event->format->es->audio.bits_per_sample = samplefmt_to_sample_size(module->codec_context->sample_fmt); + + /* Pass on the buffer requirements */ + event->buffer_num_min = port->buffer_num_min; + event->buffer_size_min = port->buffer_size_min; + event->buffer_size_recommended = event->buffer_size_min; + event->buffer_num_recommended = port->buffer_num_recommended; + + module->output_needs_configuring = 1; + mmal_port_event_send(port, buffer); +} + +/*****************************************************************************/ +static MMAL_STATUS_T avcodec_send_eos(MMAL_COMPONENT_T *component, MMAL_PORT_T *port) +{ + MMAL_COMPONENT_MODULE_T *module = component->priv->module; + MMAL_BUFFER_HEADER_T *out = mmal_queue_get(module->queue_out); + + if (!out) + return MMAL_EAGAIN; + + out->length = 0; + out->flags = MMAL_BUFFER_HEADER_FLAG_EOS; + mmal_port_buffer_header_callback(port, out); + return MMAL_SUCCESS; +} + +/*****************************************************************************/ +static MMAL_STATUS_T avcodec_send_frame(MMAL_COMPONENT_T *component, MMAL_PORT_T *port) +{ + MMAL_COMPONENT_MODULE_T *module = component->priv->module; + MMAL_BUFFER_HEADER_T *out; + int size, samples; + + /* Detect format changes */ + if (module->codec_context->channels != module->channels || + module->codec_context->sample_rate != module->sample_rate || + module->codec_context->sample_fmt != module->sample_fmt) + { + avcodec_send_event_format_changed(component, port); + return MMAL_EAGAIN; + } + + out = mmal_queue_get(module->queue_out); + if (!out) + return MMAL_EAGAIN; + + size = module->output_size; + if (size > (int)out->alloc_size) + size = out->alloc_size; + + samples = size / module->channels * 8 / module->bits_per_sample; + size = samples * module->channels * module->bits_per_sample / 8; + out->length = size; + out->pts = module->pts; + out->flags = 0; + memcpy(out->data, module->output, size); + module->output_size -= size; + module->output += size; + + if (module->pts != MMAL_TIME_UNKNOWN) + { + module->last_pts = module->pts; + module->samples_since_last_pts = 0; + } + module->pts = MMAL_TIME_UNKNOWN; + module->samples_since_last_pts += samples; + + if (out->pts == MMAL_TIME_UNKNOWN) + out->pts = module->last_pts + module->samples_since_last_pts * 1000000 / module->sample_rate; + + out->dts = out->pts; + mmal_port_buffer_header_callback(port, out); + return MMAL_SUCCESS; +} + +/*****************************************************************************/ +static MMAL_BOOL_T avaudio_do_processing(MMAL_COMPONENT_T *component) +{ + MMAL_COMPONENT_MODULE_T *module = component->priv->module; + MMAL_PORT_T *port_in = component->input[0]; + MMAL_PORT_T *port_out = component->output[0]; + MMAL_BUFFER_HEADER_T *in; + AVPacket avpkt; + int used = 0; + + if (module->output_needs_configuring) + return 0; + + if (module->output_size && + avcodec_send_frame(component, port_out) != MMAL_SUCCESS) + return 0; + if (module->output_size) + return 1; + + /* Get input buffer to decode */ + in = mmal_queue_get(module->queue_in); + if (!in) + return 0; + + /* Discard empty buffers. EOS buffers are not discarded since they will be used + * to flush the codec. */ + if (!in->length && !(in->flags & MMAL_BUFFER_HEADER_FLAG_EOS)) + goto end; + + /* Avcodec expects padded input data */ + if (in->length && !in->offset) + { + if(in->length + FF_INPUT_BUFFER_PADDING_SIZE <= in->alloc_size) + memset(in->data + in->length, 0, FF_INPUT_BUFFER_PADDING_SIZE); + else + LOG_WARN("could not pad buffer"); // Try to decode the data anyway + } + + /* The actual decoding */ + av_init_packet(&avpkt); + avpkt.data = in->length ? in->data + in->offset : 0; + avpkt.size = in->length; + module->output_size = module->output_buffer_size; + module->output = module->output_buffer; + used = avcodec_decode_audio3(module->codec_context, (int16_t*)module->output, + &module->output_size, &avpkt); + + /* Check for errors */ + if (used < 0 || used > (int)in->length) + { + LOG_ERROR("decoding failed (%i), discarding buffer", used); + used = in->length; + } + + module->pts = in->dts; + if (module->pts == MMAL_TIME_UNKNOWN) + module->pts = in->pts; + + end: + in->offset += used; + in->length -= used; + + if (in->length) + { + mmal_queue_put_back(module->queue_in, in); + return 1; + } + + /* We want to keep the EOS buffer until all the frames have been flushed */ + if ((in->flags & MMAL_BUFFER_HEADER_FLAG_EOS) && + module->output_size) + { + mmal_queue_put_back(module->queue_in, in); + return 1; + } + + /* Send EOS */ + if ((in->flags & MMAL_BUFFER_HEADER_FLAG_EOS) && + avcodec_send_eos(component, port_out) != MMAL_SUCCESS) + { + mmal_queue_put_back(module->queue_in, in); + return 0; + } + + in->offset = 0; + mmal_port_buffer_header_callback(port_in, in); + return 1; +} + +/*****************************************************************************/ +static void avcodec_do_processing_loop(MMAL_COMPONENT_T *component) +{ + while (avaudio_do_processing(component)); +} + +/** Buffer sending */ +static MMAL_STATUS_T avcodec_port_send(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) +{ + MMAL_COMPONENT_T *component = port->component; + MMAL_COMPONENT_MODULE_T *module = component->priv->module; + + if(port->type == MMAL_PORT_TYPE_OUTPUT) mmal_queue_put(module->queue_out, buffer); + if(port->type == MMAL_PORT_TYPE_INPUT) mmal_queue_put(module->queue_in, buffer); + mmal_component_action_trigger(port->component); + + return MMAL_SUCCESS; +} + +/** Create an instance of a component */ +static MMAL_STATUS_T mmal_component_create_avcodec(const char *name, MMAL_COMPONENT_T *component) +{ + MMAL_STATUS_T status = MMAL_ENOMEM; + MMAL_COMPONENT_MODULE_T *module; + + /* Check we're the requested component */ + if(strcmp(name, "avcodec." MMAL_AUDIO_DECODE)) + return MMAL_ENOENT; + + /* Allocate our module context */ + component->priv->module = module = vcos_calloc(1, sizeof(*module), "mmal module"); + if(!module) + return MMAL_ENOENT; + + /* Allocate the ports for this component */ + component->input = mmal_ports_alloc(component, 1, MMAL_PORT_TYPE_INPUT, 0); + if(!component->input) goto error; + component->input_num = 1; + component->output = mmal_ports_alloc(component, 1, MMAL_PORT_TYPE_OUTPUT, 0); + if(!component->output) goto error; + component->output_num = 1; + + module->queue_in = mmal_queue_create(); + if(!module->queue_in) goto error; + module->queue_out = mmal_queue_create(); + if(!module->queue_out) goto error; + + module->codec_context = avcodec_alloc_context(); + if(!module->codec_context) goto error; + + component->input[0]->priv->pf_set_format = avcodec_input_port_set_format; + component->input[0]->priv->pf_enable = avcodec_port_enable; + component->input[0]->priv->pf_disable = avcodec_port_disable; + component->input[0]->priv->pf_flush = avcodec_port_flush; + component->input[0]->priv->pf_send = avcodec_port_send; + component->input[0]->buffer_num_min = INPUT_MIN_BUFFER_NUM; + component->input[0]->buffer_num_recommended = INPUT_RECOMMENDED_BUFFER_NUM; + component->input[0]->buffer_size_min = INPUT_MIN_BUFFER_SIZE; + component->input[0]->buffer_size_recommended = INPUT_RECOMMENDED_BUFFER_SIZE; + + component->output[0]->priv->pf_set_format = avcodec_output_port_set_format; + component->output[0]->priv->pf_enable = avcodec_port_enable; + component->output[0]->priv->pf_disable = avcodec_port_disable; + component->output[0]->priv->pf_disable = avcodec_port_flush; + component->output[0]->priv->pf_send = avcodec_port_send; + component->output[0]->buffer_num_min = OUTPUT_MIN_BUFFER_NUM; + component->output[0]->buffer_num_recommended = OUTPUT_RECOMMENDED_BUFFER_NUM; + component->output[0]->buffer_size_min = OUTPUT_MIN_BUFFER_SIZE; + component->output[0]->buffer_size_recommended = OUTPUT_RECOMMENDED_BUFFER_SIZE; + + component->output[0]->format->type = MMAL_ES_TYPE_AUDIO; + component->output[0]->format->encoding = MMAL_ENCODING_PCM_SIGNED_LE; + + component->priv->pf_destroy = avcodec_component_destroy; + + status = mmal_component_action_register(component, avcodec_do_processing_loop); + if (status != MMAL_SUCCESS) + goto error; + + return MMAL_SUCCESS; + + error: + avcodec_component_destroy(component); + return status; +} + +static struct { + uint32_t encoding; + int codecid; +} codec_to_encoding_table[] = +{ + {MMAL_ENCODING_MP4A, CODEC_ID_AAC}, + {MMAL_ENCODING_MPGA, CODEC_ID_MP3}, + {MMAL_ENCODING_ALAW, CODEC_ID_PCM_ALAW}, + {MMAL_ENCODING_MULAW, CODEC_ID_PCM_MULAW}, + {MMAL_ENCODING_ADPCM_MS, CODEC_ID_ADPCM_MS}, + {MMAL_ENCODING_ADPCM_IMA_MS, CODEC_ID_ADPCM_IMA_WAV}, + {MMAL_ENCODING_ADPCM_SWF, CODEC_ID_ADPCM_SWF}, + {MMAL_ENCODING_WMA1, CODEC_ID_WMAV1}, + {MMAL_ENCODING_WMA2, CODEC_ID_WMAV2}, + {MMAL_ENCODING_WMAP, CODEC_ID_WMAPRO}, + {MMAL_ENCODING_WMAL, CODEC_ID_NONE}, + {MMAL_ENCODING_WMAV, CODEC_ID_WMAVOICE}, + {MMAL_ENCODING_AMRNB, CODEC_ID_AMR_NB}, + {MMAL_ENCODING_AMRWB, CODEC_ID_AMR_WB}, + {MMAL_ENCODING_AMRWBP, CODEC_ID_NONE}, + {MMAL_ENCODING_AC3, CODEC_ID_AC3}, + {MMAL_ENCODING_EAC3, CODEC_ID_EAC3}, + {MMAL_ENCODING_DTS, CODEC_ID_DTS}, + {MMAL_ENCODING_MLP, CODEC_ID_MLP}, + {MMAL_ENCODING_FLAC, CODEC_ID_FLAC}, + {MMAL_ENCODING_VORBIS, CODEC_ID_VORBIS}, + {MMAL_ENCODING_SPEEX, CODEC_ID_SPEEX}, + {MMAL_ENCODING_NELLYMOSER, CODEC_ID_NELLYMOSER}, + {MMAL_ENCODING_QCELP, CODEC_ID_QCELP}, + + {MMAL_ENCODING_UNKNOWN, CODEC_ID_NONE} +}; + +static uint32_t encoding_to_codecid(uint32_t encoding) +{ + unsigned int i; + for(i = 0; codec_to_encoding_table[i].encoding != MMAL_ENCODING_UNKNOWN; i++) + if(codec_to_encoding_table[i].encoding == encoding) break; + return codec_to_encoding_table[i].codecid; +} + +static struct { + uint32_t encoding; + enum AVSampleFormat samplefmt; + unsigned int sample_size; +} samplefmt_to_encoding_table[] = +{ + {MMAL_ENCODING_PCM_UNSIGNED, AV_SAMPLE_FMT_U8, 8}, + {MMAL_ENCODING_PCM_SIGNED, AV_SAMPLE_FMT_S16, 16}, + {MMAL_ENCODING_PCM_SIGNED, AV_SAMPLE_FMT_S32, 32}, + {MMAL_ENCODING_PCM_FLOAT, AV_SAMPLE_FMT_FLT, 32}, + {MMAL_ENCODING_PCM_FLOAT, AV_SAMPLE_FMT_DBL, 64}, + {MMAL_ENCODING_UNKNOWN, AV_SAMPLE_FMT_NONE, 1} +}; + +static uint32_t samplefmt_to_encoding(enum AVSampleFormat samplefmt) +{ + unsigned int i; + for(i = 0; samplefmt_to_encoding_table[i].encoding != MMAL_ENCODING_UNKNOWN; i++) + if(samplefmt_to_encoding_table[i].samplefmt == samplefmt) break; + return samplefmt_to_encoding_table[i].encoding; +} + +static unsigned int samplefmt_to_sample_size(enum AVSampleFormat samplefmt) +{ + unsigned int i; + for(i = 0; samplefmt_to_encoding_table[i].encoding != MMAL_ENCODING_UNKNOWN; i++) + if(samplefmt_to_encoding_table[i].samplefmt == samplefmt) break; + return samplefmt_to_encoding_table[i].sample_size; +} + +MMAL_CONSTRUCTOR(mmal_register_component_avcodec_audio); +void mmal_register_component_avcodec_audio(void) +{ + avcodec_init(); + avcodec_register_all(); + + mmal_component_supplier_register("avcodec", mmal_component_create_avcodec); +} diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/components/avcodec_video_decoder.c b/external_src/raspicam-0.1.3/dependencies/mmal/components/avcodec_video_decoder.c new file mode 100644 index 0000000..356c429 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/components/avcodec_video_decoder.c @@ -0,0 +1,586 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 "mmal.h" +#include "core/mmal_component_private.h" +#include "core/mmal_port_private.h" +#include "mmal_logging.h" + +#define attribute_deprecated +#include "libavcodec/avcodec.h" +#include "libavutil/mathematics.h" +#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT( 52, 23, 0 ) +# include "libavformat/avformat.h" + static AVPacket null_packet = {AV_NOPTS_VALUE, AV_NOPTS_VALUE}; +# define av_init_packet(a) *(a) = null_packet +#endif + +#if LIBAVCODEC_VERSION_MAJOR < 53 +# define avcodec_decode_video2(a,b,c,d) avcodec_decode_video(a,b,c,(d)->data,(d)->size) +#endif + +/* Buffering requirements */ +#define INPUT_MIN_BUFFER_SIZE (800*1024) +#define INPUT_MIN_BUFFER_NUM 1 +#define INPUT_RECOMMENDED_BUFFER_SIZE INPUT_MIN_BUFFER_SIZE +#define INPUT_RECOMMENDED_BUFFER_NUM 10 +#define OUTPUT_MIN_BUFFER_NUM 1 +#define OUTPUT_RECOMMENDED_BUFFER_NUM 4 + +#define DEFAULT_WIDTH 320 +#define DEFAULT_HEIGHT 240 + +static uint32_t encoding_to_codecid(uint32_t encoding); +static uint32_t pixfmt_to_encoding(enum PixelFormat); + +/****************************/ +typedef struct MMAL_COMPONENT_MODULE_T +{ + MMAL_STATUS_T status; + + MMAL_QUEUE_T *queue_in; + MMAL_QUEUE_T *queue_out; + + int picture_available; + int64_t pts; + int64_t dts; + + AVFrame *picture; + AVCodecContext *codec_context; + AVCodec *codec; + + int width; + int height; + enum PixelFormat pix_fmt; + AVPicture layout; + unsigned int planes; + + int frame_size; + MMAL_BOOL_T output_needs_configuring; + +} MMAL_COMPONENT_MODULE_T; + +/** Destroy a previously created component */ +static MMAL_STATUS_T avcodec_component_destroy(MMAL_COMPONENT_T *component) +{ + MMAL_COMPONENT_MODULE_T *module = component->priv->module; + + if (module->picture) + av_free(module->picture); + if (module->codec_context) + { + if(module->codec_context->extradata) vcos_free(module->codec_context->extradata); + if(module->codec_context->codec) avcodec_close(module->codec_context); + av_free(module->codec_context); + } + + if(module->queue_in) mmal_queue_destroy(module->queue_in); + if(module->queue_out) mmal_queue_destroy(module->queue_out); + vcos_free(module); + if(component->input_num) mmal_ports_free(component->input, 1); + if(component->output_num) mmal_ports_free(component->output, 1); + return MMAL_SUCCESS; +} + +/** Set format on a port */ +static MMAL_STATUS_T avcodec_input_port_set_format(MMAL_PORT_T *port) +{ + MMAL_COMPONENT_T *component = port->component; + MMAL_COMPONENT_MODULE_T *module = component->priv->module; + enum CodecID codec_id; + AVCodec *codec; + + codec_id = encoding_to_codecid(port->format->encoding); + if(codec_id == CODEC_ID_NONE || + !(codec = avcodec_find_decoder(codec_id))) + { + LOG_ERROR("ffmpeg codec id %d (for %4.4s) not recognized", + codec_id, (char *)&port->format->encoding); + return MMAL_ENXIO; + } + + module->picture = avcodec_alloc_frame(); + + module->codec_context->width = port->format->es->video.width; + module->codec_context->height = port->format->es->video.height; + module->codec_context->extradata_size = port->format->extradata_size; + module->codec_context->extradata = + vcos_calloc(1, port->format->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE, + "avcodec extradata"); + if(module->codec_context->extradata) + memcpy(module->codec_context->extradata, port->format->extradata, + port->format->extradata_size); + + if (codec->capabilities & CODEC_CAP_TRUNCATED) + module->codec_context->flags |= CODEC_FLAG_TRUNCATED; + + if (avcodec_open(module->codec_context, codec) < 0) + { + LOG_ERROR("could not open codec"); + return MMAL_EIO; + } + + /* Set a default format */ + if (module->codec_context->pix_fmt == PIX_FMT_NONE) + module->codec_context->pix_fmt = PIX_FMT_YUV420P; + + /* Copy format to output */ + LOG_DEBUG("avcodec output format %i (%ix%i)", module->codec_context->pix_fmt, + module->codec_context->width, module->codec_context->height); + port->format->es->video.width = module->codec_context->width; + port->format->es->video.height = module->codec_context->height; + mmal_format_copy(component->output[0]->format, port->format); + component->output[0]->format->encoding = pixfmt_to_encoding(module->codec_context->pix_fmt); + if (!component->output[0]->format->es->video.width) + component->output[0]->format->es->video.width = DEFAULT_WIDTH; + if (!component->output[0]->format->es->video.height) + component->output[0]->format->es->video.height = DEFAULT_HEIGHT; + + component->output[0]->priv->pf_set_format(component->output[0]); + + return MMAL_SUCCESS; +} + +/** Set format on a port */ +static MMAL_STATUS_T avcodec_output_port_set_format(MMAL_PORT_T *port) +{ + MMAL_COMPONENT_T *component = port->component; + MMAL_COMPONENT_MODULE_T *module = component->priv->module; + + /* Format can only be set to what is output by the codec */ + if (pixfmt_to_encoding(module->codec_context->pix_fmt) != port->format->encoding) + return MMAL_EINVAL; + + module->pix_fmt = module->codec_context->pix_fmt; + module->width = port->format->es->video.width; + module->height = port->format->es->video.height; + + module->frame_size = + avpicture_fill(&module->layout, 0, module->pix_fmt, module->width, module->height); + if (module->frame_size < 0) + return MMAL_EINVAL; + + /* Calculate the number of planes for this format */ + for (module->planes = 0; module->planes < 4; ) + if (!module->layout.data[module->planes++]) + break; + + port->buffer_size_min = module->frame_size; + port->component->priv->module->output_needs_configuring = 0; + mmal_component_action_trigger(port->component); + + return MMAL_SUCCESS; +} + +/** Enable processing on a port */ +static MMAL_STATUS_T avcodec_port_enable(MMAL_PORT_T *port, MMAL_PORT_BH_CB_T cb) +{ + MMAL_PARAM_UNUSED(port); + MMAL_PARAM_UNUSED(cb); + return MMAL_SUCCESS; +} + +/** Flush a port */ +static MMAL_STATUS_T avcodec_port_flush(MMAL_PORT_T *port) +{ + MMAL_COMPONENT_T *component = port->component; + MMAL_COMPONENT_MODULE_T *module = component->priv->module; + MMAL_BUFFER_HEADER_T *buffer; + MMAL_QUEUE_T *queue; + + if(port->type == MMAL_PORT_TYPE_OUTPUT) + queue = module->queue_out; + else if(port->type == MMAL_PORT_TYPE_INPUT) + queue = module->queue_in; + else + return MMAL_EINVAL; + + /* Flush buffers that our component is holding on to. + * If the reading thread is holding onto a buffer it will send it back ASAP as well + * so no need to care about that. */ + while((buffer = mmal_queue_get(queue))) + mmal_port_buffer_header_callback(port, buffer); + + return MMAL_SUCCESS; +} + +/** Disable processing on a port */ +static MMAL_STATUS_T avcodec_port_disable(MMAL_PORT_T *port) +{ + MMAL_STATUS_T status; + + /* Actions are prevented from running at that point so a flush + * will return all buffers. */ + status = avcodec_port_flush(port); + if(status != MMAL_SUCCESS) + return status; + + return MMAL_SUCCESS; +} + +/*****************************************************************************/ +static void avcodec_send_event_format_changed(MMAL_COMPONENT_T *component, MMAL_PORT_T *port) +{ + MMAL_COMPONENT_MODULE_T *module = component->priv->module; + MMAL_BUFFER_HEADER_T *buffer = NULL; + MMAL_EVENT_FORMAT_CHANGED_T *event; + + /* Get an event buffer */ + module->status = mmal_port_event_get(port, &buffer, MMAL_EVENT_FORMAT_CHANGED); + if (module->status != MMAL_SUCCESS) + { + LOG_ERROR("unable to get an event buffer"); + return; + } + event = mmal_event_format_changed_get(buffer); + + /* Fill in the new format */ + mmal_format_copy(event->format, port->format); + event->format->es->video.width = module->codec_context->width; + event->format->es->video.height = module->codec_context->height; + event->format->encoding = pixfmt_to_encoding(module->codec_context->pix_fmt); + + /* Pass on the buffer requirements */ + event->buffer_num_min = port->buffer_num_min; + event->buffer_size_min = module->codec_context->width * module->codec_context->height * 2; + event->buffer_size_recommended = event->buffer_size_min; + event->buffer_num_recommended = port->buffer_num_recommended; + + module->output_needs_configuring = 1; + mmal_port_event_send(port, buffer); +} + +/*****************************************************************************/ +static MMAL_STATUS_T avcodec_send_eos(MMAL_COMPONENT_T *component, MMAL_PORT_T *port) +{ + MMAL_COMPONENT_MODULE_T *module = component->priv->module; + MMAL_BUFFER_HEADER_T *out = mmal_queue_get(module->queue_out); + + if (!out) + return MMAL_EAGAIN; + + out->length = 0; + out->flags = MMAL_BUFFER_HEADER_FLAG_EOS; + mmal_port_buffer_header_callback(port, out); + return MMAL_SUCCESS; +} + +/*****************************************************************************/ +static MMAL_STATUS_T avcodec_send_picture(MMAL_COMPONENT_T *component, MMAL_PORT_T *port) +{ + MMAL_COMPONENT_MODULE_T *module = component->priv->module; + MMAL_BUFFER_HEADER_T *out; + int i, size; + + /* Detect format changes */ + if (module->codec_context->width != module->width || + module->codec_context->height != module->height || + module->codec_context->pix_fmt != module->pix_fmt) + { + avcodec_send_event_format_changed(component, port); + return MMAL_EAGAIN; + } + + out = mmal_queue_get(module->queue_out); + if (!out) + return MMAL_EAGAIN; + + size = avpicture_layout((AVPicture *)module->picture, module->pix_fmt, + module->width, module->height, out->data, out->alloc_size); + if (size < 0) + { + mmal_queue_put_back(module->queue_out, out); + LOG_ERROR("avpicture_layout failed: %i, %i, %i, %i",module->pix_fmt, + module->width, module->height, out->alloc_size ); + mmal_event_error_send(component, MMAL_EINVAL); + return MMAL_EINVAL; + } + + out->length = size; + out->pts = module->pts; + out->flags = 0; + + out->type->video.planes = module->planes; + for (i = 0; i < 3; i++) + { + out->type->video.offset[i] = (uint64_t)module->layout.data[i]; + out->type->video.pitch[i] = module->layout.linesize[i]; + } + + mmal_port_buffer_header_callback(port, out); + return MMAL_SUCCESS; +} + +/*****************************************************************************/ +static MMAL_BOOL_T avcodec_do_processing(MMAL_COMPONENT_T *component) +{ + MMAL_COMPONENT_MODULE_T *module = component->priv->module; + MMAL_PORT_T *port_in = component->input[0]; + MMAL_PORT_T *port_out = component->output[0]; + MMAL_BUFFER_HEADER_T *in; + AVPacket avpkt; + int used = 0; + + if (module->output_needs_configuring) + return 0; + + if (module->picture_available && + avcodec_send_picture(component, port_out) != MMAL_SUCCESS) + return 0; + + module->picture_available = 0; + + /* Get input buffer to decode */ + in = mmal_queue_get(module->queue_in); + if (!in) + return 0; + + /* Discard empty buffers. EOS buffers are not discarded since they will be used + * to flush the codec. */ + if (!in->length && !(in->flags & MMAL_BUFFER_HEADER_FLAG_EOS)) + goto end; + + /* Avcodec expects padded input data */ + if (in->length && !in->offset) + { + if(in->length + FF_INPUT_BUFFER_PADDING_SIZE <= in->alloc_size) + memset(in->data + in->length, 0, FF_INPUT_BUFFER_PADDING_SIZE); + else + LOG_WARN("could not pad buffer"); // Try to decode the data anyway + } + + /* The actual decoding */ + module->codec_context->reordered_opaque = in->pts; + av_init_packet(&avpkt); + avpkt.data = in->length ? in->data + in->offset : 0; + avpkt.size = in->length; + used = avcodec_decode_video2(module->codec_context, module->picture, + &module->picture_available, &avpkt); + + /* Check for errors */ + if (used < 0 || used > (int)in->length) + { + LOG_ERROR("decoding failed (%i), discarding buffer", used); + used = in->length; + } + + if (module->picture_available) + { + module->pts = module->picture->reordered_opaque; + if (module->pts == MMAL_TIME_UNKNOWN) + module->pts = in->dts; + } + + end: + in->offset += used; + in->length -= used; + + if (in->length) + { + mmal_queue_put_back(module->queue_in, in); + return 1; + } + + /* We want to keep the EOS buffer until all the frames have been flushed */ + if ((in->flags & MMAL_BUFFER_HEADER_FLAG_EOS) && + module->picture_available) + { + mmal_queue_put_back(module->queue_in, in); + return 1; + } + + /* Send EOS */ + if ((in->flags & MMAL_BUFFER_HEADER_FLAG_EOS) && + avcodec_send_eos(component, port_out) != MMAL_SUCCESS) + { + mmal_queue_put_back(module->queue_in, in); + return 0; + } + + in->offset = 0; + mmal_port_buffer_header_callback(port_in, in); + return 1; +} + +/*****************************************************************************/ +static void avcodec_do_processing_loop(MMAL_COMPONENT_T *component) +{ + while (avcodec_do_processing(component)); +} + +/** Buffer sending */ +static MMAL_STATUS_T avcodec_port_send(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) +{ + MMAL_COMPONENT_T *component = port->component; + MMAL_COMPONENT_MODULE_T *module = component->priv->module; + + if(port->type == MMAL_PORT_TYPE_OUTPUT) mmal_queue_put(module->queue_out, buffer); + if(port->type == MMAL_PORT_TYPE_INPUT) mmal_queue_put(module->queue_in, buffer); + mmal_component_action_trigger(port->component); + + return MMAL_SUCCESS; +} + +/** Create an instance of a component */ +static MMAL_STATUS_T mmal_component_create_avcodec(const char *name, MMAL_COMPONENT_T *component) +{ + MMAL_STATUS_T status = MMAL_ENOMEM; + MMAL_COMPONENT_MODULE_T *module; + + /* Check we're the requested component */ + if(strcmp(name, "avcodec." MMAL_VIDEO_DECODE)) + return MMAL_ENOENT; + + /* Allocate our module context */ + component->priv->module = module = vcos_malloc(sizeof(*module), "mmal module"); + memset(module, 0, sizeof(*module)); + + /* Allocate the ports for this component */ + component->input = mmal_ports_alloc(component, 1, MMAL_PORT_TYPE_INPUT, 0); + if(!component->input) goto error; + component->input_num = 1; + component->output = mmal_ports_alloc(component, 1, MMAL_PORT_TYPE_OUTPUT, 0); + if(!component->output) goto error; + component->output_num = 1; + + module->queue_in = mmal_queue_create(); + if(!module->queue_in) goto error; + module->queue_out = mmal_queue_create(); + if(!module->queue_out) goto error; + + module->codec_context = avcodec_alloc_context(); + if(!module->codec_context) goto error; + + component->input[0]->priv->pf_set_format = avcodec_input_port_set_format; + component->input[0]->priv->pf_enable = avcodec_port_enable; + component->input[0]->priv->pf_disable = avcodec_port_disable; + component->input[0]->priv->pf_flush = avcodec_port_flush; + component->input[0]->priv->pf_send = avcodec_port_send; + component->input[0]->buffer_num_min = INPUT_MIN_BUFFER_NUM; + component->input[0]->buffer_num_recommended = INPUT_RECOMMENDED_BUFFER_NUM; + component->input[0]->buffer_size_min = INPUT_MIN_BUFFER_SIZE; + component->input[0]->buffer_size_recommended = INPUT_RECOMMENDED_BUFFER_SIZE; + + component->output[0]->priv->pf_set_format = avcodec_output_port_set_format; + component->output[0]->priv->pf_enable = avcodec_port_enable; + component->output[0]->priv->pf_disable = avcodec_port_disable; + component->output[0]->priv->pf_flush = avcodec_port_flush; + component->output[0]->priv->pf_send = avcodec_port_send; + component->output[0]->buffer_num_min = OUTPUT_MIN_BUFFER_NUM; + component->output[0]->buffer_num_recommended = OUTPUT_RECOMMENDED_BUFFER_NUM; + + component->output[0]->format->type = MMAL_ES_TYPE_VIDEO; + component->output[0]->format->encoding = MMAL_ENCODING_I420; + component->output[0]->format->es->video.width = DEFAULT_WIDTH; + component->output[0]->format->es->video.height = DEFAULT_HEIGHT; + + component->priv->pf_destroy = avcodec_component_destroy; + + status = mmal_component_action_register(component, avcodec_do_processing_loop); + if (status != MMAL_SUCCESS) + goto error; + + return MMAL_SUCCESS; + + error: + avcodec_component_destroy(component); + return status; +} + +static struct { + uint32_t encoding; + int codecid; +} codec_to_encoding_table[] = +{ + {MMAL_ENCODING_H263, CODEC_ID_H263}, + {MMAL_ENCODING_H264, CODEC_ID_H264}, + {MMAL_ENCODING_MP4V, CODEC_ID_MPEG4}, + {MMAL_ENCODING_MP2V, CODEC_ID_MPEG2VIDEO}, + {MMAL_ENCODING_MP1V, CODEC_ID_MPEG1VIDEO}, + {MMAL_ENCODING_WMV3, CODEC_ID_WMV3}, + {MMAL_ENCODING_WMV2, CODEC_ID_WMV2}, + {MMAL_ENCODING_WMV1, CODEC_ID_WMV1}, + {MMAL_ENCODING_WVC1, CODEC_ID_VC1}, + {MMAL_ENCODING_VP6, CODEC_ID_VP6}, +#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT( 52, 68, 2 ) + {MMAL_ENCODING_VP8, CODEC_ID_VP8}, +#endif + {MMAL_ENCODING_THEORA, CODEC_ID_THEORA}, + + {MMAL_ENCODING_GIF, CODEC_ID_GIF}, + {MMAL_ENCODING_PNG, CODEC_ID_PNG}, + {MMAL_ENCODING_PPM, CODEC_ID_PPM}, + {MMAL_ENCODING_BMP, CODEC_ID_BMP}, + {MMAL_ENCODING_JPEG, CODEC_ID_MJPEG}, + + {MMAL_ENCODING_UNKNOWN, CODEC_ID_NONE} +}; + +static uint32_t encoding_to_codecid(uint32_t encoding) +{ + unsigned int i; + for(i = 0; codec_to_encoding_table[i].encoding != MMAL_ENCODING_UNKNOWN; i++) + if(codec_to_encoding_table[i].encoding == encoding) break; + return codec_to_encoding_table[i].codecid; +} + +static struct { + uint32_t encoding; + enum PixelFormat pixfmt; +} pixfmt_to_encoding_table[] = +{ + {MMAL_ENCODING_I420, PIX_FMT_YUV420P}, + {MMAL_ENCODING_I422, PIX_FMT_YUV422P}, + {MMAL_ENCODING_I420, PIX_FMT_YUVJ420P}, // FIXME + {MMAL_ENCODING_I422, PIX_FMT_YUVJ422P}, // FIXME + {MMAL_ENCODING_RGB16, PIX_FMT_RGB565}, + {MMAL_ENCODING_BGR16, PIX_FMT_BGR565}, + {MMAL_ENCODING_RGB24, PIX_FMT_RGB24}, + {MMAL_ENCODING_BGR24, PIX_FMT_BGR24}, + {MMAL_ENCODING_ARGB, PIX_FMT_ARGB}, + {MMAL_ENCODING_RGBA, PIX_FMT_RGBA}, + {MMAL_ENCODING_ABGR, PIX_FMT_ABGR}, + {MMAL_ENCODING_BGRA, PIX_FMT_BGRA}, + {MMAL_ENCODING_UNKNOWN, PIX_FMT_NONE} +}; + +static uint32_t pixfmt_to_encoding(enum PixelFormat pixfmt) +{ + unsigned int i; + for(i = 0; pixfmt_to_encoding_table[i].encoding != MMAL_ENCODING_UNKNOWN; i++) + if(pixfmt_to_encoding_table[i].pixfmt == pixfmt) break; + return pixfmt_to_encoding_table[i].encoding; +} + +MMAL_CONSTRUCTOR(mmal_register_component_avcodec); +void mmal_register_component_avcodec(void) +{ + avcodec_init(); + avcodec_register_all(); + + mmal_component_supplier_register("avcodec", mmal_component_create_avcodec); +} diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/components/clock.c b/external_src/raspicam-0.1.3/dependencies/mmal/components/clock.c new file mode 100644 index 0000000..d59f4e4 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/components/clock.c @@ -0,0 +1,900 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 "mmal.h" +#include "core/mmal_component_private.h" +#include "core/mmal_port_private.h" +#include "util/mmal_util_rational.h" +#include "util/mmal_list.h" +#include "mmal_logging.h" + + +#define CLOCK_PORTS_NUM 5 + +#define MAX_CLOCK_EVENT_SLOTS 16 + +#define DEFAULT_FRAME_RATE 30 /* frames per second */ +#define DEFAULT_CLOCK_LATENCY 60000 /* microseconds */ + +#define FILTER_DURATION 2 /* seconds */ +#define MAX_FILTER_LENGTH 180 /* samples */ + +#define MAX_TIME (~(1LL << 63)) /* microseconds */ +#define MIN_TIME (1LL << 63) /* microseconds */ + +#define ABS(a) ((a) < 0 ? -(a) : (a)) +#define MIN(a,b) ((a) < (b) ? (a) : (b)) +#define MAX(a,b) ((a) > (b) ? (a) : (b)) + +/** Set to 1 to enable additional stream timing log + * messages used for debugging the clock algorithm */ +#define ENABLE_ADDITIONAL_LOGGING 0 +static int clock_additional_logging = ENABLE_ADDITIONAL_LOGGING; + +/*****************************************************************************/ +typedef int64_t TIME_T; + +typedef struct FILTER_T +{ + uint32_t first; /**< index to the oldest sample */ + uint32_t last; /**< index to the most recent sample*/ + uint32_t count; /**< total number of samples in the filter */ + uint32_t length; /**< maximum number of samples */ + TIME_T sum; /**< sum of all samples currently in the filter */ + TIME_T h[MAX_FILTER_LENGTH]; /**< filter history */ +} FILTER_T; + +/** Frame statistics for a stream */ +typedef struct CLOCK_STREAM_T +{ + uint32_t id; /**< for debug purposes */ + + MMAL_BOOL_T started; /**< TRUE at least one frame has been received */ + + TIME_T pts; /**< most recent time-stamp seen */ + TIME_T stc; /**< most recent wall-time seen */ + + TIME_T mt_off; /**< offset of the current time stamp from the + arrival time, i.e. PTS - STC */ + TIME_T mt_off_avg; /**< rolling average of the media time offset */ + TIME_T mt_off_std; /**< approximate standard deviation of the media + time offset */ + + FILTER_T avg_filter; /**< moving average filter */ + FILTER_T std_filter; /**< (approximate) standard deviation filter */ +} CLOCK_STREAM_T; + +/** Clock stream events */ +typedef enum CLOCK_STREAM_EVENT_T +{ + CLOCK_STREAM_EVENT_NONE, + CLOCK_STREAM_EVENT_STARTED, /**< first data received */ + CLOCK_STREAM_EVENT_DISCONT, /**< discontinuity detected */ + CLOCK_STREAM_EVENT_FRAME_COMPLETE, /**< complete frame received */ +} CLOCK_STREAM_EVENT_T; + +/** Clock port event */ +typedef struct CLOCK_PORT_EVENT_T +{ + MMAL_LIST_ELEMENT_T link; /**< must be first */ + MMAL_PORT_T *port; /**< clock port where the event occurred */ + MMAL_CLOCK_EVENT_T event; /**< event data */ +} CLOCK_PORT_EVENT_T; + +/** Clock component context */ +typedef struct MMAL_COMPONENT_MODULE_T +{ + MMAL_STATUS_T status; /**< current status of the component */ + + MMAL_BOOL_T clock_discont; /**< TRUE -> clock discontinuity detected */ + + uint32_t stream_min_id; /**< id of selected minimum stream (debugging only) */ + uint32_t stream_max_id; /**< if of selected maximum stream (debugging only) */ + + TIME_T mt_off_target; /**< target clock media time offset */ + TIME_T mt_off_clk; /**< current clock media time offset */ + + TIME_T adj_p; /**< proportional clock adjustment */ + TIME_T adj_m; /**< clock adjustment factor (between 1 and 0) */ + TIME_T adj; /**< final clock adjustment */ + + TIME_T stc_at_update; /**< the value of the STC the last time the clocks + were updated */ + + TIME_T frame_duration; /**< one frame period (microseconds) */ + MMAL_RATIONAL_T frame_rate; /**< frame rate set by the client */ + uint32_t frame_rate_log2; /**< frame rate expressed as a power of two */ + + MMAL_RATIONAL_T scale; /**< current clock scale factor */ + MMAL_BOOL_T pending_scale; /**< TRUE -> scale change is pending */ + + MMAL_CLOCK_LATENCY_T latency; + MMAL_CLOCK_UPDATE_THRESHOLD_T update_threshold; + MMAL_CLOCK_DISCONT_THRESHOLD_T discont_threshold; + MMAL_CLOCK_REQUEST_THRESHOLD_T request_threshold; + + /** Clock port events */ + struct + { + MMAL_LIST_T* queue; /**< pending events */ + MMAL_LIST_T* free; /**< available event slots */ + CLOCK_PORT_EVENT_T pool[MAX_CLOCK_EVENT_SLOTS]; + } events; +} MMAL_COMPONENT_MODULE_T; + +/** Clock port context */ +typedef struct MMAL_PORT_MODULE_T +{ + CLOCK_STREAM_T *stream; /**< stream associated with this clock port */ +} MMAL_PORT_MODULE_T; + + +/*****************************************************************************/ +/** Round x up to the next power of two */ +static uint32_t next_pow2(uint32_t x) +{ + x--; + x = (x >> 1) | x; + x = (x >> 2) | x; + x = (x >> 4) | x; + x = (x >> 8) | x; + x = (x >> 16) | x; + return ++x; +} + +/** Given a power of 2 value, return the number of bit shifts */ +static uint32_t pow2_shift(uint32_t x) +{ + static const uint32_t BIT_POSITIONS[32] = + { + 0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, + 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9 + }; + + return BIT_POSITIONS[((x & -x) * 0x077CB531U) >> 27]; +} + +/** Add 2 values with saturation */ +static inline TIME_T saturate_add(TIME_T a, TIME_T b) +{ + TIME_T sum = a + b; + if (a > 0 && b > 0 && sum < 0) + sum = MAX_TIME; + else if (a < 0 && b < 0 && sum > 0) + sum = MIN_TIME; + return sum; +} + +/*****************************************************************************/ +/** Filter reset */ +static void filter_init(FILTER_T *filter, uint32_t length) +{ + memset(filter, 0, sizeof(*filter)); + filter->last = length - 1; + filter->length = length; +}; + +/** Increment filter index modulo the length */ +static inline uint32_t filter_index_wrap(uint32_t index, uint32_t length) +{ + return (++index < length) ? index : 0; +} + +/** Remove the oldest sample from the filter */ +static void filter_drop(FILTER_T *filter) +{ + if (!filter->count) + return; + + filter->sum -= filter->h[filter->first]; + filter->first = filter_index_wrap(filter->first, filter->length); + filter->count--; +} + +/** Add a new sample (and drop the oldest when full) */ +static void filter_insert(FILTER_T *filter, TIME_T sample) +{ + if (filter->count == filter->length) + filter_drop(filter); + + filter->last = filter_index_wrap(filter->last, filter->length); + filter->h[filter->last] = sample; + filter->sum = saturate_add(filter->sum, sample); + filter->count++; +} + +/*****************************************************************************/ +/** Create and initialise a clock stream */ +static MMAL_BOOL_T clock_create_stream(CLOCK_STREAM_T **stream, uint32_t id, uint32_t filter_length) +{ + CLOCK_STREAM_T *s = vcos_calloc(1, sizeof(CLOCK_STREAM_T), "clock stream"); + if (!s) + { + LOG_ERROR("failed to allocate stream"); + return MMAL_FALSE; + } + + s->id = id; + + filter_init(&s->avg_filter, filter_length); + filter_init(&s->std_filter, filter_length); + + *stream = s; + return MMAL_TRUE; +} + +/** Flag this stream as started */ +static void clock_start_stream(CLOCK_STREAM_T *stream, TIME_T stc, TIME_T pts) +{ + stream->started = MMAL_TRUE; + stream->pts = pts; + stream->stc = stc; +} + +/** Reset the internal state of a stream */ +static void clock_reset_stream(CLOCK_STREAM_T *stream) +{ + if (!stream) + return; + + stream->pts = 0; + stream->stc = 0; + stream->mt_off = 0; + stream->mt_off_avg = 0; + stream->mt_off_std = 0; + stream->started = MMAL_FALSE; + + filter_init(&stream->avg_filter, stream->avg_filter.length); + filter_init(&stream->std_filter, stream->std_filter.length); +} + +/** Update the internal state of a stream */ +static CLOCK_STREAM_EVENT_T clock_update_stream(CLOCK_STREAM_T *stream, TIME_T stc, TIME_T pts, + TIME_T discont_threshold) +{ + CLOCK_STREAM_EVENT_T event = CLOCK_STREAM_EVENT_NONE; + TIME_T pts_delta, stc_delta; + + if (pts == MMAL_TIME_UNKNOWN) + { + LOG_TRACE("ignoring invalid timestamp received at %"PRIi64, stc); + return CLOCK_STREAM_EVENT_NONE; + } + + if (!stream->started) + { + LOG_TRACE("stream %d started %"PRIi64" %"PRIi64, stream->id, stc, pts); + clock_start_stream(stream, stc, pts); + return CLOCK_STREAM_EVENT_STARTED; + } + + /* XXX: This should really use the buffer flags to determine if a complete + * frame has been received. However, not all clients set MMAL buffer flags + * correctly (if at all). */ + pts_delta = pts - stream->pts; + stc_delta = stc - stream->stc; + + /* Check for discontinuities. */ + if ((ABS(pts_delta) > discont_threshold) || (ABS(stc_delta) > discont_threshold)) + { + LOG_ERROR("discontinuity detected on stream %d %"PRIi64" %"PRIi64" %"PRIi64, + stream->id, pts_delta, stc_delta, discont_threshold); + return CLOCK_STREAM_EVENT_DISCONT; + } + + if (pts_delta) + { + /* A complete frame has now been received, so update the stream's notion of media time */ + stream->mt_off = stream->pts - stream->stc; + + filter_insert(&stream->avg_filter, stream->mt_off); + stream->mt_off_avg = stream->avg_filter.sum / stream->avg_filter.count; + + filter_insert(&stream->std_filter, ABS(stream->mt_off - stream->mt_off_avg)); + stream->mt_off_std = stream->std_filter.sum / stream->std_filter.count; + + LOG_TRACE("stream %d %"PRIi64" %"PRIi64" %"PRIi64" %"PRIi64, + stream->id, stream->stc, stream->pts, stream->mt_off_avg, stream->mt_off); + + event = CLOCK_STREAM_EVENT_FRAME_COMPLETE; + } + + stream->pts = pts; + stream->stc = stc; + + return event; +} + +/*****************************************************************************/ +/** Start all enabled clock ports, making sure all use the same thresholds */ +static void clock_start_clocks(MMAL_COMPONENT_T *component, TIME_T media_time) +{ + MMAL_COMPONENT_MODULE_T *module = component->priv->module; + unsigned i; + + for (i = 0; i < component->clock_num; ++i) + { + MMAL_PORT_T *port = component->clock[i]; + if (port->is_enabled) + { + LOG_TRACE("starting clock %d with time %"PRIi64, port->index, media_time); + mmal_port_clock_reference_set(port, MMAL_TRUE); + mmal_port_clock_media_time_set(port, media_time); + mmal_port_clock_update_threshold_set(port, &module->update_threshold); + mmal_port_clock_discont_threshold_set(port, &module->discont_threshold); + mmal_port_clock_request_threshold_set(port, &module->request_threshold); + mmal_port_clock_active_set(port, MMAL_TRUE); + } + } +} + +/** Stop (and flush) all enabled clock ports */ +static void clock_stop_clocks(MMAL_COMPONENT_T *component) +{ + unsigned i; + + for (i = 0; i < component->clock_num; ++i) + { + MMAL_PORT_T *port = component->clock[i]; + if (port->is_enabled) + { + LOG_TRACE("stopping clock %d", port->index); + mmal_port_clock_request_flush(port); + mmal_port_clock_active_set(port, MMAL_FALSE); + } + } +} + +/** Reset the internal state of all streams in order to rebase clock + * adjustment calculations */ +static void clock_reset_clocks(MMAL_COMPONENT_T *component) +{ + MMAL_COMPONENT_MODULE_T *module = component->priv->module; + unsigned i; + + for (i = 0; i < component->clock_num; ++i) + clock_reset_stream(component->clock[i]->priv->module->stream); + + module->clock_discont = MMAL_TRUE; +} + +/** Change the media-time for all enabled clock ports */ +static void clock_set_media_time(MMAL_COMPONENT_T *component, TIME_T media_time) +{ + unsigned i; + + for (i = 0; i < component->clock_num; ++i) + { + MMAL_PORT_T *port = component->clock[i]; + if (port->is_enabled) + mmal_port_clock_media_time_set(port, media_time); + } +} + +/** Change the scale for all clock ports */ +static void clock_set_scale(MMAL_COMPONENT_T *component, MMAL_RATIONAL_T scale) +{ + unsigned i; + + for (i = 0; i < component->clock_num; ++i) + mmal_port_clock_scale_set(component->clock[i], scale); + + component->priv->module->pending_scale = 0; +} + +/** Update the average and standard deviation calculations for all streams + * (dropping samples where necessary) and return the minimum and maximum + * streams */ +static MMAL_BOOL_T clock_get_mt_off_avg(MMAL_COMPONENT_T *component, TIME_T stc, + CLOCK_STREAM_T **minimum, CLOCK_STREAM_T **maximum) +{ + MMAL_COMPONENT_MODULE_T *module = component->priv->module; + TIME_T drop_threshold = 6 * module->frame_duration; + TIME_T reset_threshold = module->latency.target << 1; + TIME_T avg_min = MAX_TIME; + TIME_T avg_max = MIN_TIME; + TIME_T avg_bias; + TIME_T stc_delta; + unsigned i; + + *minimum = 0; + *maximum = 0; + + for (i = 0; i < component->clock_num; ++i) + { + CLOCK_STREAM_T *stream = component->clock[i]->priv->module->stream; + if (stream) + { + stc_delta = stc - stream->stc; + + /* Drop samples from the moving average and standard deviation filters */ + if (stc_delta > reset_threshold) + { + filter_init(&stream->avg_filter, stream->avg_filter.length); + filter_init(&stream->std_filter, stream->std_filter.length); + LOG_TRACE("reset stream %d filters due to stc_delta %"PRIi64, stream->id, stc_delta); + } + else if (stc_delta > drop_threshold) + { + filter_drop(&stream->avg_filter); + filter_drop(&stream->std_filter); + LOG_TRACE("drop stream %d filter samples due to stc_delta %"PRIi64, stream->id, stc_delta); + } + + /* No point in continuing if filters are empty */ + if (!stream->avg_filter.count) + continue; + + /* Calculate new average and standard deviation for the stream */ + stream->mt_off_avg = stream->avg_filter.sum / stream->avg_filter.count; + stream->mt_off_std = stream->std_filter.sum / stream->std_filter.count; + + /* Select the minimum and maximum average between all active streams */ + avg_bias = (stream->avg_filter.length - stream->avg_filter.count) * ABS(stream->mt_off_avg) / stream->avg_filter.length; + if ((stream->mt_off_avg + avg_bias) < avg_min) + { + avg_min = stream->mt_off_avg; + *minimum = stream; + LOG_TRACE("found min on %d mt_off_avg %"PRIi64" mt_off_std %"PRIi64" avg_bias %"PRIi64" count %d", + stream->id, stream->mt_off_avg, stream->mt_off_std, avg_bias, stream->avg_filter.count); + } + if ((stream->mt_off_avg - avg_bias) > avg_max) + { + avg_max = stream->mt_off_avg; + *maximum = stream; + LOG_TRACE("found max on %d mt_off_avg %"PRIi64" mt_off_std %"PRIi64" avg_bias %"PRIi64" count %d", + stream->id, stream->mt_off_avg, stream->mt_off_std, avg_bias, stream->avg_filter.count); + } + } + } + + return (*minimum) && (*maximum); +} + +/** Adjust the media-time of the playback clocks based on current timing statistics */ +static void clock_adjust_clocks(MMAL_COMPONENT_T *component, TIME_T stc) +{ + MMAL_COMPONENT_MODULE_T *module = component->priv->module; + CLOCK_STREAM_T *stream_min; + CLOCK_STREAM_T *stream_max; + TIME_T mt_off_clk; + TIME_T stc_prev; + + if (!clock_get_mt_off_avg(component, stc, &stream_min, &stream_max)) + return; + + module->stream_min_id = stream_min->id; + module->stream_max_id = stream_max->id; + + /* Calculate the actual media-time offset seen by the clock */ + mt_off_clk = mmal_port_clock_media_time_get(component->clock[0]) - stc; + + stc_prev = module->stc_at_update; + module->stc_at_update = stc; + + /* If there has been a discontinuity, restart the clock, + * else use the clock control loop to apply a clock adjustment */ + if (module->clock_discont) + { + module->clock_discont = MMAL_FALSE; + + module->mt_off_clk = stream_min->mt_off_avg - module->latency.target; + module->mt_off_target = module->mt_off_clk; + + clock_stop_clocks(component); + clock_start_clocks(component, module->mt_off_clk + stc); + } + else + { + /* Determine the new clock target */ + TIME_T mt_off_target_max = stream_max->mt_off_avg - module->latency.target; + TIME_T mt_off_target_min = stream_min->mt_off_avg - module->frame_duration; + module->mt_off_target = MIN(mt_off_target_max, mt_off_target_min); + + /* Calculate the proportional adjustment, capped by the attack rate + * set by the client */ + TIME_T stc_delta = (stc > stc_prev) ? (stc - stc_prev) : 0; + TIME_T adj_p_max = stc_delta * module->latency.attack_rate / module->latency.attack_period; + + module->adj_p = module->mt_off_target - module->mt_off_clk; + if (module->adj_p < -adj_p_max) + module->adj_p = -adj_p_max; + else if (module->adj_p > adj_p_max) + module->adj_p = adj_p_max; + + /* Calculate the confidence of the adjustment using the approximate + * standard deviation for the selected stream: + * + * adj_m = 1.0 - STD * FPS / 4 + * + * The adjustment factor is scaled up by 2^20 which is an approximation + * of 1000000 (microseconds per second) and the frame rate is assumed + * to be either 32 or 64 which are approximations for 24/25/30 and 60 + * fps to avoid divisions. This has a lower limit of 0. */ + module->adj_m = + MAX((1 << 20) - ((stream_min->mt_off_std << module->frame_rate_log2) >> 2), 0); + + /* Modulate the proportional adjustment by the sample confidence + * and apply the adjustment to the current clock */ + module->adj = (module->adj_p * module->adj_m) >> 20; + module->adj = (module->adj * (stream_min->avg_filter.count << 8) / stream_min->avg_filter.length) >> 8; + module->mt_off_clk += module->adj; + + clock_set_media_time(component, module->mt_off_clk + stc); + } + + /* Any pending clock scale changes can now be applied */ + if (component->priv->module->pending_scale) + clock_set_scale(component, component->priv->module->scale); +} + +/*****************************************************************************/ +static void clock_process_stream_event(MMAL_COMPONENT_T *component, CLOCK_STREAM_T *stream, + CLOCK_STREAM_EVENT_T event, TIME_T stc) +{ + MMAL_COMPONENT_MODULE_T *module = component->priv->module; + + switch (event) + { + case CLOCK_STREAM_EVENT_FRAME_COMPLETE: + clock_adjust_clocks(component, stc); + if (clock_additional_logging) + { + VCOS_ALERT("STRM_%d %"PRIi64" %"PRIi64" %"PRIi64" %"PRIi64" %"PRIi64" %"PRIi64" %d %" + PRIi64" %"PRIi64" %"PRIi64" %"PRIi64" %"PRIi64" %u %u", + stream->id, stream->stc, stream->pts, stream->mt_off_avg, stream->mt_off, + stream->mt_off_std, ABS(stream->mt_off - stream->mt_off_avg), stream->avg_filter.count, + module->mt_off_clk, module->mt_off_target, module->adj_p, module->adj_m, module->adj, + module->stream_min_id, module->stream_max_id); + } + break; + case CLOCK_STREAM_EVENT_DISCONT: + clock_reset_clocks(component); + break; + default: + /* ignore all other events */ + break; + } +} + +/** Handler for input buffer events */ +static void clock_process_input_buffer_info_event(MMAL_COMPONENT_T *component, MMAL_PORT_T *port, + const MMAL_CLOCK_BUFFER_INFO_T *info) +{ + CLOCK_STREAM_EVENT_T stream_event = CLOCK_STREAM_EVENT_NONE; + MMAL_COMPONENT_MODULE_T *module = component->priv->module; + MMAL_PORT_MODULE_T *port_module = port->priv->module; + TIME_T stc = (TIME_T)((uint64_t)info->arrival_time); + TIME_T pts = info->time_stamp; + + LOG_TRACE("port %d %"PRIi64" %"PRIi64, port->index, stc, pts); + + if (!port_module->stream) + { + /* First data received for this stream */ + uint32_t filter_length = module->frame_rate.num * FILTER_DURATION / + module->frame_rate.den; + if (!clock_create_stream(&port_module->stream, port->index, filter_length)) + return; + } + + stream_event = clock_update_stream(port_module->stream, stc, pts, module->discont_threshold.threshold); + + clock_process_stream_event(component, port_module->stream, stream_event, stc); +} + +/** Handler for clock scale events */ +static void clock_process_scale_event(MMAL_COMPONENT_T *component, MMAL_RATIONAL_T scale) +{ + /* When pausing the clock (i.e. scale = 0.0), apply the scale change + * immediately. However, when resuming the clock (i.e. scale = 1.0), + * the scale change can only be applied the next time new buffer timing + * information is received. This ensures that clocks resume with the + * correct media-time. */ + if (scale.num == 0) + { + component->priv->module->scale = scale; + clock_set_scale(component, scale); + } + else + { + /* Only support scale == 1.0 */ + if (!mmal_rational_equal(component->priv->module->scale, scale) && + (scale.num == scale.den)) + { + component->priv->module->scale = scale; + component->priv->module->pending_scale = 1; + clock_reset_clocks(component); + } + } +} + +/** Handler for update threshold events */ +static void clock_process_update_threshold_event(MMAL_COMPONENT_T *component, const MMAL_CLOCK_UPDATE_THRESHOLD_T *threshold) +{ + unsigned i; + + component->priv->module->update_threshold = *threshold; + + for (i = 0; i < component->clock_num; ++i) + mmal_port_clock_update_threshold_set(component->clock[i], threshold); +} + +/** Handler for discontinuity threshold events */ +static void clock_process_discont_threshold_event(MMAL_COMPONENT_T *component, const MMAL_CLOCK_DISCONT_THRESHOLD_T *threshold) +{ + unsigned i; + + component->priv->module->discont_threshold = *threshold; + + for (i = 0; i < component->clock_num; ++i) + mmal_port_clock_discont_threshold_set(component->clock[i], threshold); +} + +/** Handler for request threshold events */ +static void clock_process_request_threshold_event(MMAL_COMPONENT_T *component, const MMAL_CLOCK_REQUEST_THRESHOLD_T *threshold) +{ + unsigned i; + + component->priv->module->request_threshold = *threshold; + + for (i = 0; i < component->clock_num; ++i) + mmal_port_clock_request_threshold_set(component->clock[i], threshold); +} + +/** Handler for latency events */ +static void clock_process_latency_event(MMAL_COMPONENT_T *component, const MMAL_CLOCK_LATENCY_T *latency) +{ + component->priv->module->latency = *latency; + + clock_reset_clocks(component); +} + +/** Add a clock port event to the queue and trigger the action thread */ +static MMAL_STATUS_T clock_event_queue(MMAL_COMPONENT_T *component, MMAL_PORT_T *port, const MMAL_CLOCK_EVENT_T *event) +{ + CLOCK_PORT_EVENT_T *slot = (CLOCK_PORT_EVENT_T*)mmal_list_pop_front(component->priv->module->events.free); + if (!slot) + { + LOG_ERROR("no event slots available"); + return MMAL_ENOSPC; + } + + slot->port = port; + slot->event = *event; + mmal_list_push_back(component->priv->module->events.queue, &slot->link); + + return mmal_component_action_trigger(component); +} + +/** Get the next clock port event in the queue */ +static MMAL_STATUS_T clock_event_dequeue(MMAL_COMPONENT_T *component, CLOCK_PORT_EVENT_T *port_event) +{ + CLOCK_PORT_EVENT_T *slot = (CLOCK_PORT_EVENT_T*)mmal_list_pop_front(component->priv->module->events.queue); + if (!slot) + return MMAL_EINVAL; + + port_event->port = slot->port; + port_event->event = slot->event; + mmal_list_push_back(component->priv->module->events.free, &slot->link); + + if (port_event->event.buffer) + { + port_event->event.buffer->length = 0; + mmal_port_buffer_header_callback(port_event->port, port_event->event.buffer); + } + + return MMAL_SUCCESS; +} + +/** Event callback from a clock port */ +static void clock_event_cb(MMAL_PORT_T *port, const MMAL_CLOCK_EVENT_T *event) +{ + clock_event_queue(port->component, port, event); +} + + +/*****************************************************************************/ +/** Actual processing function */ +static MMAL_BOOL_T clock_do_processing(MMAL_COMPONENT_T *component) +{ + CLOCK_PORT_EVENT_T port_event; + + if (clock_event_dequeue(component, &port_event) != MMAL_SUCCESS) + return MMAL_FALSE; /* No more external events to process */ + + /* Process external events (coming from clock ports) */ + switch (port_event.event.id) + { + case MMAL_CLOCK_EVENT_SCALE: + clock_process_scale_event(component, port_event.event.data.scale); + break; + case MMAL_CLOCK_EVENT_UPDATE_THRESHOLD: + clock_process_update_threshold_event(component, &port_event.event.data.update_threshold); + break; + case MMAL_CLOCK_EVENT_DISCONT_THRESHOLD: + clock_process_discont_threshold_event(component, &port_event.event.data.discont_threshold); + break; + case MMAL_CLOCK_EVENT_REQUEST_THRESHOLD: + clock_process_request_threshold_event(component, &port_event.event.data.request_threshold); + break; + case MMAL_CLOCK_EVENT_LATENCY: + clock_process_latency_event(component, &port_event.event.data.latency); + break; + case MMAL_CLOCK_EVENT_INPUT_BUFFER_INFO: + clock_process_input_buffer_info_event(component, port_event.port, &port_event.event.data.buffer); + break; + default: + break; + } + + return MMAL_TRUE; +} + +/** Component action thread */ +static void clock_do_processing_loop(MMAL_COMPONENT_T *component) +{ + while (clock_do_processing(component)); +} + + +/*****************************************************************************/ +/** Set a parameter on the clock component's control port */ +static MMAL_STATUS_T clock_control_parameter_set(MMAL_PORT_T *port, const MMAL_PARAMETER_HEADER_T *param) +{ + MMAL_COMPONENT_T *component = port->component; + MMAL_COMPONENT_MODULE_T *module = component->priv->module; + MMAL_STATUS_T status = MMAL_SUCCESS; + + switch (param->id) + { + case MMAL_PARAMETER_CLOCK_FRAME_RATE: + { + const MMAL_PARAMETER_FRAME_RATE_T *p = (const MMAL_PARAMETER_FRAME_RATE_T *)param; + module->frame_rate = p->frame_rate; + /* XXX: take frame_rate.den into account */ + module->frame_rate_log2 = pow2_shift(next_pow2(module->frame_rate.num)); + module->frame_duration = p->frame_rate.den * 1000000 / p->frame_rate.num; + LOG_TRACE("frame rate %d/%d (%u) duration %"PRIi64, + module->frame_rate.num, module->frame_rate.den, + module->frame_rate_log2, module->frame_duration); + } + break; + case MMAL_PARAMETER_CLOCK_LATENCY: + { + /* Changing the latency setting requires a reset of the clock algorithm, but + * that can only be safely done from within the component's worker thread. + * So, queue the new latency setting as a clock event. */ + const MMAL_PARAMETER_CLOCK_LATENCY_T *p = (const MMAL_PARAMETER_CLOCK_LATENCY_T *)param; + MMAL_CLOCK_EVENT_T event = { MMAL_CLOCK_EVENT_LATENCY, MMAL_CLOCK_EVENT_MAGIC }; + + LOG_TRACE("latency target %"PRIi64" attack %"PRIi64"/%"PRIi64, + p->value.target, p->value.attack_rate, p->value.attack_period); + + event.data.latency = p->value; + status = clock_event_queue(port->component, port, &event); + } + break; + default: + LOG_ERROR("parameter not supported (0x%x)", param->id); + status = MMAL_ENOSYS; + break; + } + return status; +} + +/** Destroy a previously created component */ +static MMAL_STATUS_T clock_component_destroy(MMAL_COMPONENT_T *component) +{ + MMAL_COMPONENT_MODULE_T *module = component->priv->module; + unsigned int i; + + if (module->events.free) + mmal_list_destroy(module->events.free); + + if (module->events.queue) + mmal_list_destroy(module->events.queue); + + if (component->clock_num) + { + for (i = 0; i < component->clock_num; ++i) + vcos_free(component->clock[i]->priv->module->stream); + + mmal_ports_clock_free(component->clock, component->clock_num); + } + + vcos_free(module); + + return MMAL_SUCCESS; +} + +/** Create an instance of a clock component */ +static MMAL_STATUS_T mmal_component_create_clock(const char *name, MMAL_COMPONENT_T *component) +{ + int i; + MMAL_COMPONENT_MODULE_T *module; + MMAL_STATUS_T status = MMAL_ENOMEM; + MMAL_PARAM_UNUSED(name); + + /* Allocate the context for our module */ + component->priv->module = module = vcos_malloc(sizeof(*module), "mmal module"); + if (!module) + return MMAL_ENOMEM; + memset(module, 0, sizeof(*module)); + + component->priv->pf_destroy = clock_component_destroy; + + /* Create the clock ports (clock ports are managed by the framework) */ + component->clock = mmal_ports_clock_alloc(component, CLOCK_PORTS_NUM, + sizeof(MMAL_PORT_MODULE_T), clock_event_cb); + if (!component->clock) + goto error; + component->clock_num = CLOCK_PORTS_NUM; + + component->control->priv->pf_parameter_set = clock_control_parameter_set; + + /* Setup event slots */ + module->events.free = mmal_list_create(); + module->events.queue = mmal_list_create(); + if (!module->events.free || !module->events.queue) + { + LOG_ERROR("failed to create list %p %p", module->events.free, module->events.queue); + goto error; + } + for (i = 0; i < MAX_CLOCK_EVENT_SLOTS; ++i) + mmal_list_push_back(module->events.free, &module->events.pool[i].link); + + component->priv->priority = VCOS_THREAD_PRI_REALTIME; + status = mmal_component_action_register(component, clock_do_processing_loop); + + module->clock_discont = MMAL_TRUE; + module->frame_rate.num = DEFAULT_FRAME_RATE; + module->frame_rate.den = 1; + + module->scale = mmal_port_clock_scale_get(component->clock[0]); + + memset(&module->latency, 0, sizeof(module->latency)); + module->latency.target = DEFAULT_CLOCK_LATENCY; + + mmal_port_clock_update_threshold_get(component->clock[0], &module->update_threshold); + mmal_port_clock_discont_threshold_get(component->clock[0], &module->discont_threshold); + mmal_port_clock_request_threshold_get(component->clock[0], &module->request_threshold); + + return status; + + error: + clock_component_destroy(component); + return status; +} + + +/*****************************************************************************/ +MMAL_CONSTRUCTOR(mmal_register_component_clock); +void mmal_register_component_clock(void) +{ + mmal_component_supplier_register("clock", mmal_component_create_clock); +} diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/components/container_reader.c b/external_src/raspicam-0.1.3/dependencies/mmal/components/container_reader.c new file mode 100644 index 0000000..b4e77da --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/components/container_reader.c @@ -0,0 +1,1000 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 "mmal.h" +#include "core/mmal_component_private.h" +#include "core/mmal_port_private.h" +#include "mmal_logging.h" + +#include "containers/containers.h" +#include "containers/containers_codecs.h" +#include "containers/core/containers_utils.h" + +#define READER_MAX_URI_LENGTH 1024 + +#define WRITER_PORTS_NUM 3 /**< 3 ports should be enough for video + audio + subpicture */ + +/* Buffering requirements */ +#define READER_MIN_BUFFER_SIZE (2*1024) +#define READER_MIN_BUFFER_NUM 1 +#define READER_RECOMMENDED_BUFFER_SIZE (32*1024) +#define READER_RECOMMENDED_BUFFER_NUM 10 + +/*****************************************************************************/ + +/** Private context for this component */ +typedef struct MMAL_COMPONENT_MODULE_T +{ + VC_CONTAINER_T *container; + char uri[READER_MAX_URI_LENGTH+1]; + unsigned int ports; + + MMAL_BOOL_T writer; + MMAL_BOOL_T error; + + /* Reader specific */ + MMAL_BOOL_T packet_logged; + + /* Writer specific */ + unsigned int port_last_used; + unsigned int port_writing_frame; + +} MMAL_COMPONENT_MODULE_T; + +typedef struct MMAL_PORT_MODULE_T +{ + unsigned int track; + MMAL_QUEUE_T *queue; + + MMAL_BOOL_T flush; + MMAL_BOOL_T eos; + + VC_CONTAINER_ES_FORMAT_T *format; /**< Format description for the elementary stream */ + +} MMAL_PORT_MODULE_T; + +/*****************************************************************************/ +static struct { + VC_CONTAINER_FOURCC_T codec; + MMAL_FOURCC_T encoding; + VC_CONTAINER_FOURCC_T codec_variant; + MMAL_FOURCC_T encoding_variant; +} encoding_table[] = +{ + {VC_CONTAINER_CODEC_H263, MMAL_ENCODING_H263, 0, 0}, + {VC_CONTAINER_CODEC_H264, MMAL_ENCODING_H264, 0, 0}, + {VC_CONTAINER_CODEC_H264, MMAL_ENCODING_H264, + VC_CONTAINER_VARIANT_H264_AVC1, MMAL_ENCODING_VARIANT_H264_AVC1}, + {VC_CONTAINER_CODEC_H264, MMAL_ENCODING_H264, + VC_CONTAINER_VARIANT_H264_RAW, MMAL_ENCODING_VARIANT_H264_RAW}, + {VC_CONTAINER_CODEC_MP4V, MMAL_ENCODING_MP4V, 0, 0}, + {VC_CONTAINER_CODEC_MP2V, MMAL_ENCODING_MP2V, 0, 0}, + {VC_CONTAINER_CODEC_MP1V, MMAL_ENCODING_MP1V, 0, 0}, + {VC_CONTAINER_CODEC_WMV3, MMAL_ENCODING_WMV3, 0, 0}, + {VC_CONTAINER_CODEC_WMV2, MMAL_ENCODING_WMV2, 0, 0}, + {VC_CONTAINER_CODEC_WMV1, MMAL_ENCODING_WMV1, 0, 0}, + {VC_CONTAINER_CODEC_WVC1, MMAL_ENCODING_WVC1, 0, 0}, + {VC_CONTAINER_CODEC_VP6, MMAL_ENCODING_VP6, 0, 0}, + {VC_CONTAINER_CODEC_VP7, MMAL_ENCODING_VP7, 0, 0}, + {VC_CONTAINER_CODEC_VP8, MMAL_ENCODING_VP8, 0, 0}, + {VC_CONTAINER_CODEC_THEORA, MMAL_ENCODING_THEORA, 0, 0}, + {VC_CONTAINER_CODEC_SPARK, MMAL_ENCODING_SPARK, 0, 0}, + + {VC_CONTAINER_CODEC_GIF, MMAL_ENCODING_GIF, 0, 0}, + {VC_CONTAINER_CODEC_JPEG, MMAL_ENCODING_JPEG, 0, 0}, + {VC_CONTAINER_CODEC_PNG, MMAL_ENCODING_PNG, 0, 0}, + {VC_CONTAINER_CODEC_PPM, MMAL_ENCODING_PPM, 0, 0}, + {VC_CONTAINER_CODEC_TGA, MMAL_ENCODING_TGA, 0, 0}, + {VC_CONTAINER_CODEC_BMP, MMAL_ENCODING_BMP, 0, 0}, + + {VC_CONTAINER_CODEC_PCM_SIGNED_BE, MMAL_ENCODING_PCM_SIGNED_BE, 0, 0}, + {VC_CONTAINER_CODEC_PCM_UNSIGNED_BE,MMAL_ENCODING_PCM_UNSIGNED_BE, 0, 0}, + {VC_CONTAINER_CODEC_PCM_SIGNED_LE, MMAL_ENCODING_PCM_SIGNED_LE, 0, 0}, + {VC_CONTAINER_CODEC_PCM_UNSIGNED_LE,MMAL_ENCODING_PCM_UNSIGNED_LE, 0, 0}, + {VC_CONTAINER_CODEC_PCM_FLOAT_BE, MMAL_ENCODING_PCM_FLOAT_BE, 0, 0}, + {VC_CONTAINER_CODEC_PCM_FLOAT_LE, MMAL_ENCODING_PCM_FLOAT_LE, 0, 0}, + + {VC_CONTAINER_CODEC_MPGA, MMAL_ENCODING_MPGA, 0, 0}, + {VC_CONTAINER_CODEC_MP4A, MMAL_ENCODING_MP4A, 0, 0}, + {VC_CONTAINER_CODEC_ALAW, MMAL_ENCODING_ALAW, 0, 0}, + {VC_CONTAINER_CODEC_MULAW, MMAL_ENCODING_MULAW, 0, 0}, + {VC_CONTAINER_CODEC_ADPCM_MS, MMAL_ENCODING_ADPCM_MS, 0, 0}, + {VC_CONTAINER_CODEC_ADPCM_IMA_MS, MMAL_ENCODING_ADPCM_IMA_MS, 0, 0}, + {VC_CONTAINER_CODEC_ADPCM_SWF, MMAL_ENCODING_ADPCM_SWF, 0, 0}, + {VC_CONTAINER_CODEC_WMA1, MMAL_ENCODING_WMA1, 0, 0}, + {VC_CONTAINER_CODEC_WMA2, MMAL_ENCODING_WMA2, 0, 0}, + {VC_CONTAINER_CODEC_WMAP, MMAL_ENCODING_WMAP, 0, 0}, + {VC_CONTAINER_CODEC_WMAL, MMAL_ENCODING_WMAL, 0, 0}, + {VC_CONTAINER_CODEC_WMAV, MMAL_ENCODING_WMAV, 0, 0}, + {VC_CONTAINER_CODEC_AMRNB, MMAL_ENCODING_AMRNB, 0, 0}, + {VC_CONTAINER_CODEC_AMRWB, MMAL_ENCODING_AMRWB, 0, 0}, + {VC_CONTAINER_CODEC_AMRWBP, MMAL_ENCODING_AMRWBP, 0, 0}, + {VC_CONTAINER_CODEC_AC3, MMAL_ENCODING_AC3, 0, 0}, + {VC_CONTAINER_CODEC_EAC3, MMAL_ENCODING_EAC3, 0, 0}, + {VC_CONTAINER_CODEC_DTS, MMAL_ENCODING_DTS, 0, 0}, + {VC_CONTAINER_CODEC_MLP, MMAL_ENCODING_MLP, 0, 0}, + {VC_CONTAINER_CODEC_FLAC, MMAL_ENCODING_FLAC, 0, 0}, + {VC_CONTAINER_CODEC_VORBIS, MMAL_ENCODING_VORBIS, 0, 0}, + {VC_CONTAINER_CODEC_SPEEX, MMAL_ENCODING_SPEEX, 0, 0}, + {VC_CONTAINER_CODEC_ATRAC3, MMAL_ENCODING_ATRAC3, 0, 0}, + {VC_CONTAINER_CODEC_ATRACX, MMAL_ENCODING_ATRACX, 0, 0}, + {VC_CONTAINER_CODEC_ATRACL, MMAL_ENCODING_ATRACL, 0, 0}, + {VC_CONTAINER_CODEC_MIDI, MMAL_ENCODING_MIDI, 0, 0}, + {VC_CONTAINER_CODEC_EVRC, MMAL_ENCODING_EVRC, 0, 0}, + {VC_CONTAINER_CODEC_NELLYMOSER, MMAL_ENCODING_NELLYMOSER, 0, 0}, + {VC_CONTAINER_CODEC_QCELP, MMAL_ENCODING_QCELP, 0, 0}, + + {VC_CONTAINER_CODEC_UNKNOWN, MMAL_ENCODING_UNKNOWN, 0, 0} +}; + +static MMAL_FOURCC_T container_to_mmal_encoding(VC_CONTAINER_FOURCC_T codec) +{ + unsigned int i; + for(i = 0; encoding_table[i].codec != VC_CONTAINER_CODEC_UNKNOWN; i++) + if(encoding_table[i].codec == codec) + break; + return encoding_table[i].encoding; +} + +static VC_CONTAINER_FOURCC_T mmal_to_container_encoding(uint32_t encoding) +{ + unsigned int i; + for(i = 0; encoding_table[i].codec != VC_CONTAINER_CODEC_UNKNOWN; i++) + if(encoding_table[i].encoding == encoding) + break; + return encoding_table[i].codec; +} + +static MMAL_FOURCC_T container_to_mmal_variant(VC_CONTAINER_FOURCC_T codec, + VC_CONTAINER_FOURCC_T codec_variant) +{ + unsigned int i; + for(i = 0; encoding_table[i].codec != VC_CONTAINER_CODEC_UNKNOWN; i++) + if(encoding_table[i].codec == codec && + encoding_table[i].codec_variant == codec_variant) + break; + return encoding_table[i].encoding_variant; +} + +static VC_CONTAINER_FOURCC_T mmal_to_container_variant(MMAL_FOURCC_T encoding, + MMAL_FOURCC_T encoding_variant) +{ + unsigned int i; + for(i = 0; encoding_table[i].codec != VC_CONTAINER_CODEC_UNKNOWN; i++) + if(encoding_table[i].encoding == encoding && + encoding_table[i].encoding_variant == encoding_variant) + break; + return encoding_table[i].codec_variant; +} + +/*****************************************************************************/ +static struct { + VC_CONTAINER_ES_TYPE_T container_type; + MMAL_ES_TYPE_T type; +} es_type_table[] = +{ + {VC_CONTAINER_ES_TYPE_VIDEO, MMAL_ES_TYPE_VIDEO}, + {VC_CONTAINER_ES_TYPE_AUDIO, MMAL_ES_TYPE_AUDIO}, + {VC_CONTAINER_ES_TYPE_SUBPICTURE, MMAL_ES_TYPE_SUBPICTURE}, + {VC_CONTAINER_ES_TYPE_UNKNOWN, MMAL_ES_TYPE_UNKNOWN} +}; + +static MMAL_ES_TYPE_T container_to_mmal_es_type(VC_CONTAINER_ES_TYPE_T type) +{ + unsigned int i; + for(i = 0; es_type_table[i].container_type != VC_CONTAINER_ES_TYPE_UNKNOWN; i++) + if(es_type_table[i].container_type == type) + break; + return es_type_table[i].type; +} + +static VC_CONTAINER_ES_TYPE_T mmal_to_container_es_type(MMAL_ES_TYPE_T type) +{ + unsigned int i; + for(i = 0; es_type_table[i].container_type != VC_CONTAINER_ES_TYPE_UNKNOWN; i++) + if(es_type_table[i].type == type) + break; + return es_type_table[i].container_type; +} + +static MMAL_STATUS_T container_map_to_mmal_status(VC_CONTAINER_STATUS_T cstatus) +{ + switch (cstatus) + { + case VC_CONTAINER_SUCCESS: return MMAL_SUCCESS; + case VC_CONTAINER_ERROR_CORRUPTED: return MMAL_ECORRUPT; + case VC_CONTAINER_ERROR_OUT_OF_MEMORY: return MMAL_ENOMEM; + case VC_CONTAINER_ERROR_OUT_OF_RESOURCES: return MMAL_ENOSPC; + case VC_CONTAINER_ERROR_NOT_READY: return MMAL_ENOTREADY; + case VC_CONTAINER_ERROR_NOT_FOUND: return MMAL_ENOENT; + case VC_CONTAINER_ERROR_URI_NOT_FOUND: return MMAL_ENOENT; + default: return MMAL_EINVAL; + } +} + +static MMAL_STATUS_T container_to_mmal_format(MMAL_ES_FORMAT_T *format, + VC_CONTAINER_ES_FORMAT_T *container_format) +{ + format->type = container_to_mmal_es_type(container_format->es_type); + if(format->type == MMAL_ES_TYPE_UNKNOWN) + return MMAL_EINVAL; + + format->encoding = container_to_mmal_encoding(container_format->codec); + format->encoding_variant = container_to_mmal_variant(container_format->codec, container_format->codec_variant); + format->bitrate = container_format->bitrate; + format->flags = (container_format->flags & VC_CONTAINER_ES_FORMAT_FLAG_FRAMED) ? + MMAL_ES_FORMAT_FLAG_FRAMED : 0; + memset(format->es, 0, sizeof(*format->es)); + + switch(format->type) + { + case MMAL_ES_TYPE_VIDEO: + format->es->video.width = container_format->type->video.width; + format->es->video.height = container_format->type->video.height; + format->es->video.crop.width = container_format->type->video.visible_width; + format->es->video.crop.height = container_format->type->video.visible_height; + format->es->video.frame_rate.num = container_format->type->video.frame_rate_num; + format->es->video.frame_rate.den = container_format->type->video.frame_rate_den; + format->es->video.par.num = container_format->type->video.par_num; + format->es->video.par.den = container_format->type->video.par_den; + break; + case MMAL_ES_TYPE_AUDIO: + format->es->audio.channels = container_format->type->audio.channels; + format->es->audio.sample_rate = container_format->type->audio.sample_rate; + format->es->audio.bits_per_sample = container_format->type->audio.bits_per_sample; + format->es->audio.block_align = container_format->type->audio.block_align; + break; + default: + LOG_ERROR("format es type not handled (%i)", (int)format->type); + break; + } + + if(container_format->extradata_size) + { + MMAL_STATUS_T status = mmal_format_extradata_alloc(format, container_format->extradata_size); + if(status != MMAL_SUCCESS) + { + LOG_ERROR("couldn't allocate extradata"); + return status; + } + format->extradata_size = container_format->extradata_size; + memcpy(format->extradata, container_format->extradata, format->extradata_size); + } + + return MMAL_SUCCESS; +} + +static MMAL_STATUS_T mmal_to_container_format(VC_CONTAINER_ES_FORMAT_T *container_format, + MMAL_ES_FORMAT_T *format) +{ + container_format->es_type = mmal_to_container_es_type(format->type); + if(container_format->es_type == VC_CONTAINER_ES_TYPE_UNKNOWN) + return MMAL_EINVAL; + + container_format->codec = mmal_to_container_encoding(format->encoding); + container_format->codec_variant = mmal_to_container_variant(format->encoding, format->encoding_variant); + container_format->bitrate = format->bitrate; + container_format->flags = 0; + if(format->flags & MMAL_ES_FORMAT_FLAG_FRAMED) + container_format->flags |= VC_CONTAINER_ES_FORMAT_FLAG_FRAMED; + memset(container_format->type, 0, sizeof(*container_format->type)); + + /* Auto-detect H264 AVC1 variant */ + if(format->encoding == MMAL_ENCODING_H264 && !format->encoding_variant && + format->extradata_size >= 5 && *format->extradata == 1) + container_format->codec_variant = VC_CONTAINER_VARIANT_H264_AVC1; + + switch(format->type) + { + case MMAL_ES_TYPE_VIDEO: + container_format->type->video.width = format->es->video.width; + container_format->type->video.height = format->es->video.height; + container_format->type->video.frame_rate_num = format->es->video.frame_rate.num; + container_format->type->video.frame_rate_den = format->es->video.frame_rate.den; + container_format->type->video.par_num = format->es->video.par.num; + container_format->type->video.par_den = format->es->video.par.den; + break; + case MMAL_ES_TYPE_AUDIO: + container_format->type->audio.channels = format->es->audio.channels; + container_format->type->audio.sample_rate = format->es->audio.sample_rate; + container_format->type->audio.bits_per_sample = format->es->audio.bits_per_sample; + container_format->type->audio.block_align = format->es->audio.block_align; + break; + default: + LOG_ERROR("format es type not handled (%i)", (int)format->type); + break; + } + + container_format->extradata_size = format->extradata_size; + container_format->extradata = format->extradata; + + return MMAL_SUCCESS; +} + +/*****************************************************************************/ +static void reader_do_processing(MMAL_COMPONENT_T *component) +{ + MMAL_COMPONENT_MODULE_T *module = component->priv->module; + MMAL_BUFFER_HEADER_T *buffer; + VC_CONTAINER_STATUS_T cstatus; + VC_CONTAINER_PACKET_T packet; + MMAL_STATUS_T status; + unsigned int i; + + memset(&packet, 0, sizeof(packet)); + + while(1) + { + cstatus = vc_container_read(module->container, &packet, VC_CONTAINER_READ_FLAG_INFO); + if(cstatus == VC_CONTAINER_ERROR_CONTINUE) + continue; + if(cstatus != VC_CONTAINER_SUCCESS) + { + LOG_DEBUG("READ EOF (%i)", cstatus); + break; + } + + if (!module->packet_logged) + LOG_DEBUG("packet info: track %i, size %i/%i, pts %"PRId64"%s, dts %"PRId64"%s, flags %x%s", + packet.track, packet.size, packet.frame_size, + packet.pts == VC_CONTAINER_TIME_UNKNOWN ? 0 : packet.pts, + packet.pts == VC_CONTAINER_TIME_UNKNOWN ? ":unknown" : "", + packet.dts == VC_CONTAINER_TIME_UNKNOWN ? 0 : packet.dts, + packet.dts == VC_CONTAINER_TIME_UNKNOWN ? ":unknown" : "", + packet.flags, (packet.flags & VC_CONTAINER_PACKET_FLAG_KEYFRAME) ? " (keyframe)" : ""); + + /* Find the port corresponding to that track */ + for(i = 0; i < module->ports; i++) + if(component->output[i]->priv->module->track == packet.track) + break; + if(i == module->ports) + { + vc_container_read(module->container, 0, VC_CONTAINER_READ_FLAG_SKIP); + continue; + } + + /* Get a buffer from this port */ + buffer = mmal_queue_get(component->output[i]->priv->module->queue); + if(!buffer) + { + module->packet_logged = 1; + break; /* Try again next time */ + } + module->packet_logged = 0; + + if(component->output[i]->priv->module->flush) + { + buffer->length = 0; + component->output[i]->priv->module->flush = MMAL_FALSE; + } + + mmal_buffer_header_mem_lock(buffer); + packet.data = buffer->data + buffer->length; + packet.buffer_size = buffer->alloc_size - buffer->length; + packet.size = 0; + cstatus = vc_container_read(module->container, &packet, 0); + mmal_buffer_header_mem_unlock(buffer); + if(cstatus != VC_CONTAINER_SUCCESS) + { + LOG_DEBUG("TEST read status: %i", cstatus); + mmal_queue_put_back(component->output[i]->priv->module->queue, buffer); + break; + } + + if(!buffer->length) + { + buffer->pts = packet.pts == VC_CONTAINER_TIME_UNKNOWN ? MMAL_TIME_UNKNOWN : packet.pts; + buffer->dts = packet.dts == VC_CONTAINER_TIME_UNKNOWN ? MMAL_TIME_UNKNOWN : packet.dts; + buffer->flags = 0; + if(packet.flags & VC_CONTAINER_PACKET_FLAG_KEYFRAME) + buffer->flags |= MMAL_BUFFER_HEADER_FLAG_KEYFRAME; + if(packet.flags & VC_CONTAINER_PACKET_FLAG_FRAME_START) + buffer->flags |= MMAL_BUFFER_HEADER_FLAG_FRAME_START; + } + if(packet.flags & VC_CONTAINER_PACKET_FLAG_FRAME_END) + buffer->flags |= MMAL_BUFFER_HEADER_FLAG_FRAME_END; +#ifdef VC_CONTAINER_PACKET_FLAG_CONFIG + if(packet.flags & VC_CONTAINER_PACKET_FLAG_CONFIG) + buffer->flags |= MMAL_BUFFER_HEADER_FLAG_CONFIG; +#endif + + buffer->length += packet.size; + + if((component->output[i]->format->flags & MMAL_ES_FORMAT_FLAG_FRAMED) && + buffer->length != buffer->alloc_size && + !(buffer->flags & MMAL_BUFFER_HEADER_FLAG_FRAME_END)) + { + mmal_queue_put_back(component->output[i]->priv->module->queue, buffer); + continue; + } + + /* Send buffer back */ + mmal_port_buffer_header_callback(component->output[i], buffer); + } + + if(cstatus == VC_CONTAINER_ERROR_EOS) + { + /* Send an empty EOS buffer for each port */ + for(i = 0; i < component->output_num; i++) + { + MMAL_PORT_T *port = component->output[i]; + if(!port->is_enabled) + continue; + if(port->priv->module->eos) + continue; + /* Get a buffer from this port */ + buffer = mmal_queue_get(port->priv->module->queue); + if(!buffer) + continue; /* Try again next time */ + buffer->length = 0; + buffer->pts = buffer->dts = MMAL_TIME_UNKNOWN; + buffer->flags = MMAL_BUFFER_HEADER_FLAG_EOS; + /* Send buffer back */ + port->priv->module->eos = 1; + mmal_port_buffer_header_callback(port, buffer); + } + } + else if(cstatus != VC_CONTAINER_SUCCESS && !module->error) + { + status = mmal_event_error_send(component, container_map_to_mmal_status(cstatus)); + if (status != MMAL_SUCCESS) + { + LOG_ERROR("unable to send an error event buffer (%i)", (int)status); + return; + } + module->error = 1; + } + + return; +} + +/*****************************************************************************/ +static void writer_do_processing(MMAL_COMPONENT_T *component) +{ + MMAL_COMPONENT_MODULE_T *module = component->priv->module; + VC_CONTAINER_STATUS_T cstatus; + MMAL_PORT_MODULE_T *port_module; + MMAL_PORT_T *port; + MMAL_STATUS_T status; + MMAL_BOOL_T eos; + int64_t timestamp, timestamp_current; + MMAL_BUFFER_HEADER_T *buffer; + VC_CONTAINER_PACKET_T packet; + unsigned int i, index; + + if(module->error) + return; + + /* Select the next port to read from based on earliest timestamp. Buffers without + * timestamps will end-up being prioritised. */ + for(i = 0, index = module->port_last_used, port = 0, timestamp = INT64_C(0); + i < component->input_num; i++, index++) + { + if(index == component->input_num) + index = 0; + + if(!component->input[index]->is_enabled) + continue; + + buffer = mmal_queue_get(component->input[index]->priv->module->queue); + if(!buffer) + continue; + + timestamp_current = buffer->dts; + if (timestamp_current == MMAL_TIME_UNKNOWN) + timestamp_current = buffer->pts; + if(!port) + timestamp = timestamp_current; + + if(timestamp_current <= timestamp) + { + port = component->input[index]; + timestamp = timestamp_current; + module->port_last_used = index; + } + mmal_queue_put_back(component->input[index]->priv->module->queue, buffer); + } + + /* If a port is currently writing a frame then we override the decision to avoid + * splitting frames */ + if(module->port_writing_frame && module->port_writing_frame - 1 < component->input_num && + component->input[module->port_writing_frame-1]->is_enabled) + port = component->input[module->port_writing_frame-1]; + + if(!port) + return; /* nothing to write */ + + port_module = port->priv->module; + + /* Get a buffer from this port */ + buffer = mmal_queue_get(port_module->queue); + if(!buffer) + return; /* nothing to write */ + + mmal_buffer_header_mem_lock(buffer); + memset(&packet, 0, sizeof(packet)); + packet.track = port_module->track; + packet.size = buffer->length; + packet.data = buffer->data + buffer->offset; + packet.pts = buffer->pts == MMAL_TIME_UNKNOWN ? VC_CONTAINER_TIME_UNKNOWN : buffer->pts; + packet.dts = buffer->dts == MMAL_TIME_UNKNOWN ? VC_CONTAINER_TIME_UNKNOWN : buffer->dts; + if(buffer->flags & MMAL_BUFFER_HEADER_FLAG_KEYFRAME) + packet.flags |= VC_CONTAINER_PACKET_FLAG_KEYFRAME; + if(buffer->flags & MMAL_BUFFER_HEADER_FLAG_FRAME_START) + packet.flags |= VC_CONTAINER_PACKET_FLAG_FRAME_START; + if(buffer->flags & MMAL_BUFFER_HEADER_FLAG_FRAME_END) + packet.flags |= VC_CONTAINER_PACKET_FLAG_FRAME_END; + eos = buffer->flags & MMAL_BUFFER_HEADER_FLAG_EOS; + + if ((packet.flags & VC_CONTAINER_PACKET_FLAG_FRAME) == VC_CONTAINER_PACKET_FLAG_FRAME) + packet.frame_size = packet.size; + else + packet.frame_size = 0; + + module->port_writing_frame = port->index + 1; + if((buffer->flags & MMAL_BUFFER_HEADER_FLAG_FRAME_END) || + !(port->format->flags & MMAL_ES_FORMAT_FLAG_FRAMED)) + module->port_writing_frame = 0; + + LOG_DEBUG("packet info: track %i, size %i/%i, pts %"PRId64", flags %x%s", + packet.track, packet.size, packet.frame_size, packet.pts, + packet.flags, (packet.flags & VC_CONTAINER_PACKET_FLAG_KEYFRAME) ? " (keyframe)" : ""); + + cstatus = vc_container_write(module->container, &packet); + mmal_buffer_header_mem_unlock(buffer); + + /* Send buffer back */ + buffer->length = 0; + mmal_port_buffer_header_callback(port, buffer); + + /* Check for errors */ + if(cstatus != VC_CONTAINER_SUCCESS) + { + LOG_ERROR("write failed (%i)", (int)cstatus); + status = mmal_event_error_send(component, container_map_to_mmal_status(cstatus)); + if (status != MMAL_SUCCESS) + { + LOG_ERROR("unable to send an error event buffer (%i)", (int)status); + return; + } + module->error = 1; + return; + } + + /* Generate EOS events */ + if(eos) + { + MMAL_EVENT_END_OF_STREAM_T *event; + status = mmal_port_event_get(component->control, &buffer, MMAL_EVENT_EOS); + if (status != MMAL_SUCCESS) + { + LOG_ERROR("unable to get an event buffer"); + return; + } + + buffer->length = sizeof(*event); + event = (MMAL_EVENT_END_OF_STREAM_T *)buffer->data; + event->port_type = port->type; + event->port_index = port->index; + mmal_port_event_send(component->control, buffer); + } +} + +/** Destroy a previously created component */ +static MMAL_STATUS_T container_component_destroy(MMAL_COMPONENT_T *component) +{ + MMAL_COMPONENT_MODULE_T *module = component->priv->module; + unsigned int i; + + if(module->container) + vc_container_close(module->container); + + for(i = 0; i < component->input_num; i++) + { + if(component->input[i]->priv->module->queue) + mmal_queue_destroy(component->input[i]->priv->module->queue); + if(component->input[i]->priv->module->format) + vc_container_format_delete(component->input[i]->priv->module->format); + } + if(component->input_num) + mmal_ports_free(component->input, component->input_num); + + for(i = 0; i < component->output_num; i++) + if(component->output[i]->priv->module->queue) + mmal_queue_destroy(component->output[i]->priv->module->queue); + if(component->output_num) + mmal_ports_free(component->output, component->output_num); + + vcos_free(module); + return MMAL_SUCCESS; +} + +/** Enable processing on a port */ +static MMAL_STATUS_T container_port_enable(MMAL_PORT_T *port, MMAL_PORT_BH_CB_T cb) +{ + MMAL_COMPONENT_T *component = port->component; + MMAL_COMPONENT_MODULE_T *module = component->priv->module; + MMAL_PORT_MODULE_T *port_module = port->priv->module; + MMAL_PARAM_UNUSED(cb); + + if(!module->container) + return MMAL_EINVAL; + + if(module->writer) + { + VC_CONTAINER_STATUS_T cstatus; + port_module->track = module->container->tracks_num; + cstatus = vc_container_control(module->container, VC_CONTAINER_CONTROL_TRACK_ADD, + port_module->format); + if(cstatus != VC_CONTAINER_SUCCESS) + { + LOG_ERROR("error adding track %4.4s (%i)", (char *)&port->format->encoding, (int)cstatus); + return container_map_to_mmal_status(cstatus); + } + } + + if(port_module->track >= module->container->tracks_num) + { + LOG_ERROR("error 1 adding track %4.4s (%i/%i)", (char *)&port->format->encoding, port_module->track, module->container->tracks_num); + return MMAL_EINVAL; + } + module->container->tracks[port_module->track]->is_enabled = 1; + return MMAL_SUCCESS; +} + +/** Flush a port */ +static MMAL_STATUS_T container_port_flush(MMAL_PORT_T *port) +{ + MMAL_PORT_MODULE_T *port_module = port->priv->module; + MMAL_BUFFER_HEADER_T *buffer; + + /* Flush buffers that our component is holding on to. + * If the reading thread is holding onto a buffer it will send it back ASAP as well + * so no need to care about that. */ + buffer = mmal_queue_get(port_module->queue); + while(buffer) + { + buffer->length = 0; + mmal_port_buffer_header_callback(port, buffer); + buffer = mmal_queue_get(port_module->queue); + } + + return MMAL_SUCCESS; +} + +/** Disable processing on a port */ +static MMAL_STATUS_T container_port_disable(MMAL_PORT_T *port) +{ + MMAL_COMPONENT_T *component = port->component; + MMAL_COMPONENT_MODULE_T *module = component->priv->module; + unsigned int track = port->priv->module->track; + MMAL_STATUS_T status; + + if(!module->container || track >= module->container->tracks_num) + return MMAL_EINVAL; + + /* Actions are prevented from running at that point so a flush + * will return all buffers. */ + status = container_port_flush(port); + if(status != MMAL_SUCCESS) + return status; + + module->container->tracks[track]->is_enabled = 0; + return MMAL_SUCCESS; +} + +/** Send a buffer header to a port */ +static MMAL_STATUS_T container_port_send(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) +{ + mmal_queue_put(port->priv->module->queue, buffer); + mmal_component_action_trigger(port->component); + return MMAL_SUCCESS; +} + +/** Set format on a port */ +static MMAL_STATUS_T container_port_set_format(MMAL_PORT_T *port) +{ + MMAL_COMPONENT_T *component = port->component; + MMAL_COMPONENT_MODULE_T *module = component->priv->module; + MMAL_STATUS_T status; + + if(!module->writer) + return MMAL_EINVAL; + + /* Set format of the track */ + status = mmal_to_container_format(port->priv->module->format, port->format); + if (status != MMAL_SUCCESS) + return status; + + port->buffer_num_min = READER_MIN_BUFFER_NUM; + port->buffer_num_recommended = READER_RECOMMENDED_BUFFER_NUM; + port->buffer_size_min = READER_MIN_BUFFER_SIZE; + port->buffer_size_recommended = READER_RECOMMENDED_BUFFER_SIZE; + return MMAL_SUCCESS; +} + +static MMAL_STATUS_T reader_container_open(MMAL_COMPONENT_T *component, const char *uri) +{ + MMAL_COMPONENT_MODULE_T *module = component->priv->module; + VC_CONTAINER_STATUS_T cstatus; + VC_CONTAINER_T *container; + unsigned int i, port, track; + + /* Open container */ + module->container = container = + vc_container_open_reader(uri, &cstatus, 0, 0); + if(!container) + { + LOG_ERROR("error opening file %s (%i)", uri, cstatus); + return container_map_to_mmal_status(cstatus); + } + + /* Disable all tracks */ + for(track = 0; track < container->tracks_num; track++) + container->tracks[track]->is_enabled = 0; + + /* Fill-in the ports */ + for(i = 0, port = 0; i < component->output_num; i++) + { + VC_CONTAINER_ES_TYPE_T type = VC_CONTAINER_ES_TYPE_VIDEO; + if(i == 1) type = VC_CONTAINER_ES_TYPE_AUDIO; + if(i == 2) type = VC_CONTAINER_ES_TYPE_SUBPICTURE; + + /* Look for the first track with the specified type */ + for(track = 0; track < container->tracks_num; track++) + if(container->tracks[track]->format->es_type == type) + break; + if(track == container->tracks_num) + continue; + + if(container_to_mmal_encoding(container->tracks[track]->format->codec) == MMAL_ENCODING_UNKNOWN) + continue; + + /* Set format of the port */ + if(container_to_mmal_format(component->output[port]->format, + container->tracks[track]->format) != MMAL_SUCCESS) + continue; + + component->output[port]->buffer_num_min = READER_MIN_BUFFER_NUM; + component->output[port]->buffer_num_recommended = READER_RECOMMENDED_BUFFER_NUM; + component->output[port]->buffer_size_min = READER_MIN_BUFFER_SIZE; + component->output[port]->buffer_size_recommended = READER_RECOMMENDED_BUFFER_SIZE; + component->output[port]->priv->module->track = track; + + /* We're done with this port */ + port++; + } + module->ports = port; + + /* Reset the left over ports */ + for(i = port; i < component->output_num; i++) + { + component->output[i]->format->type = MMAL_ES_TYPE_UNKNOWN; + component->output[i]->format->encoding = MMAL_ENCODING_UNKNOWN; + } + + return MMAL_SUCCESS; +} + +static MMAL_STATUS_T reader_container_seek(MMAL_COMPONENT_T *component, const MMAL_PARAMETER_SEEK_T *seek) +{ + MMAL_COMPONENT_MODULE_T *module = component->priv->module; + VC_CONTAINER_SEEK_FLAGS_T flags = 0; + int64_t offset = seek->offset; + VC_CONTAINER_STATUS_T cstatus; + unsigned int i; + + if(seek->flags & MMAL_PARAM_SEEK_FLAG_PRECISE) + flags |= VC_CONTAINER_SEEK_FLAG_PRECISE; + if(seek->flags & MMAL_PARAM_SEEK_FLAG_FORWARD) + flags |= VC_CONTAINER_SEEK_FLAG_FORWARD; + + mmal_component_action_lock(component); + for(i = 0; i < component->output_num; i++) + { + component->output[i]->priv->module->eos = MMAL_FALSE; + component->output[i]->priv->module->flush = MMAL_TRUE; + } + cstatus = vc_container_seek( module->container, &offset, VC_CONTAINER_SEEK_MODE_TIME, flags); + mmal_component_action_unlock(component); + return container_map_to_mmal_status(cstatus); +} + +static MMAL_STATUS_T reader_parameter_set(MMAL_PORT_T *port, const MMAL_PARAMETER_HEADER_T *param) +{ + MMAL_COMPONENT_T *component = port->component; + MMAL_COMPONENT_MODULE_T *module = component->priv->module; + + switch(param->id) + { + case MMAL_PARAMETER_URI: + if(module->container) + return MMAL_EINVAL; + + memset(module->uri, 0, sizeof(module->uri)); + strncpy(module->uri, ((const MMAL_PARAMETER_STRING_T *)param)->str, sizeof(module->uri)-1 ); + return reader_container_open(component, module->uri); + + case MMAL_PARAMETER_SEEK: + if(!module->container || param->size < sizeof(MMAL_PARAMETER_SEEK_T)) + return MMAL_EINVAL; + + return reader_container_seek(component, (const MMAL_PARAMETER_SEEK_T *)param); + + default: + return MMAL_ENOSYS; + } + + return MMAL_SUCCESS; +} + +/** Create an instance of a component */ +static MMAL_STATUS_T mmal_component_create_reader(const char *name, MMAL_COMPONENT_T *component) +{ + MMAL_COMPONENT_MODULE_T *module; + unsigned int outputs_num, i; + MMAL_STATUS_T status = MMAL_ENOMEM; + MMAL_PARAM_UNUSED(name); + + /* Allocate the context for our module */ + component->priv->module = module = vcos_malloc(sizeof(*module), "mmal module"); + if (!module) + return MMAL_ENOMEM; + memset(module, 0, sizeof(*module)); + + component->priv->pf_destroy = container_component_destroy; + + /* Create 3 tracks for now (audio/video/subpicture). + * FIXME: ideally we should create 1 track per elementary stream. */ + outputs_num = 3; + + /* Now the component on reader has been created, we can allocate + * the ports for this component */ + component->output = mmal_ports_alloc(component, outputs_num, MMAL_PORT_TYPE_OUTPUT, + sizeof(MMAL_PORT_MODULE_T)); + if(!component->output) + goto error; + component->output_num = outputs_num; + + for(i = 0; i < outputs_num; i++) + { + component->output[i]->priv->pf_enable = container_port_enable; + component->output[i]->priv->pf_disable = container_port_disable; + component->output[i]->priv->pf_flush = container_port_flush; + component->output[i]->priv->pf_send = container_port_send; + component->output[i]->priv->module->queue = mmal_queue_create(); + if(!component->output[i]->priv->module->queue) + goto error; + } + component->control->priv->pf_parameter_set = reader_parameter_set; + + status = mmal_component_action_register(component, reader_do_processing); + if (status != MMAL_SUCCESS) + goto error; + + return MMAL_SUCCESS; + + error: + container_component_destroy(component); + return status; +} + +static MMAL_STATUS_T writer_parameter_set(MMAL_PORT_T *port, const MMAL_PARAMETER_HEADER_T *param) +{ + MMAL_COMPONENT_T *component = port->component; + MMAL_COMPONENT_MODULE_T *module = component->priv->module; + VC_CONTAINER_STATUS_T cstatus; + + switch(param->id) + { + case MMAL_PARAMETER_URI: + if(module->container) + return MMAL_EINVAL; + + memset(module->uri, 0, sizeof(module->uri)); + strncpy(module->uri, ((const MMAL_PARAMETER_URI_T *)param)->uri, sizeof(module->uri)-1 ); + + /* Open container */ + module->container = vc_container_open_writer(module->uri, &cstatus, 0, 0); + if(!module->container) + { + LOG_ERROR("error opening file %s (%i)", module->uri, cstatus); + return container_map_to_mmal_status(cstatus); + } + return MMAL_SUCCESS; + + default: + return MMAL_ENOSYS; + } + + return MMAL_SUCCESS; +} + +/** Create an instance of a component */ +static MMAL_STATUS_T mmal_component_create_writer(const char *name, MMAL_COMPONENT_T *component) +{ + MMAL_COMPONENT_MODULE_T *module; + MMAL_STATUS_T status = MMAL_ENOMEM; + unsigned int i; + MMAL_PARAM_UNUSED(name); + + /* Allocate the context for our module */ + component->priv->module = module = vcos_malloc(sizeof(*module), "mmal module"); + if (!module) + return MMAL_ENOMEM; + memset(module, 0, sizeof(*module)); + module->writer = 1; + + component->priv->pf_destroy = container_component_destroy; + + /* Now the component on reader has been created, we can allocate + * the ports for this component */ + component->input = mmal_ports_alloc(component, WRITER_PORTS_NUM, MMAL_PORT_TYPE_INPUT, + sizeof(MMAL_PORT_MODULE_T)); + if(!component->input) + goto error; + component->input_num = WRITER_PORTS_NUM; + + for(i = 0; i < component->input_num; i++) + { + component->input[i]->priv->pf_enable = container_port_enable; + component->input[i]->priv->pf_disable = container_port_disable; + component->input[i]->priv->pf_flush = container_port_flush; + component->input[i]->priv->pf_send = container_port_send; + component->input[i]->priv->pf_set_format = container_port_set_format; + + component->input[i]->priv->module->queue = mmal_queue_create(); + if(!component->input[i]->priv->module->queue) + goto error; + component->input[i]->priv->module->format = vc_container_format_create(0); + if(!component->input[i]->priv->module->format) + goto error; + } + component->control->priv->pf_parameter_set = writer_parameter_set; + + status = mmal_component_action_register(component, writer_do_processing); + if (status != MMAL_SUCCESS) + goto error; + + return MMAL_SUCCESS; + + error: + container_component_destroy(component); + return status; +} + +MMAL_CONSTRUCTOR(mmal_register_component_container_reader); +void mmal_register_component_container_reader(void) +{ + mmal_component_supplier_register("container_reader", mmal_component_create_reader); +} + +MMAL_CONSTRUCTOR(mmal_register_component_container_writer); +void mmal_register_component_container_writer(void) +{ + mmal_component_supplier_register("container_writer", mmal_component_create_writer); +} diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/components/copy.c b/external_src/raspicam-0.1.3/dependencies/mmal/components/copy.c new file mode 100644 index 0000000..1bbd952 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/components/copy.c @@ -0,0 +1,327 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 "mmal.h" +#include "core/mmal_component_private.h" +#include "core/mmal_port_private.h" +#include "mmal_logging.h" + +/*****************************************************************************/ +typedef struct MMAL_COMPONENT_MODULE_T +{ + MMAL_STATUS_T status; /**< current status of the component */ + +} MMAL_COMPONENT_MODULE_T; + +typedef struct MMAL_PORT_MODULE_T +{ + MMAL_QUEUE_T *queue; /**< queue for the buffers sent to the ports */ + MMAL_BOOL_T needs_configuring; /**< port is waiting for a format commit */ + +} MMAL_PORT_MODULE_T; + +/*****************************************************************************/ + +/** Actual processing function */ +static MMAL_BOOL_T copy_do_processing(MMAL_COMPONENT_T *component) +{ + MMAL_COMPONENT_MODULE_T *module = component->priv->module; + MMAL_PORT_T *port_in = component->input[0]; + MMAL_PORT_T *port_out = component->output[0]; + MMAL_BUFFER_HEADER_T *in, *out; + + if (port_out->priv->module->needs_configuring) + return 0; + + in = mmal_queue_get(port_in->priv->module->queue); + if (!in) + return 0; + + /* Handle event buffers */ + if (in->cmd) + { + MMAL_EVENT_FORMAT_CHANGED_T *event = mmal_event_format_changed_get(in); + if (event) + { + module->status = mmal_format_full_copy(port_in->format, event->format); + if (module->status == MMAL_SUCCESS) + module->status = port_in->priv->pf_set_format(port_in); + if (module->status != MMAL_SUCCESS) + { + LOG_ERROR("format not set on port %s %p (%i)", port_in->name, port_in, module->status); + if (mmal_event_error_send(component, module->status) != MMAL_SUCCESS) + LOG_ERROR("unable to send an error event buffer"); + } + } + else + { + LOG_ERROR("discarding event %i on port %s %p", (int)in->cmd, port_in->name, port_in); + } + + in->length = 0; + mmal_port_buffer_header_callback(port_in, in); + return 1; + } + + /* Don't do anything if we've already seen an error */ + if (module->status != MMAL_SUCCESS) + { + mmal_queue_put_back(port_in->priv->module->queue, in); + return 0; + } + + out = mmal_queue_get(port_out->priv->module->queue); + if (!out) + { + mmal_queue_put_back(port_in->priv->module->queue, in); + return 0; + } + + /* Sanity check the output buffer is big enough */ + if (out->alloc_size < in->length) + { + module->status = MMAL_EINVAL; + if (mmal_event_error_send(component, module->status) != MMAL_SUCCESS) + LOG_ERROR("unable to send an error event buffer"); + return 0; + } + + mmal_buffer_header_mem_lock(out); + mmal_buffer_header_mem_lock(in); + memcpy(out->data, in->data + in->offset, in->length); + mmal_buffer_header_mem_unlock(in); + mmal_buffer_header_mem_unlock(out); + out->length = in->length; + out->offset = 0; + out->flags = in->flags; + out->pts = in->pts; + out->dts = in->dts; + *out->type = *in->type; + + /* Send buffers back */ + in->length = 0; + mmal_port_buffer_header_callback(port_in, in); + mmal_port_buffer_header_callback(port_out, out); + return 1; +} + +/*****************************************************************************/ +static void copy_do_processing_loop(MMAL_COMPONENT_T *component) +{ + while (copy_do_processing(component)); +} + +/** Destroy a previously created component */ +static MMAL_STATUS_T copy_component_destroy(MMAL_COMPONENT_T *component) +{ + unsigned int i; + + for(i = 0; i < component->input_num; i++) + if(component->input[i]->priv->module->queue) + mmal_queue_destroy(component->input[i]->priv->module->queue); + if(component->input_num) + mmal_ports_free(component->input, component->input_num); + + for(i = 0; i < component->output_num; i++) + if(component->output[i]->priv->module->queue) + mmal_queue_destroy(component->output[i]->priv->module->queue); + if(component->output_num) + mmal_ports_free(component->output, component->output_num); + + vcos_free(component->priv->module); + return MMAL_SUCCESS; +} + +/** Enable processing on a port */ +static MMAL_STATUS_T copy_port_enable(MMAL_PORT_T *port, MMAL_PORT_BH_CB_T cb) +{ + MMAL_PARAM_UNUSED(cb); + + /* We need to propagate the buffer requirements when the input port is + * enabled */ + if (port->type == MMAL_PORT_TYPE_INPUT) + return port->priv->pf_set_format(port); + + return MMAL_SUCCESS; +} + +/** Flush a port */ +static MMAL_STATUS_T copy_port_flush(MMAL_PORT_T *port) +{ + MMAL_PORT_MODULE_T *port_module = port->priv->module; + MMAL_BUFFER_HEADER_T *buffer; + + /* Flush buffers that our component is holding on to */ + buffer = mmal_queue_get(port_module->queue); + while(buffer) + { + mmal_port_buffer_header_callback(port, buffer); + buffer = mmal_queue_get(port_module->queue); + } + + return MMAL_SUCCESS; +} + +/** Disable processing on a port */ +static MMAL_STATUS_T copy_port_disable(MMAL_PORT_T *port) +{ + /* We just need to flush our internal queue */ + return copy_port_flush(port); +} + +/** Send a buffer header to a port */ +static MMAL_STATUS_T copy_port_send(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) +{ + mmal_queue_put(port->priv->module->queue, buffer); + mmal_component_action_trigger(port->component); + return MMAL_SUCCESS; +} + +/** Set format on input port */ +static MMAL_STATUS_T copy_input_port_format_commit(MMAL_PORT_T *in) +{ + MMAL_COMPONENT_T *component = in->component; + MMAL_PORT_T *out = component->output[0]; + MMAL_EVENT_FORMAT_CHANGED_T *event; + MMAL_BUFFER_HEADER_T *buffer; + MMAL_STATUS_T status; + + /* Check if there's anything to propagate to the output port */ + /* The format of the output port needs to match the input port */ + if (!mmal_format_compare(in->format, out->format) && + out->buffer_size_min == out->buffer_size_recommended && + out->buffer_size_min == MMAL_MAX(in->buffer_size_min, in->buffer_size)) + return MMAL_SUCCESS; + + /* If the output port is not enabled we just need to update its format. + * Otherwise we'll have to trigger a format changed event for it. */ + if (!out->is_enabled) + { + out->buffer_size_min = out->buffer_size_recommended = + MMAL_MAX(in->buffer_size, in->buffer_size_min); + return mmal_format_full_copy(out->format, in->format); + } + + /* Send an event on the output port */ + status = mmal_port_event_get(out, &buffer, MMAL_EVENT_FORMAT_CHANGED); + if (status != MMAL_SUCCESS) + { + LOG_ERROR("unable to get an event buffer"); + return status; + } + + event = mmal_event_format_changed_get(buffer); + mmal_format_copy(event->format, in->format); /* FIXME: can full copy be done ? */ + + /* Pass on the buffer requirements */ + event->buffer_num_min = out->buffer_num_min; + event->buffer_num_recommended = out->buffer_num_recommended; + event->buffer_size_min = event->buffer_size_recommended = + MMAL_MAX(in->buffer_size_min, in->buffer_size); + + out->priv->module->needs_configuring = 1; + mmal_port_event_send(out, buffer); + return status; +} + +/** Set format on output port */ +static MMAL_STATUS_T copy_output_port_format_commit(MMAL_PORT_T *out) +{ + MMAL_COMPONENT_T *component = out->component; + MMAL_PORT_T *in = component->input[0]; + + /* The format of the output port needs to match the input port */ + if (mmal_format_compare(out->format, in->format)) + return MMAL_EINVAL; + + out->priv->module->needs_configuring = 0; + mmal_component_action_trigger(out->component); + return MMAL_SUCCESS; +} + +/** Create an instance of a component */ +static MMAL_STATUS_T mmal_component_create_copy(const char *name, MMAL_COMPONENT_T *component) +{ + MMAL_COMPONENT_MODULE_T *module; + MMAL_STATUS_T status = MMAL_ENOMEM; + MMAL_PARAM_UNUSED(name); + + /* Allocate the context for our module */ + component->priv->module = module = vcos_malloc(sizeof(*module), "mmal module"); + if (!module) + return MMAL_ENOMEM; + memset(module, 0, sizeof(*module)); + + component->priv->pf_destroy = copy_component_destroy; + + /* Allocate and initialise all the ports for this component */ + component->input = mmal_ports_alloc(component, 1, MMAL_PORT_TYPE_INPUT, sizeof(MMAL_PORT_MODULE_T)); + if(!component->input) + goto error; + component->input_num = 1; + component->input[0]->priv->pf_enable = copy_port_enable; + component->input[0]->priv->pf_disable = copy_port_disable; + component->input[0]->priv->pf_flush = copy_port_flush; + component->input[0]->priv->pf_send = copy_port_send; + component->input[0]->priv->pf_set_format = copy_input_port_format_commit; + component->input[0]->buffer_num_min = 1; + component->input[0]->buffer_num_recommended = 0; + component->input[0]->priv->module->queue = mmal_queue_create(); + if(!component->input[0]->priv->module->queue) + goto error; + + component->output = mmal_ports_alloc(component, 1, MMAL_PORT_TYPE_OUTPUT, sizeof(MMAL_PORT_MODULE_T)); + if(!component->output) + goto error; + component->output_num = 1; + component->output[0]->priv->pf_enable = copy_port_enable; + component->output[0]->priv->pf_disable = copy_port_disable; + component->output[0]->priv->pf_flush = copy_port_flush; + component->output[0]->priv->pf_send = copy_port_send; + component->output[0]->priv->pf_set_format = copy_output_port_format_commit; + component->output[0]->buffer_num_min = 1; + component->output[0]->buffer_num_recommended = 0; + component->output[0]->priv->module->queue = mmal_queue_create(); + if(!component->output[0]->priv->module->queue) + goto error; + + status = mmal_component_action_register(component, copy_do_processing_loop); + if (status != MMAL_SUCCESS) + goto error; + + return MMAL_SUCCESS; + + error: + copy_component_destroy(component); + return status; +} + +MMAL_CONSTRUCTOR(mmal_register_component_copy); +void mmal_register_component_copy(void) +{ + mmal_component_supplier_register("copy", mmal_component_create_copy); +} diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/components/null_sink.c b/external_src/raspicam-0.1.3/dependencies/mmal/components/null_sink.c new file mode 100644 index 0000000..78c7144 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/components/null_sink.c @@ -0,0 +1,125 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 "mmal.h" +#include "core/mmal_component_private.h" +#include "core/mmal_port_private.h" +#include "mmal_logging.h" + +#define NULLSINK_PORTS_NUM 1 + +/** Destroy a previously created component */ +static MMAL_STATUS_T null_sink_component_destroy(MMAL_COMPONENT_T *component) +{ + if(component->input_num) + mmal_ports_free(component->input, component->input_num); + return MMAL_SUCCESS; +} + +/** Enable processing on a port */ +static MMAL_STATUS_T null_sink_port_enable(MMAL_PORT_T *port, MMAL_PORT_BH_CB_T cb) +{ + MMAL_PARAM_UNUSED(port); + MMAL_PARAM_UNUSED(cb); + return MMAL_SUCCESS; +} + +/** Flush a port */ +static MMAL_STATUS_T null_sink_port_flush(MMAL_PORT_T *port) +{ + MMAL_PARAM_UNUSED(port); + return MMAL_SUCCESS; +} + +/** Disable processing on a port */ +static MMAL_STATUS_T null_sink_port_disable(MMAL_PORT_T *port) +{ + MMAL_PARAM_UNUSED(port); + return MMAL_SUCCESS; +} + +/** Send a buffer header to a port */ +static MMAL_STATUS_T null_sink_port_send(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) +{ + MMAL_BOOL_T eos = buffer->flags & MMAL_BUFFER_HEADER_FLAG_EOS; + + /* Send buffer back */ + buffer->length = 0; + mmal_port_buffer_header_callback(port, buffer); + + /* Generate EOS events */ + if(eos) + return mmal_event_eos_send(port); + + return MMAL_SUCCESS; +} + +/** Set format on a port */ +static MMAL_STATUS_T null_sink_port_format_commit(MMAL_PORT_T *port) +{ + MMAL_PARAM_UNUSED(port); + return MMAL_SUCCESS; +} + +/** Create an instance of a component */ +static MMAL_STATUS_T mmal_component_create_null_sink(const char *name, MMAL_COMPONENT_T *component) +{ + MMAL_STATUS_T status = MMAL_ENOMEM; + unsigned int i; + MMAL_PARAM_UNUSED(name); + + component->priv->pf_destroy = null_sink_component_destroy; + + /* Allocate all the ports for this component */ + component->input = mmal_ports_alloc(component, NULLSINK_PORTS_NUM, MMAL_PORT_TYPE_INPUT, 0); + if(!component->input) + goto error; + component->input_num = NULLSINK_PORTS_NUM; + + for(i = 0; i < component->input_num; i++) + { + component->input[i]->priv->pf_enable = null_sink_port_enable; + component->input[i]->priv->pf_disable = null_sink_port_disable; + component->input[i]->priv->pf_flush = null_sink_port_flush; + component->input[i]->priv->pf_send = null_sink_port_send; + component->input[i]->priv->pf_set_format = null_sink_port_format_commit; + component->input[i]->buffer_num_min = 1; + component->input[i]->buffer_num_recommended = 1; + } + + return MMAL_SUCCESS; + + error: + null_sink_component_destroy(component); + return status; +} + +MMAL_CONSTRUCTOR(mmal_register_component_null_sink); +void mmal_register_component_null_sink(void) +{ + mmal_component_supplier_register("null_sink", mmal_component_create_null_sink); +} diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/components/passthrough.c b/external_src/raspicam-0.1.3/dependencies/mmal/components/passthrough.c new file mode 100644 index 0000000..e51277d --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/components/passthrough.c @@ -0,0 +1,284 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 "mmal.h" +#include "core/mmal_component_private.h" +#include "core/mmal_port_private.h" +#include "mmal_logging.h" + +#define PASSTHROUGH_PORTS_NUM 1 + +/*****************************************************************************/ +typedef struct MMAL_COMPONENT_MODULE_T +{ + MMAL_BOOL_T error; /**< Error state */ + +} MMAL_COMPONENT_MODULE_T; + +typedef struct MMAL_PORT_MODULE_T +{ + MMAL_QUEUE_T *queue; /**< queue for the buffers sent to the ports */ + +} MMAL_PORT_MODULE_T; + +/*****************************************************************************/ + +/** Destroy a previously created component */ +static MMAL_STATUS_T passthrough_component_destroy(MMAL_COMPONENT_T *component) +{ + unsigned int i; + + for(i = 0; i < component->input_num; i++) + if(component->input[i]->priv->module->queue) + mmal_queue_destroy(component->input[i]->priv->module->queue); + if(component->input_num) + mmal_ports_free(component->input, component->input_num); + + for(i = 0; i < component->output_num; i++) + if(component->output[i]->priv->module->queue) + mmal_queue_destroy(component->output[i]->priv->module->queue); + if(component->output_num) + mmal_ports_free(component->output, component->output_num); + + vcos_free(component->priv->module); + return MMAL_SUCCESS; +} + +/** Enable processing on a port */ +static MMAL_STATUS_T passthrough_port_enable(MMAL_PORT_T *port, MMAL_PORT_BH_CB_T cb) +{ + MMAL_PARAM_UNUSED(port); + MMAL_PARAM_UNUSED(cb); + return MMAL_SUCCESS; +} + +/** Flush a port */ +static MMAL_STATUS_T passthrough_port_flush(MMAL_PORT_T *port) +{ + MMAL_PORT_MODULE_T *port_module = port->priv->module; + MMAL_BUFFER_HEADER_T *buffer; + + /* Flush buffers that our component is holding on to */ + buffer = mmal_queue_get(port_module->queue); + while(buffer) + { + mmal_port_buffer_header_callback(port, buffer); + buffer = mmal_queue_get(port_module->queue); + } + + return MMAL_SUCCESS; +} + +/** Disable processing on a port */ +static MMAL_STATUS_T passthrough_port_disable(MMAL_PORT_T *port) +{ + /* We just need to flush our internal queue */ + return passthrough_port_flush(port); +} + +/** Send a buffer header to a port */ +static MMAL_STATUS_T passthrough_port_send(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) +{ + MMAL_COMPONENT_T *component = port->component; + MMAL_COMPONENT_MODULE_T *module = component->priv->module; + MMAL_PORT_T **other_port, *in_port, *out_port; + MMAL_BUFFER_HEADER_T **other_buffer, *in = 0, *out = 0; + MMAL_STATUS_T status; + + if (module->error) + { + mmal_queue_put(port->priv->module->queue, buffer); + return MMAL_SUCCESS; /* Just do nothing */ + } + + in_port = port->component->input[port->index]; + out_port = port->component->output[port->index]; + + if (port->type == MMAL_PORT_TYPE_INPUT) + { + other_port = &out_port; + other_buffer = &out; + in = buffer; + } + else + { + other_port = &in_port; + other_buffer = ∈ + out = buffer; + } + + /* Get a buffer header from the matching port */ + *other_buffer = mmal_queue_get((*other_port)->priv->module->queue); + if (!*other_buffer) + { + /* None available. Just queue the buffer header for now. */ + mmal_queue_put(port->priv->module->queue, buffer); + return MMAL_SUCCESS; + } + + /* Copy our input buffer header */ + status = mmal_buffer_header_replicate(out, in); + if (status != MMAL_SUCCESS) + goto error; + + /* Consume the input buffer */ + in->length = 0; + + /* Send buffers back */ + mmal_port_buffer_header_callback(in_port, in); + mmal_port_buffer_header_callback(out_port, out); + + return MMAL_SUCCESS; + + error: + mmal_queue_put(in_port->priv->module->queue, in); + mmal_queue_put(out_port->priv->module->queue, out); + status = mmal_event_error_send(port->component, status); + if (status != MMAL_SUCCESS) + { + LOG_ERROR("unable to send an error event buffer (%i)", (int)status); + return MMAL_SUCCESS; + } + module->error = 1; + return MMAL_SUCCESS; +} + +/** Set format on a port */ +static MMAL_STATUS_T passthrough_port_format_commit(MMAL_PORT_T *port) +{ + /* Sanity check */ + if (port->type == MMAL_PORT_TYPE_OUTPUT) + { + LOG_ERROR("output port is read-only"); + return MMAL_EINVAL; + } + + return mmal_format_full_copy(port->component->output[port->index]->format, port->format); +} + +static MMAL_STATUS_T passthrough_port_parameter_set(MMAL_PORT_T *port, const MMAL_PARAMETER_HEADER_T *param) +{ + MMAL_COMPONENT_T *component = port->component; + MMAL_PORT_T *in = component->input[port->index], *out = component->input[port->index]; + + switch (param->id) + { + case MMAL_PARAMETER_BUFFER_REQUIREMENTS: + { + /* Propagate the requirements to the matching input and output the ports */ + const MMAL_PARAMETER_BUFFER_REQUIREMENTS_T *req = (const MMAL_PARAMETER_BUFFER_REQUIREMENTS_T *)param; + uint32_t buffer_num_min = MMAL_MAX(port->buffer_num_min, req->buffer_num_min); + uint32_t buffer_num_recommended = MMAL_MAX(port->buffer_num_recommended, req->buffer_num_recommended); + uint32_t buffer_size_min = MMAL_MAX(port->buffer_size_min, req->buffer_size_min); + uint32_t buffer_size_recommended = MMAL_MAX(port->buffer_size_recommended, req->buffer_size_recommended); + + in->buffer_num_min = buffer_num_min; + in->buffer_num_recommended = buffer_num_recommended; + in->buffer_size_min = buffer_size_min; + in->buffer_size_recommended = buffer_size_recommended; + out->buffer_num_min = buffer_num_min; + out->buffer_num_recommended = buffer_num_recommended; + out->buffer_size_min = buffer_size_min; + out->buffer_size_recommended = buffer_size_recommended; + } + return MMAL_SUCCESS; + + default: + return MMAL_ENOSYS; + } +} + +/** Create an instance of a component */ +static MMAL_STATUS_T mmal_component_create_passthrough(const char *name, MMAL_COMPONENT_T *component) +{ + MMAL_COMPONENT_MODULE_T *module; + MMAL_STATUS_T status = MMAL_ENOMEM; + unsigned int i; + MMAL_PARAM_UNUSED(name); + + /* Allocate the context for our module */ + component->priv->module = module = vcos_malloc(sizeof(*module), "mmal module"); + if (!module) + return MMAL_ENOMEM; + memset(module, 0, sizeof(*module)); + + component->priv->pf_destroy = passthrough_component_destroy; + + /* Allocate and initialise all the ports for this component */ + component->input = mmal_ports_alloc(component, PASSTHROUGH_PORTS_NUM, + MMAL_PORT_TYPE_INPUT, sizeof(MMAL_PORT_MODULE_T)); + if(!component->input) + goto error; + component->input_num = PASSTHROUGH_PORTS_NUM; + for(i = 0; i < component->input_num; i++) + { + component->input[i]->priv->pf_enable = passthrough_port_enable; + component->input[i]->priv->pf_disable = passthrough_port_disable; + component->input[i]->priv->pf_flush = passthrough_port_flush; + component->input[i]->priv->pf_send = passthrough_port_send; + component->input[i]->priv->pf_set_format = passthrough_port_format_commit; + component->input[i]->priv->pf_parameter_set = passthrough_port_parameter_set; + component->input[i]->buffer_num_min = 1; + component->input[i]->buffer_num_recommended = 0; + component->input[i]->priv->module->queue = mmal_queue_create(); + if(!component->input[i]->priv->module->queue) + goto error; + } + + component->output = mmal_ports_alloc(component, PASSTHROUGH_PORTS_NUM, + MMAL_PORT_TYPE_OUTPUT, sizeof(MMAL_PORT_MODULE_T)); + if(!component->output) + goto error; + component->output_num = PASSTHROUGH_PORTS_NUM; + for(i = 0; i < component->output_num; i++) + { + component->output[i]->priv->pf_enable = passthrough_port_enable; + component->output[i]->priv->pf_disable = passthrough_port_disable; + component->output[i]->priv->pf_flush = passthrough_port_flush; + component->output[i]->priv->pf_send = passthrough_port_send; + component->output[i]->priv->pf_set_format = passthrough_port_format_commit; + component->output[i]->priv->pf_parameter_set = passthrough_port_parameter_set; + component->output[i]->buffer_num_min = 1; + component->output[i]->buffer_num_recommended = 0; + component->output[i]->capabilities = MMAL_PORT_CAPABILITY_PASSTHROUGH; + component->output[i]->priv->module->queue = mmal_queue_create(); + if(!component->output[i]->priv->module->queue) + goto error; + } + + return MMAL_SUCCESS; + + error: + passthrough_component_destroy(component); + return status; +} + +MMAL_CONSTRUCTOR(mmal_register_component_passthrough); +void mmal_register_component_passthrough(void) +{ + mmal_component_supplier_register("passthrough", mmal_component_create_passthrough); +} diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/components/scheduler.c b/external_src/raspicam-0.1.3/dependencies/mmal/components/scheduler.c new file mode 100644 index 0000000..753b46a --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/components/scheduler.c @@ -0,0 +1,485 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 "mmal.h" +#include "mmal_logging.h" +#include "core/mmal_port_private.h" +#include "core/mmal_component_private.h" +#include "core/mmal_clock_private.h" + +#define SCHEDULER_CLOCK_PORTS_NUM 1 +#define SCHEDULER_INPUT_PORTS_NUM 1 +#define SCHEDULER_OUTPUT_PORTS_NUM 1 + +#define SCHEDULER_REQUEST_SLOTS 16 + +/*****************************************************************************/ +typedef struct MMAL_COMPONENT_MODULE_T +{ + MMAL_STATUS_T status; /**< current status of the component */ +} MMAL_COMPONENT_MODULE_T; + + +typedef struct MMAL_PORT_MODULE_T +{ + MMAL_QUEUE_T *queue; /**< queue for the buffers sent to the port */ + int64_t last_ts; /***< Last timestamp seen on the input port */ +} MMAL_PORT_MODULE_T; + + +/*****************************************************************************/ +/** Process an event buffer */ +static MMAL_STATUS_T scheduler_event_process(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) +{ + MMAL_STATUS_T status = MMAL_EINVAL; + + if (buffer->cmd == MMAL_EVENT_FORMAT_CHANGED) + { + MMAL_EVENT_FORMAT_CHANGED_T *event = + mmal_event_format_changed_get(buffer); + if (!event) + goto end; + + status = mmal_format_full_copy(port->format, event->format); + if (status == MMAL_SUCCESS) + status = mmal_port_format_commit(port); + if (status != MMAL_SUCCESS) + { + LOG_ERROR("format commit failed on port %s (%i)", + port->name, status); + goto end; + } + + status = MMAL_SUCCESS; + } + /* Forward any other event as is to the next component */ + else + { + LOG_DEBUG("forwarding unknown event %4.4s", (char *)&buffer->cmd); + status = mmal_event_forward(buffer, port->component->output[port->index]); + if (status != MMAL_SUCCESS) + { + LOG_ERROR("unable to forward event %4.4s", (char *)&buffer->cmd); + goto end; + } + } + + end: + buffer->length = 0; + mmal_port_buffer_header_callback(port, buffer); + return status; +} + +/** Invoked when a clock request has been serviced */ +static void scheduler_component_clock_port_request_cb(MMAL_PORT_T *port, int64_t media_time, void *cb_data) +{ + MMAL_COMPONENT_T *component = port->component;; + MMAL_PORT_T *port_in = component->input[0]; + MMAL_PORT_T *port_out = component->output[0]; + MMAL_BUFFER_HEADER_T *buffer = (MMAL_BUFFER_HEADER_T*)cb_data; + + LOG_TRACE("media-time %"PRIi64" pts %"PRIi64" delta %"PRIi64, + media_time, buffer->pts, media_time - buffer->pts); + + if (buffer->cmd) + scheduler_event_process(port_in, buffer); + else + /* Forward the buffer to the next component */ + mmal_port_buffer_header_callback(port_out, buffer); +} + +/** Process buffers on the input and output ports */ +static MMAL_BOOL_T scheduler_component_process_buffers(MMAL_COMPONENT_T *component) +{ + MMAL_COMPONENT_MODULE_T *module = component->priv->module; + MMAL_PORT_T *port_in = component->input[0]; + MMAL_PORT_T *port_out = component->output[0]; + MMAL_QUEUE_T *queue_in = port_in->priv->module->queue; + MMAL_QUEUE_T *queue_out = port_out->priv->module->queue; + MMAL_BUFFER_HEADER_T *in, *out; + MMAL_STATUS_T cb_status = MMAL_EINVAL; + + /* Don't do anything if we've already seen an error */ + if (module->status != MMAL_SUCCESS) + { + LOG_ERROR("module failure"); + return MMAL_FALSE; + } + + in = mmal_queue_get(queue_in); + + /* Special case for dealing with event buffers */ + if (in && in->cmd) + { + /* We normally schedule cmds so they come out in the right order, + * except when we don't know when to schedule them, which will only + * happen at the start of the stream. + * The fudge factor added to the last timestamp here is because the + * cmd really applies to the next buffer so we want to make sure + * we leave enough time to the next component to process the previous + * buffer before forwarding the event. */ + in->pts = port_in->priv->module->last_ts + 1000; + if (in->pts != MMAL_TIME_UNKNOWN) + cb_status = mmal_port_clock_request_add(component->clock[0], + in->pts, scheduler_component_clock_port_request_cb, in); + if (cb_status != MMAL_SUCCESS) + { + if (in->pts != MMAL_TIME_UNKNOWN) + LOG_ERROR("failed to add request for cmd"); + scheduler_event_process(port_in, in); + } + return MMAL_TRUE; + } + + /* Need both an input and output buffer to be able to go any further */ + out = mmal_queue_get(queue_out); + if (!in || !out) + goto end; + + if (port_out->capabilities & MMAL_PORT_CAPABILITY_PASSTHROUGH) + { + /* Just need to keep a reference to the input buffer */ + module->status = mmal_buffer_header_replicate(out, in); + } + else + { + /* Make a full copy of the input payload */ + if (out->alloc_size < in->length) + { + LOG_ERROR("output buffer too small"); + + module->status = MMAL_EINVAL; + if (mmal_event_error_send(component, module->status) != MMAL_SUCCESS) + LOG_ERROR("unable to send an error event buffer"); + goto end; + } + mmal_buffer_header_mem_lock(out); + mmal_buffer_header_mem_lock(in); + memcpy(out->data, in->data + in->offset, in->length); + mmal_buffer_header_mem_unlock(in); + mmal_buffer_header_mem_unlock(out); + out->length = in->length; + out->offset = 0; + out->flags = in->flags; + out->pts = in->pts; + out->dts = in->dts; + *out->type = *in->type; + } + + /* Finished with the input buffer, so return it */ + in->length = 0; + mmal_port_buffer_header_callback(port_in, in); + in = 0; + + if (module->status != MMAL_SUCCESS) + { + LOG_ERROR("failed to replicate buffer"); + goto end; + } + + /* Request a clock callback when media-time >= pts */ + LOG_TRACE("requesting callback at %"PRIi64,out->pts); + port_in->priv->module->last_ts = out->pts; + + cb_status = mmal_port_clock_request_add(component->clock[0], out->pts, + scheduler_component_clock_port_request_cb, out); + if (cb_status != MMAL_SUCCESS) + { + LOG_ERROR("failed to add request"); + out->length = 0; + mmal_port_buffer_header_callback(port_out, out); + if (cb_status != MMAL_ECORRUPT) + module->status = cb_status; + } + out = 0; + + end: + if (in) + mmal_queue_put_back(queue_in, in); + if (out) + mmal_queue_put_back(queue_out, out); + + return mmal_queue_length(queue_in) && mmal_queue_length(queue_out); +} + +/** Main processing action */ +static void scheduler_component_action(MMAL_COMPONENT_T *component) +{ + /* Send requests to the clock */ + while (scheduler_component_process_buffers(component)); +} + +/** Destroy a scheduler component */ +static MMAL_STATUS_T scheduler_component_destroy(MMAL_COMPONENT_T *component) +{ + unsigned int i; + + for (i = 0; i < component->input_num; i++) + if (component->input[i]->priv->module->queue) + mmal_queue_destroy(component->input[i]->priv->module->queue); + if (component->input_num) + mmal_ports_free(component->input, component->input_num); + + for (i = 0; i < component->output_num; i++) + if (component->output[i]->priv->module->queue) + mmal_queue_destroy(component->output[i]->priv->module->queue); + if (component->output_num) + mmal_ports_free(component->output, component->output_num); + + if (component->clock_num) + mmal_ports_clock_free(component->clock, component->clock_num); + + vcos_free(component->priv->module); + return MMAL_SUCCESS; +} + +/** Enable processing on a port */ +static MMAL_STATUS_T scheduler_port_enable(MMAL_PORT_T *port, MMAL_PORT_BH_CB_T cb) +{ + MMAL_PARAM_UNUSED(port); + MMAL_PARAM_UNUSED(cb); + return MMAL_SUCCESS; +} + +/** Flush a port */ +static MMAL_STATUS_T scheduler_port_flush(MMAL_PORT_T *port) +{ + MMAL_PORT_MODULE_T *port_module = port->priv->module; + MMAL_BUFFER_HEADER_T *buffer; + + /* Flush buffers associated with pending clock requests */ + mmal_port_clock_request_flush(port->component->clock[0]); + + /* Flush buffers that our component is holding on to */ + buffer = mmal_queue_get(port_module->queue); + while (buffer) + { + mmal_port_buffer_header_callback(port, buffer); + buffer = mmal_queue_get(port_module->queue); + } + + port->priv->module->last_ts = MMAL_TIME_UNKNOWN; + return MMAL_SUCCESS; +} + +/** Disable processing on a port */ +static MMAL_STATUS_T scheduler_port_disable(MMAL_PORT_T *port) +{ + /* We just need to flush our internal queue */ + return scheduler_port_flush(port); +} + +/** Send a buffer header to a port */ +static MMAL_STATUS_T scheduler_port_send(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) +{ + MMAL_COMPONENT_T *component = port->component; + + /* notify the clock port */ + if (port->type == MMAL_PORT_TYPE_INPUT && !buffer->cmd) + { + MMAL_CLOCK_BUFFER_INFO_T info = { buffer->pts, vcos_getmicrosecs() }; + mmal_port_clock_input_buffer_info(port->component->clock[0], &info); + } + + mmal_queue_put(port->priv->module->queue, buffer); + return mmal_component_action_trigger(component); +} + +/** Set format on an input port */ +static MMAL_STATUS_T scheduler_input_port_format_commit(MMAL_PORT_T *port) +{ + MMAL_COMPONENT_T *component = port->component; + MMAL_EVENT_FORMAT_CHANGED_T *event; + MMAL_PORT_T *output = component->output[0]; + MMAL_BUFFER_HEADER_T *buffer; + MMAL_STATUS_T status; + + /* If the output port is not enabled we just need to update its format. + * Otherwise we'll have to trigger a format changed event for it. */ + if (!output->is_enabled) + { + status = mmal_format_full_copy(output->format, port->format); + return status; + } + + /* Send an event on the output port */ + status = mmal_port_event_get(output, &buffer, MMAL_EVENT_FORMAT_CHANGED); + if (status != MMAL_SUCCESS) + { + LOG_ERROR("unable to get an event buffer"); + return status; + } + event = mmal_event_format_changed_get(buffer); + if (!event) + { + mmal_buffer_header_release(buffer); + LOG_ERROR("failed to set format"); + return MMAL_EINVAL; + } + mmal_format_copy(event->format, port->format); + + /* Pass on the buffer requirements */ + event->buffer_num_min = port->buffer_num_min; + event->buffer_size_min = port->buffer_size_min; + event->buffer_num_recommended = port->buffer_num_recommended; + event->buffer_size_recommended = port->buffer_size_recommended; + + mmal_port_event_send(component->output[port->index], buffer); + return status; +} + +/** Set format on an output port */ +static MMAL_STATUS_T scheduler_output_port_format_commit(MMAL_PORT_T *port) +{ + /* The format of the output port needs to match the input port */ + if (mmal_format_compare(port->format, port->component->input[port->index]->format)) + LOG_DEBUG("output port format different from input port"); + + return MMAL_SUCCESS; +} + +static MMAL_STATUS_T scheduler_port_parameter_set(MMAL_PORT_T *port, const MMAL_PARAMETER_HEADER_T *param) +{ + MMAL_COMPONENT_T *component = port->component; + MMAL_PORT_T *in = component->input[port->index], *out = component->input[port->index]; + + switch (param->id) + { + case MMAL_PARAMETER_BUFFER_REQUIREMENTS: + { + /* Propagate the requirements to the matching input and output the ports */ + const MMAL_PARAMETER_BUFFER_REQUIREMENTS_T *req = (const MMAL_PARAMETER_BUFFER_REQUIREMENTS_T *)param; + uint32_t buffer_num_min = MMAL_MAX(port->buffer_num_min, req->buffer_num_min); + uint32_t buffer_num_recommended = MMAL_MAX(port->buffer_num_recommended, req->buffer_num_recommended); + uint32_t buffer_size_min = MMAL_MAX(port->buffer_size_min, req->buffer_size_min); + uint32_t buffer_size_recommended = MMAL_MAX(port->buffer_size_recommended, req->buffer_size_recommended); + + in->buffer_num_min = buffer_num_min; + in->buffer_num_recommended = buffer_num_recommended; + in->buffer_size_min = buffer_size_min; + in->buffer_size_recommended = buffer_size_recommended; + out->buffer_num_min = buffer_num_min; + out->buffer_num_recommended = buffer_num_recommended; + out->buffer_size_min = buffer_size_min; + out->buffer_size_recommended = buffer_size_recommended; + } + return MMAL_SUCCESS; + + default: + return MMAL_ENOSYS; + } +} + +/** Create an instance of a component */ +static MMAL_STATUS_T mmal_component_create_scheduler(const char *name, MMAL_COMPONENT_T *component) +{ + MMAL_COMPONENT_MODULE_T *module; + MMAL_STATUS_T status = MMAL_ENOMEM; + int disable_passthrough = 0; + unsigned int i; + + /* Allocate the context for our module */ + component->priv->module = module = vcos_calloc(1, sizeof(*module), "mmal module"); + if (!module) + return MMAL_ENOMEM; + + component->priv->pf_destroy = scheduler_component_destroy; + + /* Allocate and initialise all the ports for this component */ + component->input = mmal_ports_alloc(component, SCHEDULER_INPUT_PORTS_NUM, + MMAL_PORT_TYPE_INPUT, sizeof(MMAL_PORT_MODULE_T)); + if (!component->input) + goto error; + component->input_num = SCHEDULER_INPUT_PORTS_NUM; + for (i = 0; i < component->input_num; i++) + { + component->input[i]->priv->pf_enable = scheduler_port_enable; + component->input[i]->priv->pf_disable = scheduler_port_disable; + component->input[i]->priv->pf_flush = scheduler_port_flush; + component->input[i]->priv->pf_send = scheduler_port_send; + component->input[i]->priv->pf_set_format = scheduler_input_port_format_commit; + component->input[i]->priv->pf_parameter_set = scheduler_port_parameter_set; + component->input[i]->buffer_num_min = 1; + component->input[i]->buffer_num_recommended = 0; + component->input[i]->capabilities = MMAL_PORT_CAPABILITY_SUPPORTS_EVENT_FORMAT_CHANGE; + component->input[i]->priv->module->queue = mmal_queue_create(); + if (!component->input[i]->priv->module->queue) + goto error; + component->input[i]->priv->module->last_ts = MMAL_TIME_UNKNOWN; + } + + /* Override passthrough behaviour */ + if (strstr(name, ".copy")) + { + LOG_TRACE("disable passthrough on output ports"); + disable_passthrough = 1; + } + + component->output = mmal_ports_alloc(component, SCHEDULER_OUTPUT_PORTS_NUM, + MMAL_PORT_TYPE_OUTPUT, sizeof(MMAL_PORT_MODULE_T)); + if (!component->output) + goto error; + component->output_num = SCHEDULER_OUTPUT_PORTS_NUM; + for (i = 0; i < component->output_num; i++) + { + component->output[i]->priv->pf_enable = scheduler_port_enable; + component->output[i]->priv->pf_disable = scheduler_port_disable; + component->output[i]->priv->pf_flush = scheduler_port_flush; + component->output[i]->priv->pf_send = scheduler_port_send; + component->output[i]->priv->pf_set_format = scheduler_output_port_format_commit; + component->output[i]->priv->pf_parameter_set = scheduler_port_parameter_set; + component->output[i]->buffer_num_min = 1; + component->output[i]->buffer_num_recommended = 0; + component->output[i]->capabilities = disable_passthrough ? 0 : MMAL_PORT_CAPABILITY_PASSTHROUGH; + component->output[i]->priv->module->queue = mmal_queue_create(); + if (!component->output[i]->priv->module->queue) + goto error; + } + + /* Create the clock port (clock ports are managed by the framework) */ + component->clock = mmal_ports_clock_alloc(component, SCHEDULER_CLOCK_PORTS_NUM, 0, NULL); + if (!component->clock) + goto error; + component->clock_num = SCHEDULER_CLOCK_PORTS_NUM; + + status = mmal_component_action_register(component, scheduler_component_action); + if (status != MMAL_SUCCESS) + goto error; + + return MMAL_SUCCESS; + +error: + scheduler_component_destroy(component); + return status; +} + +MMAL_CONSTRUCTOR(mmal_register_component_scheduler); +void mmal_register_component_scheduler(void) +{ + mmal_component_supplier_register("scheduler", mmal_component_create_scheduler); +} + diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/components/sdl_audio_render.c b/external_src/raspicam-0.1.3/dependencies/mmal/components/sdl_audio_render.c new file mode 100644 index 0000000..43c2ff2 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/components/sdl_audio_render.c @@ -0,0 +1,278 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 "mmal.h" +#include "mmal_logging.h" +#include "core/mmal_component_private.h" +#include "core/mmal_port_private.h" + +#include + +#define FRAME_LENGTH 2048 + +/* Buffering requirements */ +#define INPUT_MIN_BUFFER_NUM 4 +#define INPUT_RECOMMENDED_BUFFER_NUM 8 + +/****************************/ +typedef struct MMAL_COMPONENT_MODULE_T +{ + MMAL_STATUS_T status; + MMAL_QUEUE_T *queue; + MMAL_BOOL_T audio_opened; + +} MMAL_COMPONENT_MODULE_T; + +/** Destroy a previously created component */ +static MMAL_STATUS_T sdl_component_destroy(MMAL_COMPONENT_T *component) +{ + MMAL_COMPONENT_MODULE_T *module = component->priv->module; + + if (module->audio_opened) + SDL_CloseAudio(); + SDL_QuitSubSystem(SDL_INIT_AUDIO); + + if(component->input_num) mmal_ports_free(component->input, 1); + if(module->queue) mmal_queue_destroy(module->queue); + vcos_free(module); + return MMAL_SUCCESS; +} + +static void sdl_callback( void *ctx, uint8_t *stream, int size ) +{ + MMAL_PORT_T *port = (MMAL_PORT_T *)ctx; + MMAL_COMPONENT_T *component = port->component; + MMAL_COMPONENT_MODULE_T *module = component->priv->module; + MMAL_BUFFER_HEADER_T *buffer; + unsigned int i, bytes; + + while (size > 0) + { + buffer = mmal_queue_get(module->queue); + if (!buffer) + { + LOG_ERROR("audio underrun"); + return; + } + + if (port->format->encoding == MMAL_ENCODING_PCM_SIGNED && + port->format->es->audio.bits_per_sample == 16) + { + bytes = buffer->length; + if (bytes > (unsigned int)size) bytes = size; + memcpy(stream, buffer->data + buffer->offset, bytes); + buffer->offset += bytes; + buffer->length -= bytes; + stream += bytes; + size -= bytes; + } + else if (port->format->es->audio.bits_per_sample == 32) + { + bytes = buffer->length; + if (bytes > 2 * (unsigned int)size) bytes = 2 * size; + vcos_assert(!(bytes&0x3)); + + if (port->format->encoding == MMAL_ENCODING_PCM_FLOAT) + { + float *in = (float *)(buffer->data + buffer->offset); + int16_t *out = (int16_t *)stream; + for (i = 0; i < bytes / 4; i++) + { + if (*in >= 1.0) *out = 32767; + else if (*in < -1.0) *out = -32768; + else *out = *in * 32768.0; + in++; out++; + } + } + else if (port->format->encoding == MMAL_ENCODING_PCM_SIGNED) + { + int32_t *in = (int32_t *)(buffer->data + buffer->offset); + int16_t *out = (int16_t *)stream; + for (i = 0; i < bytes / 4; i++) + *out++ = (*in++) >> 16; + } + buffer->offset += bytes; + buffer->length -= bytes; + stream += bytes / 2; + size -= bytes / 2; + } + + if (buffer->length) + { + /* We still have some data left for next time */ + mmal_queue_put_back(module->queue, buffer); + continue; + } + + /* Handle the EOS */ + if (buffer->flags & MMAL_BUFFER_HEADER_FLAG_EOS) + mmal_event_eos_send(port); + + buffer->offset = 0; + mmal_port_buffer_header_callback(port, buffer); + } +} + +/** Set format on a port */ +static MMAL_STATUS_T sdl_port_set_format(MMAL_PORT_T *port) +{ + MMAL_COMPONENT_T *component = port->component; + MMAL_COMPONENT_MODULE_T *module = component->priv->module; + SDL_AudioSpec desired, obtained; + + if (port->format->encoding != MMAL_ENCODING_PCM_SIGNED && + port->format->encoding != MMAL_ENCODING_PCM_FLOAT && + port->format->es->audio.bits_per_sample != 16 && + port->format->es->audio.bits_per_sample != 32) + { + LOG_ERROR("port does not support '%4.4s' at %ibps", + (char *)&port->format->encoding, port->format->es->audio.bits_per_sample); + return MMAL_EINVAL; + } + + if (module->audio_opened) + SDL_CloseAudio(); + module->audio_opened = MMAL_FALSE; + + desired.freq = port->format->es->audio.sample_rate; + desired.format = AUDIO_S16SYS; + desired.channels = port->format->es->audio.channels; + desired.callback = sdl_callback; + desired.userdata = port; + desired.samples = FRAME_LENGTH; + + /* Open the sound device. */ + if (SDL_OpenAudio( &desired, &obtained ) < 0) + return MMAL_ENOSYS; + module->audio_opened = MMAL_TRUE; + + /* Now have a look at what we got. */ + if (obtained.format != AUDIO_S16SYS) + return MMAL_ENOSYS; + + port->format->es->audio.sample_rate = obtained.freq; + port->format->es->audio.channels = obtained.channels; + port->buffer_size_min = obtained.samples * port->format->es->audio.channels * 2; + + return MMAL_SUCCESS; +} + +/** Enable processing on a port */ +static MMAL_STATUS_T sdl_port_enable(MMAL_PORT_T *port, MMAL_PORT_BH_CB_T cb) +{ + MMAL_PARAM_UNUSED(port); + MMAL_PARAM_UNUSED(cb); + SDL_PauseAudio( 0 ); + return MMAL_SUCCESS; +} + +/** Disable processing on a port */ +static MMAL_STATUS_T sdl_port_disable(MMAL_PORT_T *port) +{ + MMAL_COMPONENT_T *component = port->component; + MMAL_COMPONENT_MODULE_T *module = component->priv->module; + MMAL_BUFFER_HEADER_T *buffer; + + SDL_PauseAudio( 1 ); + + while((buffer = mmal_queue_get(module->queue))) + mmal_port_buffer_header_callback(port, buffer); + return MMAL_SUCCESS; +} + +static MMAL_STATUS_T sdl_port_send(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) +{ + MMAL_COMPONENT_T *component = port->component; + MMAL_COMPONENT_MODULE_T *module = component->priv->module; + + /* Handle event buffers */ + if (buffer->cmd) + { + LOG_ERROR("discarding event %i on port %p", (int)buffer->cmd, port); + buffer->length = 0; + mmal_port_buffer_header_callback(port, buffer); + return MMAL_SUCCESS; + } + + if (module->status != MMAL_SUCCESS) + return module->status; + + mmal_queue_put(module->queue, buffer); + + return MMAL_SUCCESS; +} + +/** Create an instance of a component */ +static MMAL_STATUS_T mmal_component_create_sdl(const char *name, MMAL_COMPONENT_T *component) +{ + MMAL_COMPONENT_MODULE_T *module; + + /* Check we're the requested component */ + if(strcmp(name, "sdl." MMAL_AUDIO_RENDER)) + return MMAL_ENOENT; + + if( SDL_WasInit(SDL_INIT_AUDIO) ) + return MMAL_ENXIO; + + /* Allocate our module context */ + component->priv->module = module = vcos_calloc(1, sizeof(*module), "mmal module"); + if(!module) + return MMAL_ENOMEM; + + if(SDL_Init(SDL_INIT_AUDIO|SDL_INIT_NOPARACHUTE) < 0) + return MMAL_ENXIO; + + /* Allocate the ports for this component */ + component->input = mmal_ports_alloc(component, 1, MMAL_PORT_TYPE_INPUT, 0); + if(!component->input) + goto error; + component->input_num = 1; + + module->queue = mmal_queue_create(); + if(!module->queue) + goto error; + + component->input[0]->priv->pf_set_format = sdl_port_set_format; + component->input[0]->priv->pf_enable = sdl_port_enable; + component->input[0]->priv->pf_disable = sdl_port_disable; + component->input[0]->priv->pf_send = sdl_port_send; + component->input[0]->buffer_num_min = INPUT_MIN_BUFFER_NUM; + component->input[0]->buffer_num_recommended = INPUT_RECOMMENDED_BUFFER_NUM; + + component->priv->pf_destroy = sdl_component_destroy; + return MMAL_SUCCESS; + + error: + sdl_component_destroy(component); + return MMAL_ENOMEM; +} + +MMAL_CONSTRUCTOR(mmal_register_component_sdl_audio); +void mmal_register_component_sdl_audio(void) +{ + mmal_component_supplier_register("sdl", mmal_component_create_sdl); +} diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/components/sdl_video_render.c b/external_src/raspicam-0.1.3/dependencies/mmal/components/sdl_video_render.c new file mode 100644 index 0000000..6f95d96 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/components/sdl_video_render.c @@ -0,0 +1,394 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 "mmal.h" +#include "mmal_logging.h" +#include "core/mmal_component_private.h" +#include "core/mmal_port_private.h" + +#include + +#define NUM_PORTS_INPUT 1 +#define SDL_WIDTH 800 +#define SDL_HEIGHT 600 + +/* Buffering requirements */ +#define INPUT_MIN_BUFFER_NUM 1 +#define INPUT_RECOMMENDED_BUFFER_NUM 4 + +/****************************/ +typedef struct MMAL_COMPONENT_MODULE_T +{ + SDL_Overlay *sdl_overlay; + SDL_Surface *sdl_surface; + unsigned int width; + unsigned int height; + MMAL_STATUS_T status; + MMAL_RECT_T display_region; + + MMAL_QUEUE_T *queue; + + SDL_Thread *thread; + MMAL_BOOL_T quit; +} MMAL_COMPONENT_MODULE_T; + +static MMAL_STATUS_T sdl_port_parameter_set(MMAL_PORT_T *port, const MMAL_PARAMETER_HEADER_T *param) +{ + MMAL_STATUS_T status = MMAL_ENOSYS; + MMAL_COMPONENT_T *component = port->component; + MMAL_COMPONENT_MODULE_T *module = component->priv->module; + + switch (param->id) + { + case MMAL_PARAMETER_DISPLAYREGION: + { + /* We only support setting the destination rectangle */ + const MMAL_DISPLAYREGION_T *display = (const MMAL_DISPLAYREGION_T *)param; + if (display->set & MMAL_DISPLAY_SET_DEST_RECT) + module->display_region = display->dest_rect; + status = MMAL_SUCCESS; + } + break; + default: + break; + } + return status; +} + +/** Destroy a previously created component */ +static MMAL_STATUS_T sdl_component_destroy(MMAL_COMPONENT_T *component) +{ + MMAL_COMPONENT_MODULE_T *module = component->priv->module; + SDL_Event event = {SDL_QUIT}; + + module->quit = MMAL_TRUE; + SDL_PushEvent(&event); + if(module->thread) + SDL_WaitThread(module->thread, NULL); + if(module->sdl_overlay) + SDL_FreeYUVOverlay(module->sdl_overlay); + if(module->sdl_surface) + SDL_FreeSurface(module->sdl_surface); + SDL_QuitSubSystem(SDL_INIT_VIDEO); + + if(component->input_num) mmal_ports_free(component->input, 1); + if(module->queue) mmal_queue_destroy(module->queue); + vcos_free(module); + return MMAL_SUCCESS; +} + +static MMAL_STATUS_T mmal_sdl_create_surface(MMAL_COMPONENT_MODULE_T *module) +{ + uint32_t flags; + int bpp; + int w = module->display_region.width; + int h = module->display_region.height; + + flags = SDL_ANYFORMAT | SDL_HWPALETTE | SDL_HWSURFACE | SDL_DOUBLEBUF | SDL_RESIZABLE; + bpp = SDL_VideoModeOK(w, h, 16, flags); + if(!bpp) + { + LOG_ERROR("no SDL video mode available"); + return MMAL_ENOSYS; + } + module->sdl_surface = SDL_SetVideoMode(w, h, bpp, flags); + if(!module->sdl_surface) + { + LOG_ERROR("cannot create SDL surface"); + return MMAL_ENOMEM; + } + return MMAL_SUCCESS; +} + + +/** Set format on a port */ +static MMAL_STATUS_T sdl_port_set_format(MMAL_PORT_T *port) +{ + MMAL_COMPONENT_T *component = port->component; + MMAL_COMPONENT_MODULE_T *module = component->priv->module; + MMAL_STATUS_T status; + + if ((status=mmal_sdl_create_surface(module)) != MMAL_SUCCESS) + return status; + + /* We only support I420 */ + if (port->format->encoding != MMAL_ENCODING_I420) + return MMAL_ENOSYS; + + /* Check if we need to re-create an overlay */ + if (module->sdl_overlay && + module->width == port->format->es->video.width && + module->height == port->format->es->video.height) + return MMAL_SUCCESS; /* Nothing to do */ + + if (module->sdl_overlay) + SDL_FreeYUVOverlay(module->sdl_overlay); + + /* Create overlay */ + module->sdl_overlay = + SDL_CreateYUVOverlay(port->format->es->video.width, + port->format->es->video.height, + SDL_YV12_OVERLAY, module->sdl_surface); + if (!module->sdl_overlay) + { + LOG_ERROR("cannot create SDL overlay"); + return MMAL_ENOSPC; + } + module->width = port->format->es->video.width; + module->height = port->format->es->video.height; + + port->buffer_size_min = module->width * module->height * 3 / 2; + return MMAL_SUCCESS; +} + +/** Enable processing on a port */ +static MMAL_STATUS_T sdl_port_enable(MMAL_PORT_T *port, MMAL_PORT_BH_CB_T cb) +{ + MMAL_PARAM_UNUSED(port); + MMAL_PARAM_UNUSED(cb); + return MMAL_SUCCESS; +} + +/** Disable processing on a port */ +static MMAL_STATUS_T sdl_port_disable(MMAL_PORT_T *port) +{ + MMAL_PARAM_UNUSED(port); + return MMAL_SUCCESS; +} + +/** Flush a port */ +static MMAL_STATUS_T sdl_port_flush(MMAL_PORT_T *port) +{ + MMAL_COMPONENT_T *component = port->component; + MMAL_COMPONENT_MODULE_T *module = component->priv->module; + MMAL_BUFFER_HEADER_T *buffer; + + /* Flush buffers that our component is holding on to. + * If the reading thread is holding onto a buffer it will send it back ASAP as well + * so no need to care about that. */ + while((buffer = mmal_queue_get(module->queue))) + mmal_port_buffer_header_callback(port, buffer); + + return MMAL_SUCCESS; +} + +static MMAL_BOOL_T sdl_do_processing(MMAL_COMPONENT_T *component) +{ + MMAL_PORT_T *port = component->input[0]; + MMAL_COMPONENT_MODULE_T *module = component->priv->module; + unsigned int width = port->format->es->video.width; + unsigned int height = port->format->es->video.height; + MMAL_BUFFER_HEADER_T *buffer; + uint8_t *src_plane[3]; + uint32_t *src_pitch; + unsigned int i, line; + MMAL_BOOL_T eos; + SDL_Rect rect; + + buffer = mmal_queue_get(module->queue); + if (!buffer) + return 0; + + eos = buffer->flags & MMAL_BUFFER_HEADER_FLAG_EOS; + + /* Handle event buffers */ + if (buffer->cmd) + { + MMAL_EVENT_FORMAT_CHANGED_T *event = mmal_event_format_changed_get(buffer); + if (event) + { + mmal_format_copy(port->format, event->format); + module->status = port->priv->pf_set_format(port); + if (module->status != MMAL_SUCCESS) + { + LOG_ERROR("format not set on port %p", port); + if (mmal_event_error_send(port->component, module->status) != MMAL_SUCCESS) + LOG_ERROR("unable to send an error event buffer"); + } + } + else + { + LOG_ERROR("discarding event %i on port %p", (int)buffer->cmd, port); + } + + buffer->length = 0; + mmal_port_buffer_header_callback(port, buffer); + return 1; + } + + if (module->status != MMAL_SUCCESS) + return 1; + + /* Ignore empty buffers */ + if (!buffer->length) + goto end; + + // FIXME: sanity check the size of the buffer + + /* Blit the buffer onto the overlay. */ + src_pitch = buffer->type->video.pitch; + src_plane[0] = buffer->data + buffer->type->video.offset[0]; + src_plane[1] = buffer->data + buffer->type->video.offset[2]; + src_plane[2] = buffer->data + buffer->type->video.offset[1]; + + SDL_LockYUVOverlay(module->sdl_overlay); + for (i=0; i<3; i++) + { + uint8_t *src = src_plane[i]; + uint8_t *dst = module->sdl_overlay->pixels[i]; + + if(i == 1) {width /= 2; height /= 2;} + for(line = 0; line < height; line++) + { + memcpy(dst, src, width); + src += src_pitch[i]; + dst += module->sdl_overlay->pitches[i]; + } + } + SDL_UnlockYUVOverlay(module->sdl_overlay); + + width = port->format->es->video.width; + height = port->format->es->video.height; + rect.x = module->display_region.x; + rect.w = module->display_region.width; + height = rect.w * height / width; + rect.y = module->display_region.y + (module->display_region.height - height) / 2; + rect.h = height; + + SDL_DisplayYUVOverlay(module->sdl_overlay, &rect); + + end: + buffer->offset = buffer->length = 0; + mmal_port_buffer_header_callback(port, buffer); + + /* Generate EOS events */ + if (eos) + mmal_event_eos_send(port); + + return 1; +} + +/*****************************************************************************/ +static void sdl_do_processing_loop(MMAL_COMPONENT_T *component) +{ + while (sdl_do_processing(component)); +} + +/** Buffer sending */ +static MMAL_STATUS_T sdl_port_send(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) +{ + MMAL_COMPONENT_T *component = port->component; + MMAL_COMPONENT_MODULE_T *module = component->priv->module; + + mmal_queue_put(module->queue, buffer); + mmal_component_action_trigger(port->component); + + return MMAL_SUCCESS; +} + +/** SDL event thread */ +static int sdl_event_thread(void *arg) +{ + MMAL_COMPONENT_T *component = (MMAL_COMPONENT_T *)arg; + MMAL_COMPONENT_MODULE_T *module = component->priv->module; + SDL_Event event; + + while (SDL_WaitEvent(&event)) + { + switch (event.type) + { + case SDL_QUIT: + if (!module->quit) + mmal_event_error_send(component, MMAL_SUCCESS); + return 0; + default: + break; + } + } + + return 0; +} + +/** Create an instance of a component */ +static MMAL_STATUS_T mmal_component_create_sdl(const char *name, MMAL_COMPONENT_T *component) +{ + MMAL_COMPONENT_MODULE_T *module; + MMAL_STATUS_T status = MMAL_ENOMEM; + + /* Check we're the requested component */ + if(strcmp(name, "sdl." MMAL_VIDEO_RENDER)) + return MMAL_ENOENT; + + if(SDL_Init(SDL_INIT_VIDEO|SDL_INIT_EVENTTHREAD|SDL_INIT_NOPARACHUTE) < 0) + return MMAL_ENXIO; + + /* Allocate our module context */ + component->priv->module = module = vcos_calloc(1, sizeof(*module), "mmal module"); + if(!module) return MMAL_ENOMEM; + + module->queue = mmal_queue_create(); + if(!module->queue) goto error; + + /* Allocate the ports for this component */ + component->input = mmal_ports_alloc(component, 1, MMAL_PORT_TYPE_INPUT, 0); + if(!component->input) goto error; + component->input_num = 1; + module->display_region.width = SDL_WIDTH; + module->display_region.height = SDL_HEIGHT; + + /************/ + + component->input[0]->priv->pf_set_format = sdl_port_set_format; + component->input[0]->priv->pf_enable = sdl_port_enable; + component->input[0]->priv->pf_disable = sdl_port_disable; + component->input[0]->priv->pf_flush = sdl_port_flush; + component->input[0]->priv->pf_send = sdl_port_send; + component->input[0]->priv->pf_parameter_set = sdl_port_parameter_set; + component->input[0]->buffer_num_min = INPUT_MIN_BUFFER_NUM; + component->input[0]->buffer_num_recommended = INPUT_RECOMMENDED_BUFFER_NUM; + + component->priv->pf_destroy = sdl_component_destroy; + + /* Create a thread to monitor SDL events */ + module->thread = SDL_CreateThread(sdl_event_thread, component); + + status = mmal_component_action_register(component, sdl_do_processing_loop); + if (status != MMAL_SUCCESS) + goto error; + + return MMAL_SUCCESS; + + error: + sdl_component_destroy(component); + return status; +} + +MMAL_CONSTRUCTOR(mmal_register_component_sdl); +void mmal_register_component_sdl(void) +{ + mmal_component_supplier_register("sdl", mmal_component_create_sdl); +} diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/components/spdif.c b/external_src/raspicam-0.1.3/dependencies/mmal/components/spdif.c new file mode 100644 index 0000000..d5747ee --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/components/spdif.c @@ -0,0 +1,496 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 "mmal.h" +#include "core/mmal_component_private.h" +#include "core/mmal_port_private.h" +#include "mmal_logging.h" + +#define SPDIF_AC3_FRAME_SIZE 6144 +#define SPDIF_EAC3_FRAME_SIZE (6144*4) +#define SPDIF_FRAME_SIZE SPDIF_EAC3_FRAME_SIZE + +/* Buffering requirements */ +#define INPUT_MIN_BUFFER_SIZE SPDIF_FRAME_SIZE +#define INPUT_MIN_BUFFER_NUM 2 +#define OUTPUT_MIN_BUFFER_SIZE SPDIF_FRAME_SIZE +#define OUTPUT_MIN_BUFFER_NUM 2 + +/*****************************************************************************/ +typedef struct MMAL_COMPONENT_MODULE_T +{ + MMAL_STATUS_T status; /**< current status of the component */ + +} MMAL_COMPONENT_MODULE_T; + +typedef struct MMAL_PORT_MODULE_T +{ + MMAL_QUEUE_T *queue; /**< queue for the buffers sent to the ports */ + MMAL_BOOL_T needs_configuring; /**< port is waiting for a format commit */ + +} MMAL_PORT_MODULE_T; + +/*****************************************************************************/ + +/*****************************************************************************/ + +static MMAL_STATUS_T spdif_send_event_format_changed(MMAL_COMPONENT_T *component, MMAL_PORT_T *port, + MMAL_ES_FORMAT_T *format) +{ + MMAL_COMPONENT_MODULE_T *module = component->priv->module; + MMAL_BUFFER_HEADER_T *buffer = NULL; + MMAL_EVENT_FORMAT_CHANGED_T *event; + + /* Get an event buffer */ + module->status = mmal_port_event_get(port, &buffer, MMAL_EVENT_FORMAT_CHANGED); + if (module->status != MMAL_SUCCESS) + { + LOG_ERROR("unable to get an event buffer"); + return module->status; + } + /* coverity[returned_null] Can't return null or call above would have failed */ + event = mmal_event_format_changed_get(buffer); + + /* Fill in the new format */ + if (port->format->encoding == MMAL_ENCODING_PCM_SIGNED) + mmal_format_copy(event->format, port->format); + else + mmal_format_copy(event->format, format); + + event->format->es->audio.sample_rate = format->es->audio.sample_rate; + + /* Pass on the buffer requirements */ + event->buffer_num_min = port->buffer_num_min; + event->buffer_size_min = port->buffer_size_min; + event->buffer_size_recommended = event->buffer_size_min; + event->buffer_num_recommended = port->buffer_num_recommended; + + port->priv->module->needs_configuring = 1; + mmal_port_event_send(port, buffer); + return MMAL_SUCCESS; +} + +/** Actual processing function */ +static MMAL_BOOL_T spdif_do_processing(MMAL_COMPONENT_T *component) +{ + static const uint8_t ac3_spdif_header[6] = {0x72,0xF8,0x1F,0x4E,0x1, 0}; + MMAL_COMPONENT_MODULE_T *module = component->priv->module; + MMAL_PORT_T *port_in = component->input[0]; + MMAL_PORT_T *port_out = component->output[0]; + MMAL_BUFFER_HEADER_T *in, *out; + unsigned int i, sample_rate, frame_size, spdif_frame_size; + uint8_t *in_data; + + if (port_out->priv->module->needs_configuring) + return 0; + + in = mmal_queue_get(port_in->priv->module->queue); + if (!in) + return 0; + + /* Handle event buffers */ + if (in->cmd) + { + MMAL_EVENT_FORMAT_CHANGED_T *event = mmal_event_format_changed_get(in); + if (event) + { + module->status = mmal_format_full_copy(port_in->format, event->format); + if (module->status == MMAL_SUCCESS) + module->status = port_in->priv->pf_set_format(port_in); + if (module->status != MMAL_SUCCESS) + { + LOG_ERROR("format not set on port %s %p (%i)", port_in->name, port_in, module->status); + if (mmal_event_error_send(component, module->status) != MMAL_SUCCESS) + LOG_ERROR("unable to send an error event buffer"); + } + } + else + { + LOG_ERROR("discarding event %i on port %s %p", (int)in->cmd, port_in->name, port_in); + } + + in->length = 0; + mmal_port_buffer_header_callback(port_in, in); + return 1; + } + + /* Don't do anything if we've already seen an error */ + if (module->status != MMAL_SUCCESS) + { + mmal_queue_put_back(port_in->priv->module->queue, in); + return 0; + } + + /* Discard empty buffers */ + if (!in->length && !in->flags) + { + mmal_port_buffer_header_callback(port_in, in); + return 1; + } + /* Discard codec config data as it's not needed */ + if (in->flags & MMAL_BUFFER_HEADER_FLAG_CONFIG) + { + LOG_DEBUG("config buffer %ibytes", in->length); + in->length = 0; + mmal_port_buffer_header_callback(port_in, in); + return 1; + } + + out = mmal_queue_get(port_out->priv->module->queue); + if (!out) + { + mmal_queue_put_back(port_in->priv->module->queue, in); + return 0; + } + + spdif_frame_size = SPDIF_AC3_FRAME_SIZE; + if (port_out->format->encoding == MMAL_ENCODING_EAC3) + spdif_frame_size = SPDIF_EAC3_FRAME_SIZE; + + /* Sanity check the output buffer is big enough */ + if (out->alloc_size < spdif_frame_size) + { + module->status = MMAL_EINVAL; + if (mmal_event_error_send(component, module->status) != MMAL_SUCCESS) + LOG_ERROR("unable to send an error event buffer"); + mmal_queue_put_back(port_in->priv->module->queue, in); + mmal_queue_put_back(port_out->priv->module->queue, out); + return 0; + } + + /* Special case for empty buffers carrying a flag */ + if (!in->length && in->flags) + { + out->length = 0; + goto end; + } + + LOG_DEBUG("frame: %lld, size %i", in->pts, in->length); + mmal_buffer_header_mem_lock(out); + mmal_buffer_header_mem_lock(in); + in_data = in->data + in->offset; + + /* Sanity check we're dealing with an AC3 frame */ + if (in->length < 5) + { + LOG_ERROR("invalid data size (%i bytes)", in->length); + goto discard; + } + + if (!(in_data[0] == 0x0B || in_data[1] == 0x77) && + !(in_data[0] == 0x77 || in_data[1] == 0x0B)) + { + LOG_ERROR("invalid data (%i bytes): %2.2x,%2.2x,%2.2x,%2.2x", + in->length, in_data[0], in_data[1], in_data[2], in_data[3]); + goto discard; + } + + /* We need to make sure we use the right sample rate + * to be able to play this at the right rate */ + if ((in_data[4] & 0xC0) == 0x40) sample_rate = 44100; + else if ((in_data[4] & 0xC0) == 0x80) sample_rate = 32000; + else sample_rate = 48000; + + /* If the sample rate changes, stop everything we're doing + * and signal the format change. */ + if (sample_rate != port_out->format->es->audio.sample_rate) + { + LOG_INFO("format change: %i->%i", + port_out->format->es->audio.sample_rate, sample_rate); + port_in->format->es->audio.sample_rate = sample_rate; + spdif_send_event_format_changed(component, port_out, port_in->format); + mmal_buffer_header_mem_unlock(in); + mmal_buffer_header_mem_unlock(out); + mmal_queue_put_back(port_in->priv->module->queue, in); + mmal_queue_put_back(port_out->priv->module->queue, out); + return 0; + } + + /* Build our S/PDIF frame. We assume that we need to send + * little endian S/PDIF data. */ + if (in->length > spdif_frame_size - 8) + LOG_ERROR("frame too big, truncating (%i/%i bytes)", + in->length, spdif_frame_size - 8); + frame_size = MMAL_MIN(in->length, spdif_frame_size - 8) / 2; + memcpy(out->data, ac3_spdif_header, sizeof(ac3_spdif_header)); + out->data[5] = in_data[5] & 0x7; /* bsmod */ + out->data[6] = frame_size & 0xFF; + out->data[7] = frame_size >> 8; + + /* Copy the AC3 data, reverting the endianness if required */ + if (in_data[0] == 0x0B) + { + for (i = 0; i < frame_size; i++) + { + out->data[8+i*2] = in_data[in->offset+i*2+1]; + out->data[8+i*2+1] = in_data[in->offset+i*2]; + } + } + else + memcpy(out->data + 8, in_data, in->length); + + /* The S/PDIF frame needs to be padded */ + memset(out->data + 8 + frame_size * 2, 0, + spdif_frame_size - frame_size * 2 - 8); + mmal_buffer_header_mem_unlock(in); + mmal_buffer_header_mem_unlock(out); + out->length = spdif_frame_size; + end: + out->offset = 0; + out->flags = in->flags; + out->pts = in->pts; + out->dts = in->dts; + + /* Send buffers back */ + in->length = 0; + mmal_port_buffer_header_callback(port_in, in); + mmal_port_buffer_header_callback(port_out, out); + return 1; + + discard: + mmal_buffer_header_mem_unlock(in); + mmal_buffer_header_mem_unlock(out); + in->length = 0; + mmal_queue_put_back(port_out->priv->module->queue, out); + mmal_port_buffer_header_callback(port_in, in); + return 1; +} + +/*****************************************************************************/ +static void spdif_do_processing_loop(MMAL_COMPONENT_T *component) +{ + while (spdif_do_processing(component)); +} + +/** Destroy a previously created component */ +static MMAL_STATUS_T spdif_component_destroy(MMAL_COMPONENT_T *component) +{ + unsigned int i; + + for(i = 0; i < component->input_num; i++) + if(component->input[i]->priv->module->queue) + mmal_queue_destroy(component->input[i]->priv->module->queue); + if(component->input_num) + mmal_ports_free(component->input, component->input_num); + + for(i = 0; i < component->output_num; i++) + if(component->output[i]->priv->module->queue) + mmal_queue_destroy(component->output[i]->priv->module->queue); + if(component->output_num) + mmal_ports_free(component->output, component->output_num); + + vcos_free(component->priv->module); + return MMAL_SUCCESS; +} + +/** Enable processing on a port */ +static MMAL_STATUS_T spdif_port_enable(MMAL_PORT_T *port, MMAL_PORT_BH_CB_T cb) +{ + MMAL_PARAM_UNUSED(cb); + + /* We need to propagate the buffer requirements when the input port is + * enabled */ + if (port->type == MMAL_PORT_TYPE_INPUT) + return port->priv->pf_set_format(port); + + return MMAL_SUCCESS; +} + +/** Flush a port */ +static MMAL_STATUS_T spdif_port_flush(MMAL_PORT_T *port) +{ + MMAL_PORT_MODULE_T *port_module = port->priv->module; + MMAL_BUFFER_HEADER_T *buffer; + + /* Flush buffers that our component is holding on to */ + buffer = mmal_queue_get(port_module->queue); + while(buffer) + { + mmal_port_buffer_header_callback(port, buffer); + buffer = mmal_queue_get(port_module->queue); + } + + return MMAL_SUCCESS; +} + +/** Disable processing on a port */ +static MMAL_STATUS_T spdif_port_disable(MMAL_PORT_T *port) +{ + /* We just need to flush our internal queue */ + return spdif_port_flush(port); +} + +/** Send a buffer header to a port */ +static MMAL_STATUS_T spdif_port_send(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) +{ + mmal_queue_put(port->priv->module->queue, buffer); + mmal_component_action_trigger(port->component); + return MMAL_SUCCESS; +} + +/** Set format on input port */ +static MMAL_STATUS_T spdif_input_port_format_commit(MMAL_PORT_T *in) +{ + MMAL_COMPONENT_T *component = in->component; + MMAL_PORT_T *out = component->output[0]; + + /* Sanity check we cope with this format */ + if (in->format->encoding != MMAL_ENCODING_AC3 && + in->format->encoding != MMAL_ENCODING_EAC3) + return MMAL_ENXIO; + + LOG_INFO("%4.4s, %iHz, %ichan, %ibps", (char *)&in->format->encoding, + in->format->es->audio.sample_rate, in->format->es->audio.channels, + in->format->bitrate); + + /* TODO: should we check the bitrate to see if that fits in an S/PDIF + * frame? */ + + /* Check if there's anything to propagate to the output port */ + if (!mmal_format_compare(in->format, out->format)) + return MMAL_SUCCESS; + if (out->format->encoding == MMAL_ENCODING_PCM_SIGNED && + in->format->es->audio.sample_rate == + out->format->es->audio.sample_rate) + return MMAL_SUCCESS; + + /* If the output port is not enabled we just need to update its format. + * Otherwise we'll have to trigger a format changed event for it. */ + if (!out->is_enabled) + { + if (out->format->encoding != MMAL_ENCODING_PCM_SIGNED) + mmal_format_copy(out->format, in->format); + out->format->es->audio.sample_rate = in->format->es->audio.sample_rate; + return MMAL_SUCCESS; + } + + /* Send an event on the output port */ + return spdif_send_event_format_changed(component, out, in->format); +} + +/** Set format on output port */ +static MMAL_STATUS_T spdif_output_port_format_commit(MMAL_PORT_T *out) +{ + int supported = 0; + + if (out->format->type == MMAL_ES_TYPE_AUDIO && + out->format->encoding == MMAL_ENCODING_PCM_SIGNED && + out->format->es->audio.channels == 2 && + out->format->es->audio.bits_per_sample == 16) + supported = 1; + if (out->format->type == MMAL_ES_TYPE_AUDIO && + (out->format->encoding == MMAL_ENCODING_AC3 || + out->format->encoding == MMAL_ENCODING_EAC3)) + supported = 1; + + if (!supported) + { + LOG_ERROR("invalid format %4.4s, %ichan, %ibps", + (char *)&out->format->encoding, out->format->es->audio.channels, + out->format->es->audio.bits_per_sample); + return MMAL_EINVAL; + } + + out->priv->module->needs_configuring = 0; + mmal_component_action_trigger(out->component); + return MMAL_SUCCESS; +} + +/** Create an instance of a component */ +static MMAL_STATUS_T mmal_component_create_spdif(const char *name, MMAL_COMPONENT_T *component) +{ + MMAL_COMPONENT_MODULE_T *module; + MMAL_STATUS_T status = MMAL_ENOMEM; + MMAL_PARAM_UNUSED(name); + + /* Allocate the context for our module */ + component->priv->module = module = vcos_malloc(sizeof(*module), "mmal module"); + if (!module) + return MMAL_ENOMEM; + memset(module, 0, sizeof(*module)); + + component->priv->pf_destroy = spdif_component_destroy; + + /* Allocate and initialise all the ports for this component */ + component->input = mmal_ports_alloc(component, 1, MMAL_PORT_TYPE_INPUT, sizeof(MMAL_PORT_MODULE_T)); + if(!component->input) + goto error; + component->input_num = 1; + component->input[0]->priv->pf_enable = spdif_port_enable; + component->input[0]->priv->pf_disable = spdif_port_disable; + component->input[0]->priv->pf_flush = spdif_port_flush; + component->input[0]->priv->pf_send = spdif_port_send; + component->input[0]->priv->pf_set_format = spdif_input_port_format_commit; + component->input[0]->priv->module->queue = mmal_queue_create(); + if(!component->input[0]->priv->module->queue) + goto error; + + component->output = mmal_ports_alloc(component, 1, MMAL_PORT_TYPE_OUTPUT, sizeof(MMAL_PORT_MODULE_T)); + if(!component->output) + goto error; + component->output_num = 1; + component->output[0]->priv->pf_enable = spdif_port_enable; + component->output[0]->priv->pf_disable = spdif_port_disable; + component->output[0]->priv->pf_flush = spdif_port_flush; + component->output[0]->priv->pf_send = spdif_port_send; + component->output[0]->priv->pf_set_format = spdif_output_port_format_commit; + component->output[0]->priv->module->queue = mmal_queue_create(); + if(!component->output[0]->priv->module->queue) + goto error; + + status = mmal_component_action_register(component, spdif_do_processing_loop); + if (status != MMAL_SUCCESS) + goto error; + + component->input[0]->format->type = MMAL_ES_TYPE_AUDIO; + component->input[0]->format->encoding = MMAL_ENCODING_AC3; + component->input[0]->buffer_size_min = + component->input[0]->buffer_size_recommended = INPUT_MIN_BUFFER_SIZE; + component->input[0]->buffer_num_min = + component->input[0]->buffer_num_recommended = INPUT_MIN_BUFFER_NUM; + + component->output[0]->format->type = MMAL_ES_TYPE_AUDIO; + component->output[0]->format->encoding = MMAL_ENCODING_AC3; + component->output[0]->format->es->audio.channels = 2; + component->output[0]->format->es->audio.bits_per_sample = 16; + component->output[0]->buffer_size_min = + component->output[0]->buffer_size_recommended = OUTPUT_MIN_BUFFER_SIZE; + component->output[0]->buffer_num_min = + component->output[0]->buffer_num_recommended = OUTPUT_MIN_BUFFER_NUM; + + return MMAL_SUCCESS; + + error: + spdif_component_destroy(component); + return status; +} + +MMAL_CONSTRUCTOR(mmal_register_component_spdif); +void mmal_register_component_spdif(void) +{ + mmal_component_supplier_register("spdif", mmal_component_create_spdif); +} diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/components/splitter.c b/external_src/raspicam-0.1.3/dependencies/mmal/components/splitter.c new file mode 100644 index 0000000..7753a16 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/components/splitter.c @@ -0,0 +1,345 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 "mmal.h" +#include "core/mmal_component_private.h" +#include "core/mmal_port_private.h" +#include "mmal_logging.h" + +#define SPLITTER_OUTPUT_PORTS_NUM 4 /* 4 should do for now */ + +/*****************************************************************************/ +typedef struct MMAL_COMPONENT_MODULE_T +{ + uint32_t enabled_flags; /**< Flags indicating which output port is enabled */ + uint32_t sent_flags; /**< Flags indicating which output port we've already sent data to */ + MMAL_BOOL_T error; /**< Error state */ + +} MMAL_COMPONENT_MODULE_T; + +typedef struct MMAL_PORT_MODULE_T +{ + MMAL_QUEUE_T *queue; /**< queue for the buffers sent to the ports */ + +} MMAL_PORT_MODULE_T; + +/*****************************************************************************/ + +/** Destroy a previously created component */ +static MMAL_STATUS_T splitter_component_destroy(MMAL_COMPONENT_T *component) +{ + unsigned int i; + + for(i = 0; i < component->input_num; i++) + if(component->input[i]->priv->module->queue) + mmal_queue_destroy(component->input[i]->priv->module->queue); + if(component->input_num) + mmal_ports_free(component->input, component->input_num); + + for(i = 0; i < component->output_num; i++) + if(component->output[i]->priv->module->queue) + mmal_queue_destroy(component->output[i]->priv->module->queue); + if(component->output_num) + mmal_ports_free(component->output, component->output_num); + + vcos_free(component->priv->module); + return MMAL_SUCCESS; +} + +/** Enable processing on a port */ +static MMAL_STATUS_T splitter_port_enable(MMAL_PORT_T *port, MMAL_PORT_BH_CB_T cb) +{ +#if 0 + MMAL_COMPONENT_T *component = port->component; + uint32_t buffer_num, buffer_size; + unsigned int i; + + /* Find the max and apply that to all ports */ + buffer_num = component->input[0]->buffer_num; + buffer_size = component->input[0]->buffer_size; + for (i = 0; i < component->output_num; i++) + { + buffer_num = MMAL_MAX(buffer_num, component->output[i]->buffer_num); + buffer_size = MMAL_MAX(buffer_num, component->output[i]->buffer_size); + } + component->input[0]->buffer_num = buffer_num; + component->input[0]->buffer_size = buffer_size; + for (i = 0; i < component->output_num; i++) + { + component->output[i]->buffer_num = buffer_num; + component->output[i]->buffer_size = buffer_num; + } +#endif + + MMAL_PARAM_UNUSED(cb); + if (port->buffer_size) + if (port->type == MMAL_PORT_TYPE_OUTPUT) + port->component->priv->module->enabled_flags |= (1<index); + return MMAL_SUCCESS; +} + +/** Flush a port */ +static MMAL_STATUS_T splitter_port_flush(MMAL_PORT_T *port) +{ + MMAL_PORT_MODULE_T *port_module = port->priv->module; + MMAL_BUFFER_HEADER_T *buffer; + + /* Flush buffers that our component is holding on to */ + buffer = mmal_queue_get(port_module->queue); + while(buffer) + { + mmal_port_buffer_header_callback(port, buffer); + buffer = mmal_queue_get(port_module->queue); + } + + if (port->type == MMAL_PORT_TYPE_INPUT) + port->component->priv->module->sent_flags = 0; + + return MMAL_SUCCESS; +} + +/** Disable processing on a port */ +static MMAL_STATUS_T splitter_port_disable(MMAL_PORT_T *port) +{ + if (port->type == MMAL_PORT_TYPE_OUTPUT) + port->component->priv->module->enabled_flags &= ~(1<index); + + /* We just need to flush our internal queue */ + return splitter_port_flush(port); +} + +/** Send a buffer header to a port */ +static MMAL_STATUS_T splitter_send_output(MMAL_BUFFER_HEADER_T *buffer, MMAL_PORT_T *out_port) +{ + MMAL_BUFFER_HEADER_T *out; + MMAL_STATUS_T status; + + /* Get a buffer header from output port */ + out = mmal_queue_get(out_port->priv->module->queue); + if (!out) + return MMAL_EAGAIN; + + /* Copy our input buffer header */ + status = mmal_buffer_header_replicate(out, buffer); + if (status != MMAL_SUCCESS) + goto error; + + /* Send buffer back */ + mmal_port_buffer_header_callback(out_port, out); + return MMAL_SUCCESS; + + error: + mmal_queue_put_back(out_port->priv->module->queue, out); + return status; +} + +/** Send a buffer header to a port */ +static MMAL_STATUS_T splitter_port_send(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) +{ + MMAL_COMPONENT_T *component = port->component; + MMAL_COMPONENT_MODULE_T *module = component->priv->module; + MMAL_PORT_T *in_port, *out_port; + MMAL_BUFFER_HEADER_T *in; + MMAL_STATUS_T status; + unsigned int i; + + mmal_queue_put(port->priv->module->queue, buffer); + + if (module->error) + return MMAL_SUCCESS; /* Just do nothing */ + + /* Get input buffer header */ + in_port = component->input[0]; + in = mmal_queue_get(in_port->priv->module->queue); + if (!in) + return MMAL_SUCCESS; /* Nothing to do */ + + for (i = 0; i < component->output_num; i++) + { + out_port = component->output[i]; + status = splitter_send_output(in, out_port); + + if (status != MMAL_SUCCESS && status != MMAL_EAGAIN) + goto error; + + if (status == MMAL_SUCCESS) + module->sent_flags |= (1<sent_flags & module->enabled_flags) == module->enabled_flags) + { + in->length = 0; /* Consume the input buffer */ + mmal_port_buffer_header_callback(in_port, in); + module->sent_flags = 0; + return MMAL_SUCCESS; + } + + /* We're not done yet so put the buffer back in the queue */ + mmal_queue_put(in_port->priv->module->queue, in); + return MMAL_SUCCESS; + + error: + mmal_queue_put(in_port->priv->module->queue, in); + + status = mmal_event_error_send(port->component, status); + if (status != MMAL_SUCCESS) + { + LOG_ERROR("unable to send an error event buffer (%i)", (int)status); + return MMAL_SUCCESS; + } + module->error = 1; + return MMAL_SUCCESS; +} + +/** Set format on a port */ +static MMAL_STATUS_T splitter_port_format_commit(MMAL_PORT_T *port) +{ + MMAL_COMPONENT_T *component = port->component; + MMAL_STATUS_T status; + unsigned int i; + + /* Sanity check */ + if (port->type == MMAL_PORT_TYPE_OUTPUT) + { + LOG_ERROR("output port is read-only"); + return MMAL_EINVAL; + } + + /* Commit the format on all output ports */ + for (i = 0; i < component->output_num; i++) + { + status = mmal_format_full_copy(component->output[i]->format, port->format); + if (status != MMAL_SUCCESS) + return status; + } + + return MMAL_SUCCESS; +} + +static MMAL_STATUS_T splitter_port_parameter_set(MMAL_PORT_T *port, const MMAL_PARAMETER_HEADER_T *param) +{ + MMAL_COMPONENT_T *component = port->component; + unsigned int i; + + switch (param->id) + { + case MMAL_PARAMETER_BUFFER_REQUIREMENTS: + { + /* Propagate the requirements to all the ports */ + const MMAL_PARAMETER_BUFFER_REQUIREMENTS_T *req = (const MMAL_PARAMETER_BUFFER_REQUIREMENTS_T *)param; + uint32_t buffer_num_min = MMAL_MAX(port->buffer_num_min, req->buffer_num_min); + uint32_t buffer_num_recommended = MMAL_MAX(port->buffer_num_recommended, req->buffer_num_recommended); + uint32_t buffer_size_min = MMAL_MAX(port->buffer_size_min, req->buffer_size_min); + uint32_t buffer_size_recommended = MMAL_MAX(port->buffer_size_recommended, req->buffer_size_recommended); + + component->input[0]->buffer_num_min = buffer_num_min; + component->input[0]->buffer_num_recommended = buffer_num_recommended; + component->input[0]->buffer_size_min = buffer_size_min; + component->input[0]->buffer_size_recommended = buffer_size_recommended; + for (i = 0; i < component->output_num; i++) + { + component->output[i]->buffer_num_min = buffer_num_min; + component->output[i]->buffer_num_recommended = buffer_num_recommended; + component->output[i]->buffer_size_min = buffer_size_min; + component->output[i]->buffer_size_recommended = buffer_size_recommended; + } + + } + return MMAL_SUCCESS; + + default: + return MMAL_ENOSYS; + } +} + +/** Create an instance of a component */ +static MMAL_STATUS_T mmal_component_create_splitter(const char *name, MMAL_COMPONENT_T *component) +{ + MMAL_COMPONENT_MODULE_T *module; + MMAL_STATUS_T status = MMAL_ENOMEM; + unsigned int i; + MMAL_PARAM_UNUSED(name); + + /* Allocate the context for our module */ + component->priv->module = module = vcos_malloc(sizeof(*module), "mmal module"); + if (!module) + return MMAL_ENOMEM; + memset(module, 0, sizeof(*module)); + + component->priv->pf_destroy = splitter_component_destroy; + + /* Allocate and initialise all the ports for this component */ + component->input = mmal_ports_alloc(component, 1, MMAL_PORT_TYPE_INPUT, sizeof(MMAL_PORT_MODULE_T)); + if(!component->input) + goto error; + component->input_num = 1; + component->input[0]->priv->pf_enable = splitter_port_enable; + component->input[0]->priv->pf_disable = splitter_port_disable; + component->input[0]->priv->pf_flush = splitter_port_flush; + component->input[0]->priv->pf_send = splitter_port_send; + component->input[0]->priv->pf_set_format = splitter_port_format_commit; + component->input[0]->priv->pf_parameter_set = splitter_port_parameter_set; + component->input[0]->buffer_num_min = 1; + component->input[0]->buffer_num_recommended = 0; + component->input[0]->priv->module->queue = mmal_queue_create(); + if(!component->input[0]->priv->module->queue) + goto error; + + component->output = mmal_ports_alloc(component, SPLITTER_OUTPUT_PORTS_NUM, + MMAL_PORT_TYPE_OUTPUT, sizeof(MMAL_PORT_MODULE_T)); + if(!component->output) + goto error; + component->output_num = SPLITTER_OUTPUT_PORTS_NUM; + for(i = 0; i < component->output_num; i++) + { + component->output[i]->priv->pf_enable = splitter_port_enable; + component->output[i]->priv->pf_disable = splitter_port_disable; + component->output[i]->priv->pf_flush = splitter_port_flush; + component->output[i]->priv->pf_send = splitter_port_send; + component->output[i]->priv->pf_set_format = splitter_port_format_commit; + component->output[i]->priv->pf_parameter_set = splitter_port_parameter_set; + component->output[i]->buffer_num_min = 1; + component->output[i]->buffer_num_recommended = 0; + component->output[i]->capabilities = MMAL_PORT_CAPABILITY_PASSTHROUGH; + component->output[i]->priv->module->queue = mmal_queue_create(); + if(!component->output[i]->priv->module->queue) + goto error; + } + + return MMAL_SUCCESS; + + error: + splitter_component_destroy(component); + return status; +} + +MMAL_CONSTRUCTOR(mmal_register_component_splitter); +void mmal_register_component_splitter(void) +{ + mmal_component_supplier_register("splitter", mmal_component_create_splitter); +} diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/core/CMakeLists.txt b/external_src/raspicam-0.1.3/dependencies/mmal/core/CMakeLists.txt new file mode 100644 index 0000000..388d493 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/core/CMakeLists.txt @@ -0,0 +1,24 @@ +add_library (mmal_core ${LIBRARY_TYPE} + mmal_format.c + mmal_port.c + mmal_port_clock.c + mmal_component.c + mmal_buffer.c + mmal_queue.c + mmal_pool.c + mmal_events.c + mmal_logging.c + mmal_clock.c +) + +target_link_libraries (mmal_core vcos) + +install(TARGETS mmal_core DESTINATION lib) +install(FILES + mmal_buffer_private.h + mmal_clock_private.h + mmal_component_private.h + mmal_core_private.h + mmal_port_private.h + DESTINATION include/interface/mmal/core +) diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/core/mmal_buffer.c b/external_src/raspicam-0.1.3/dependencies/mmal/core/mmal_buffer.c new file mode 100644 index 0000000..3f83063 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/core/mmal_buffer.c @@ -0,0 +1,188 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 "mmal.h" +#include "mmal_buffer.h" +#include "core/mmal_buffer_private.h" +#include "mmal_logging.h" + +#define ROUND_UP(s,align) ((((unsigned long)(s)) & ~((align)-1)) + (align)) +#define DEFAULT_COMMAND_SIZE 256 /**< 256 bytes of space for commands */ +#define ALIGN 8 + +/** Acquire a buffer header */ +void mmal_buffer_header_acquire(MMAL_BUFFER_HEADER_T *header) +{ +#ifdef ENABLE_MMAL_EXTRA_LOGGING + LOG_TRACE("%p (%i)", header, (int)header->priv->refcount+1); +#endif + header->priv->refcount++; +} + +/** Reset a buffer header */ +void mmal_buffer_header_reset(MMAL_BUFFER_HEADER_T *header) +{ + header->length = 0; + header->offset = 0; + header->flags = 0; + header->pts = MMAL_TIME_UNKNOWN; + header->dts = MMAL_TIME_UNKNOWN; +} + +/** Release a buffer header */ +void mmal_buffer_header_release(MMAL_BUFFER_HEADER_T *header) +{ +#ifdef ENABLE_MMAL_EXTRA_LOGGING + LOG_TRACE("%p (%i)", header, (int)header->priv->refcount-1); +#endif + + if(--header->priv->refcount != 0) + return; + + if (header->priv->pf_pre_release) + { + if (header->priv->pf_pre_release(header, header->priv->pre_release_userdata)) + return; /* delay releasing the buffer */ + } + mmal_buffer_header_release_continue(header); +} + +/** Finalise buffer release following a pre-release event */ +void mmal_buffer_header_release_continue(MMAL_BUFFER_HEADER_T *header) +{ + mmal_buffer_header_reset(header); + if (header->priv->reference) + mmal_buffer_header_release(header->priv->reference); + header->priv->reference = 0; + header->priv->pf_release(header); +} + +/** Replicate a buffer header */ +MMAL_STATUS_T mmal_buffer_header_replicate(MMAL_BUFFER_HEADER_T *dest, + MMAL_BUFFER_HEADER_T *src) +{ +#ifdef ENABLE_MMAL_EXTRA_LOGGING + LOG_TRACE("dest: %p src: %p", dest, src); +#endif + + if (!dest || !src || dest->priv->reference) + return MMAL_EINVAL; + + mmal_buffer_header_acquire(src); + dest->priv->reference = src; + + /* Copy all the relevant fields */ + dest->cmd = src->cmd; + dest->alloc_size = src->alloc_size; + dest->data = src->data; + dest->offset = src->offset; + dest->length = src->length; + dest->flags = src->flags; + dest->pts = src->pts; + dest->dts = src->dts; + *dest->type = *src->type; + return MMAL_SUCCESS; +} + +/** Get the size in bytes of a fully initialised MMAL_BUFFER_HEADER_T */ +unsigned int mmal_buffer_header_size(MMAL_BUFFER_HEADER_T *header) +{ + unsigned int header_size; + + header_size = ROUND_UP(sizeof(*header), ALIGN); + header_size += ROUND_UP(sizeof(*header->type), ALIGN); + header_size += ROUND_UP(DEFAULT_COMMAND_SIZE, ALIGN); + header_size += ROUND_UP(sizeof(*header->priv), ALIGN); + return header_size; +} + +/** Initialise a MMAL_BUFFER_HEADER_T */ +MMAL_BUFFER_HEADER_T *mmal_buffer_header_initialise(void *mem, unsigned int length) +{ + MMAL_BUFFER_HEADER_T *header; + unsigned int header_size = mmal_buffer_header_size(0); + + if(length < header_size) + return 0; + + memset(mem, 0, header_size); + + header = (MMAL_BUFFER_HEADER_T *)mem; + header->type = (void *)&header[1]; + header->priv = (MMAL_BUFFER_HEADER_PRIVATE_T *)&header->type[1]; + return header; +} + +/** Return a pointer to the area reserved for the driver */ +MMAL_DRIVER_BUFFER_T *mmal_buffer_header_driver_data(MMAL_BUFFER_HEADER_T *header) +{ + return (MMAL_DRIVER_BUFFER_T *)header->priv->driver_area; +} + +/** Return a pointer to a referenced buffer header */ +MMAL_BUFFER_HEADER_T *mmal_buffer_header_reference(MMAL_BUFFER_HEADER_T *header) +{ + return header->priv->reference; +} + +#ifdef __VIDEOCORE__ +# include "vcfw/rtos/common/rtos_common_mem.h" +#endif + +/** Lock the data buffer contained in the buffer header */ +MMAL_STATUS_T mmal_buffer_header_mem_lock(MMAL_BUFFER_HEADER_T *header) +{ +#ifdef __VIDEOCORE__ + uint8_t *data = mem_lock((MEM_HANDLE_T)header->data); + if (!data) + return MMAL_EINVAL; + header->priv->payload_handle = (void *)header->data; + header->data = data; +#else + MMAL_PARAM_UNUSED(header); +#endif + + return MMAL_SUCCESS; +} + +/** Unlock the data buffer contained in the buffer header */ +void mmal_buffer_header_mem_unlock(MMAL_BUFFER_HEADER_T *header) +{ +#ifdef __VIDEOCORE__ + mem_unlock((MEM_HANDLE_T)header->priv->payload_handle); + header->data = header->priv->payload_handle; +#else + MMAL_PARAM_UNUSED(header); +#endif +} + +/** Set a pre-release callback for a buffer header */ +void mmal_buffer_header_pre_release_cb_set(MMAL_BUFFER_HEADER_T *header, MMAL_BH_PRE_RELEASE_CB_T cb, void *userdata) +{ + header->priv->pf_pre_release = cb; + header->priv->pre_release_userdata = userdata; +} diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/core/mmal_buffer_private.h b/external_src/raspicam-0.1.3/dependencies/mmal/core/mmal_buffer_private.h new file mode 100644 index 0000000..d24be20 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/core/mmal_buffer_private.h @@ -0,0 +1,86 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 MMAL_BUFFER_PRIVATE_H +#define MMAL_BUFFER_PRIVATE_H + +/** Typedef for the private area the framework reserves for the driver / communication layer */ +typedef struct MMAL_DRIVER_BUFFER_T MMAL_DRIVER_BUFFER_T; + +/** Size of the private area the framework reserves for the driver / communication layer */ +#define MMAL_DRIVER_BUFFER_SIZE 32 + +/** Typedef for the framework's private area in the buffer header */ +typedef struct MMAL_BUFFER_HEADER_PRIVATE_T +{ + /** Callback invoked just prior to actually releasing the buffer header. Returns TRUE if + * release should be delayed. */ + MMAL_BH_PRE_RELEASE_CB_T pf_pre_release; + void *pre_release_userdata; + + /** Callback used to release / recycle the buffer header. This needs to be set by + * whoever allocates the buffer header. */ + void (*pf_release)(struct MMAL_BUFFER_HEADER_T *header); + void *owner; /**< Context set by the allocator of the buffer header and passed + during the release callback */ + + int32_t refcount; /**< Reference count of the buffer header. When it reaches 0, + the release callback will be called. */ + + MMAL_BUFFER_HEADER_T *reference; /**< Reference to another acquired buffer header. */ + + /** Callback used to free the payload associated with this buffer header. This is only + * used if the buffer header was created by MMAL with a payload associated with it. */ + void (*pf_payload_free)(void *payload_context, void *payload); + void *payload; /**< Pointer / handle to the allocated payload buffer */ + void *payload_context; /**< Pointer to the context of the payload allocator */ + uint32_t payload_size; /**< Allocated size in bytes of payload buffer */ + + void *component_data; /**< Field reserved for use by the component */ + void *payload_handle; /**< Field reserved for mmal_buffer_header_mem_lock */ + + uint8_t driver_area[MMAL_DRIVER_BUFFER_SIZE]; + +} MMAL_BUFFER_HEADER_PRIVATE_T; + +/** Get the size in bytes of a fully initialised MMAL_BUFFER_HEADER_T */ +unsigned int mmal_buffer_header_size(MMAL_BUFFER_HEADER_T *header); + +/** Initialise a MMAL_BUFFER_HEADER_T */ +MMAL_BUFFER_HEADER_T *mmal_buffer_header_initialise(void *mem, unsigned int length); + +/** Return a pointer to the area reserved for the driver. + */ +MMAL_DRIVER_BUFFER_T *mmal_buffer_header_driver_data(MMAL_BUFFER_HEADER_T *); + +/** Return a pointer to a referenced buffer header. + * It is the caller's responsibility to ensure that the reference is still + * valid when using it. + */ +MMAL_BUFFER_HEADER_T *mmal_buffer_header_reference(MMAL_BUFFER_HEADER_T *header); + +#endif /* MMAL_BUFFER_PRIVATE_H */ diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/core/mmal_clock.c b/external_src/raspicam-0.1.3/dependencies/mmal/core/mmal_clock.c new file mode 100644 index 0000000..23f3043 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/core/mmal_clock.c @@ -0,0 +1,892 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 "interface/vcos/vcos.h" +#include "interface/mmal/mmal_logging.h" +#include "interface/mmal/util/mmal_list.h" +#include "interface/mmal/util/mmal_util_rational.h" +#include "interface/mmal/core/mmal_clock_private.h" + +#ifdef __VIDEOCORE__ +/* Use RTOS timer for improved accuracy */ +# include "vcfw/rtos/rtos.h" +# define USE_RTOS_TIMER +#endif + + +/*****************************************************************************/ +#ifdef USE_RTOS_TIMER +# define MIN_TIMER_DELAY 1 /* microseconds */ +#else +# define MIN_TIMER_DELAY 10000 /* microseconds */ +#endif + +/* 1.0 in Q16 format */ +#define Q16_ONE (1 << 16) + +/* Maximum number of pending requests */ +#define CLOCK_REQUEST_SLOTS 32 + +/* Number of microseconds the clock tries to service requests early + * to account for processing overhead */ +#define CLOCK_TARGET_OFFSET 20 + +/* Default wait time (in microseconds) when the clock is paused. */ +#define CLOCK_WAIT_TIME 200000LL + +/* In order to prevent unnecessary clock jitter when updating the local media-time of the + * clock, an upper and lower threshold is used. If the difference between the reference + * media-time and local media-time is greater than the upper threshold, local media-time + * is set to the reference time. Below this threshold, a weighted moving average is applied + * to the difference. If this is greater than the lower threshold, the local media-time is + * adjusted by the average. Anything below the lower threshold is ignored. */ +#define CLOCK_UPDATE_THRESHOLD_LOWER 8000 /* microseconds */ +#define CLOCK_UPDATE_THRESHOLD_UPPER 50000 /* microseconds */ + +/* Default threshold after which backward jumps in media time are treated as a discontinuity. */ +#define CLOCK_DISCONT_THRESHOLD 1000000 /* microseconds */ + +/* Default duration for which a discontinuity applies. Used for wall time duration for which + * a discontinuity continues to cause affected requests to fire immediately, and as the media + * time span for detecting discontinuous requests. */ +#define CLOCK_DISCONT_DURATION 1000000 /* microseconds */ + +/* Absolute value macro */ +#define ABS_VALUE(v) (((v) < 0) ? -(v) : (v)) + +/* Macros used to make clock access thread-safe */ +#define LOCK(p) vcos_mutex_lock(&(p)->lock); +#define UNLOCK(p) vcos_mutex_unlock(&(p)->lock); + + +/*****************************************************************************/ +#ifdef USE_RTOS_TIMER +typedef RTOS_TIMER_T MMAL_TIMER_T; +#else +typedef VCOS_TIMER_T MMAL_TIMER_T; +#endif + +typedef struct MMAL_CLOCK_REQUEST_T +{ + MMAL_LIST_ELEMENT_T link; /**< must be first */ + MMAL_CLOCK_VOID_FP priv; /**< client-supplied function pointer */ + MMAL_CLOCK_REQUEST_CB cb; /**< client-supplied callback to invoke */ + void *cb_data; /**< client-supplied callback data */ + int64_t media_time; /**< media-time requested by the client (microseconds) */ + int64_t media_time_adj; /**< adjusted media-time at which the request will + be serviced in microseconds (this takes + CLOCK_TARGET_OFFSET into account) */ +} MMAL_CLOCK_REQUEST_T; + +typedef struct MMAL_CLOCK_PRIVATE_T +{ + MMAL_CLOCK_T clock; /**< must be first */ + + MMAL_BOOL_T is_active; /**< TRUE -> media-time is advancing */ + + MMAL_BOOL_T scheduling; /**< TRUE -> client request scheduling is enabled */ + MMAL_BOOL_T stop_thread; + VCOS_SEMAPHORE_T event; + VCOS_THREAD_T thread; /**< processing thread for client requests */ + MMAL_TIMER_T timer; /**< used for scheduling client requests */ + + VCOS_MUTEX_T lock; /**< lock access to the request lists */ + + int32_t scale; /**< media-time scale factor (Q16 format) */ + int32_t scale_inv; /**< 1/scale (Q16 format) */ + MMAL_RATIONAL_T scale_rational; + /**< clock scale as a rational number; keep a copy since + converting from Q16 will result in precision errors */ + + int64_t average_ref_diff; /**< media-time moving average adjustment */ + int64_t media_time; /**< current local media-time in microseconds */ + uint32_t media_time_frac; /**< media-time fraction in microseconds (Q24 format) */ + int64_t wall_time; /**< current local wall-time (microseconds) */ + uint32_t rtc_at_update; /**< real-time clock value at local time update (microseconds) */ + int64_t media_time_at_timer; + /**< media-time when the timer was last set */ + + int64_t discont_expiry; /**< wall-time when discontinuity expires; 0 = no discontinuity + in effect */ + int64_t discont_start; /**< media-time at start of discontinuity + (n/a if discont_expiry = 0) */ + int64_t discont_end; /**< media-time at end of discontinuity + (n/a if discont_expiry = 0) */ + int64_t discont_threshold;/**< Threshold after which backward jumps in media time are treated + as a discontinuity (microseconds) */ + int64_t discont_duration; /**< Duration (wall-time) for which a discontinuity applies */ + + int64_t request_threshold;/**< Threshold after which frames exceeding the media-time are + dropped (microseconds) */ + MMAL_BOOL_T request_threshold_enable;/**< Enable the request threshold */ + int64_t update_threshold_lower; + /**< Time differences below this threshold are ignored */ + int64_t update_threshold_upper; + /**< Time differences above this threshold reset media time */ + + /* Client requests */ + struct + { + MMAL_LIST_T* list_free; + MMAL_LIST_T* list_pending; + MMAL_CLOCK_REQUEST_T pool[CLOCK_REQUEST_SLOTS]; + } request; + +} MMAL_CLOCK_PRIVATE_T; + + +/*****************************************************************************/ +static void mmal_clock_wake_thread(MMAL_CLOCK_PRIVATE_T *private); + +/***************************************************************************** + * Timer-specific functions + *****************************************************************************/ +/* Callback invoked when timer expires */ +#ifdef USE_RTOS_TIMER +static void mmal_clock_timer_cb(MMAL_TIMER_T *timer, void *ctx) +{ + MMAL_PARAM_UNUSED(timer); + /* Notify the worker thread */ + mmal_clock_wake_thread((MMAL_CLOCK_PRIVATE_T*)ctx); +} +#else +static void mmal_clock_timer_cb(void *ctx) +{ + /* Notify the worker thread */ + mmal_clock_wake_thread((MMAL_CLOCK_PRIVATE_T*)ctx); +} +#endif + +/* Create a timer */ +static inline MMAL_BOOL_T mmal_clock_timer_create(MMAL_TIMER_T *timer, void *ctx) +{ +#ifdef USE_RTOS_TIMER + return (rtos_timer_init(timer, mmal_clock_timer_cb, ctx) == 0); +#else + return (vcos_timer_create(timer, "mmal-clock timer", mmal_clock_timer_cb, ctx) == VCOS_SUCCESS); +#endif +} + +/* Destroy a timer */ +static inline void mmal_clock_timer_destroy(MMAL_TIMER_T *timer) +{ +#ifdef USE_RTOS_TIMER + /* Nothing to do */ +#else + vcos_timer_delete(timer); +#endif +} + +/* Set the timer. Delay is in microseconds. */ +static inline void mmal_clock_timer_set(MMAL_TIMER_T *timer, int64_t delay_us) +{ +#ifdef USE_RTOS_TIMER + rtos_timer_set(timer, (RTOS_TIMER_TIME_T)delay_us); +#else + /* VCOS timer only provides millisecond accuracy */ + vcos_timer_set(timer, (VCOS_UNSIGNED)(delay_us / 1000)); +#endif +} + +/* Stop the timer. */ +static inline void mmal_clock_timer_cancel(MMAL_TIMER_T *timer) +{ +#ifdef USE_RTOS_TIMER + rtos_timer_cancel(timer); +#else + vcos_timer_cancel(timer); +#endif +} + + +/***************************************************************************** + * Clock module private functions + *****************************************************************************/ +/* Update the internal wall-time and media-time */ +static void mmal_clock_update_local_time_locked(MMAL_CLOCK_PRIVATE_T *private) +{ + uint32_t time_now = vcos_getmicrosecs(); + uint32_t time_diff = (time_now > private->rtc_at_update) ? (time_now - private->rtc_at_update) : 0; + + private->wall_time += time_diff; + + /* For small clock scale values (i.e. slow motion), the media-time increment + * could potentially be rounded down when doing lots of updates, so also keep + * track of the fractional increment. */ + int64_t media_diff = ((int64_t)time_diff) * (int64_t)(private->scale << 8) + private->media_time_frac; + + private->media_time += media_diff >> 24; + private->media_time_frac = media_diff & ((1<<24)-1); + + private->rtc_at_update = time_now; +} + +/* Return the current local media-time */ +static int64_t mmal_clock_media_time_get_locked(MMAL_CLOCK_PRIVATE_T *private) +{ + mmal_clock_update_local_time_locked(private); + return private->media_time; +} + +/* Comparison function used for inserting a request into + * the list of pending requests when clock scale is positive. */ +static int mmal_clock_request_compare_pos(MMAL_LIST_ELEMENT_T *lhs, MMAL_LIST_ELEMENT_T *rhs) +{ + return ((MMAL_CLOCK_REQUEST_T*)lhs)->media_time_adj < ((MMAL_CLOCK_REQUEST_T*)rhs)->media_time_adj; +} + +/* Comparison function used for inserting a request into + * the list of pending requests when clock scale is negative. */ +static int mmal_clock_request_compare_neg(MMAL_LIST_ELEMENT_T *lhs, MMAL_LIST_ELEMENT_T *rhs) +{ + return ((MMAL_CLOCK_REQUEST_T*)lhs)->media_time_adj > ((MMAL_CLOCK_REQUEST_T*)rhs)->media_time_adj; +} + +/* Insert a new request into the list of pending requests */ +static MMAL_BOOL_T mmal_clock_request_insert(MMAL_CLOCK_PRIVATE_T *private, MMAL_CLOCK_REQUEST_T *request) +{ + MMAL_LIST_T *list = private->request.list_pending; + MMAL_CLOCK_REQUEST_T *pending; + + if (private->stop_thread) + return MMAL_FALSE; /* the clock is being destroyed */ + + if (list->length == 0) + { + mmal_list_push_front(list, &request->link); + return MMAL_TRUE; + } + + /* It is more likely for requests to be received in sequence, + * so try adding to the back of the list first before doing + * a more expensive list insert. */ + pending = (MMAL_CLOCK_REQUEST_T*)list->last; + if ((private->scale >= 0 && (request->media_time_adj >= pending->media_time_adj)) || + (private->scale < 0 && (request->media_time_adj <= pending->media_time_adj))) + { + mmal_list_push_back(list, &request->link); + } + else + { + mmal_list_insert(list, &request->link, + (private->scale >= 0) ? mmal_clock_request_compare_pos : mmal_clock_request_compare_neg); + } + return MMAL_TRUE; +} + +/* Flush all pending requests */ +static MMAL_STATUS_T mmal_clock_request_flush_locked(MMAL_CLOCK_PRIVATE_T *private, + int64_t media_time) +{ + MMAL_LIST_T *pending = private->request.list_pending; + MMAL_LIST_T *list_free = private->request.list_free; + MMAL_CLOCK_REQUEST_T *request; + + while ((request = (MMAL_CLOCK_REQUEST_T *)mmal_list_pop_front(pending)) != NULL) + { + /* Inform the client */ + request->cb(&private->clock, media_time, request->cb_data, request->priv); + /* Recycle request slot */ + mmal_list_push_back(list_free, &request->link); + } + + private->media_time_at_timer = 0; + + return MMAL_SUCCESS; +} + +/* Process all pending requests */ +static void mmal_clock_process_requests(MMAL_CLOCK_PRIVATE_T *private) +{ + int64_t media_time_now; + MMAL_LIST_T* free = private->request.list_free; + MMAL_LIST_T* pending = private->request.list_pending; + MMAL_CLOCK_REQUEST_T *next; + + if (pending->length == 0 || !private->is_active) + return; + + LOCK(private); + + /* Detect discontinuity */ + if (private->media_time_at_timer != 0) + { + media_time_now = mmal_clock_media_time_get_locked(private); + /* Currently only applied to forward speeds */ + if (private->scale > 0 && + media_time_now + private->discont_threshold < private->media_time_at_timer) + { + LOG_INFO("discontinuity: was=%" PRIi64 " now=%" PRIi64 " pending=%d", + private->media_time_at_timer, media_time_now, pending->length); + + /* It's likely that packets from before the discontinuity will continue to arrive for + * a short time. Ensure these are detected and the requests fired immediately. */ + private->discont_start = private->media_time_at_timer; + private->discont_end = private->discont_start + private->discont_duration; + private->discont_expiry = private->wall_time + private->discont_duration; + + /* Fire all pending requests */ + mmal_clock_request_flush_locked(private, media_time_now); + } + } + + /* Earliest request is always at the front */ + next = (MMAL_CLOCK_REQUEST_T*)mmal_list_pop_front(pending); + while (next) + { + media_time_now = mmal_clock_media_time_get_locked(private); + + if (private->discont_expiry != 0 && private->wall_time > private->discont_expiry) + private->discont_expiry = 0; + + /* Fire the request if it matches the pending discontinuity or if its requested media time + * has been reached. */ + if ((private->discont_expiry != 0 && + next->media_time_adj >= private->discont_start && + next->media_time_adj < private->discont_end) || + (private->scale > 0 && ((media_time_now + MIN_TIMER_DELAY) >= next->media_time_adj)) || + (private->scale < 0 && ((media_time_now - MIN_TIMER_DELAY) <= next->media_time_adj))) + { + LOG_TRACE("servicing request: next %"PRIi64" now %"PRIi64, next->media_time_adj, media_time_now); + /* Inform the client */ + next->cb(&private->clock, media_time_now, next->cb_data, next->priv); + /* Recycle the request slot */ + mmal_list_push_back(free, &next->link); + /* Move onto next pending request */ + next = (MMAL_CLOCK_REQUEST_T*)mmal_list_pop_front(pending); + } + else + { + /* The next request is in the future, so re-schedule the + * timer based on the current clock scale and media-time diff */ + int64_t media_time_delay = ABS_VALUE(media_time_now - next->media_time_adj); + int64_t wall_time_delay = ABS_VALUE(((int64_t)private->scale_inv * media_time_delay) >> 16); + + if (private->scale == 0) + wall_time_delay = CLOCK_WAIT_TIME; /* Clock is paused */ + + /* Put next request back into pending list */ + mmal_list_push_front(pending, &next->link); + next = NULL; + + /* Set the timer */ + private->media_time_at_timer = media_time_now; + mmal_clock_timer_set(&private->timer, wall_time_delay); + + LOG_TRACE("re-schedule timer: now %"PRIi64" delay %"PRIi64, media_time_now, wall_time_delay); + } + } + + UNLOCK(private); +} + +/* Trigger the worker thread (if present) */ +static void mmal_clock_wake_thread(MMAL_CLOCK_PRIVATE_T *private) +{ + if (private->scheduling) + vcos_semaphore_post(&private->event); +} + +/* Stop the worker thread */ +static void mmal_clock_stop_thread(MMAL_CLOCK_PRIVATE_T *private) +{ + private->stop_thread = MMAL_TRUE; + mmal_clock_wake_thread(private); + vcos_thread_join(&private->thread, NULL); +} + +/* Main processing thread */ +static void* mmal_clock_worker_thread(void *ctx) +{ + MMAL_CLOCK_PRIVATE_T *private = (MMAL_CLOCK_PRIVATE_T*)ctx; + + while (1) + { + vcos_semaphore_wait(&private->event); + + /* Either the timer has expired or a new request is pending */ + mmal_clock_timer_cancel(&private->timer); + + if (private->stop_thread) + break; + + mmal_clock_process_requests(private); + } + return NULL; +} + +/* Create scheduling resources */ +static MMAL_STATUS_T mmal_clock_create_scheduling(MMAL_CLOCK_PRIVATE_T *private) +{ + unsigned int i; + MMAL_BOOL_T timer_status = MMAL_FALSE; + VCOS_STATUS_T event_status = VCOS_EINVAL; + VCOS_UNSIGNED priority; + + timer_status = mmal_clock_timer_create(&private->timer, private); + if (!timer_status) + { + LOG_ERROR("failed to create timer %p", private); + goto error; + } + + event_status = vcos_semaphore_create(&private->event, "mmal-clock sema", 0); + if (event_status != VCOS_SUCCESS) + { + LOG_ERROR("failed to create event semaphore %d", event_status); + goto error; + } + + private->request.list_free = mmal_list_create(); + private->request.list_pending = mmal_list_create(); + if (!private->request.list_free || !private->request.list_pending) + { + LOG_ERROR("failed to create list %p %p", private->request.list_free, private->request.list_pending); + goto error; + } + + /* Populate the list of available request slots */ + for (i = 0; i < CLOCK_REQUEST_SLOTS; ++i) + mmal_list_push_back(private->request.list_free, &private->request.pool[i].link); + + if (vcos_thread_create(&private->thread, "mmal-clock thread", NULL, + mmal_clock_worker_thread, private) != VCOS_SUCCESS) + { + LOG_ERROR("failed to create worker thread"); + goto error; + } + priority = vcos_thread_get_priority(&private->thread); + vcos_thread_set_priority(&private->thread, 1 | (priority & VCOS_AFFINITY_MASK)); + + private->scheduling = MMAL_TRUE; + + return MMAL_SUCCESS; + +error: + if (event_status == VCOS_SUCCESS) vcos_semaphore_delete(&private->event); + if (timer_status) mmal_clock_timer_destroy(&private->timer); + if (private->request.list_free) mmal_list_destroy(private->request.list_free); + if (private->request.list_pending) mmal_list_destroy(private->request.list_pending); + return MMAL_ENOSPC; +} + +/* Destroy all scheduling resources */ +static void mmal_clock_destroy_scheduling(MMAL_CLOCK_PRIVATE_T *private) +{ + mmal_clock_stop_thread(private); + + mmal_clock_request_flush(&private->clock); + + mmal_list_destroy(private->request.list_free); + mmal_list_destroy(private->request.list_pending); + + vcos_semaphore_delete(&private->event); + + mmal_clock_timer_destroy(&private->timer); +} + +/* Start the media-time */ +static void mmal_clock_start(MMAL_CLOCK_T *clock) +{ + MMAL_CLOCK_PRIVATE_T *private = (MMAL_CLOCK_PRIVATE_T*)clock; + + private->is_active = MMAL_TRUE; + + mmal_clock_wake_thread(private); +} + +/* Stop the media-time */ +static void mmal_clock_stop(MMAL_CLOCK_T *clock) +{ + MMAL_CLOCK_PRIVATE_T *private = (MMAL_CLOCK_PRIVATE_T*)clock; + + private->is_active = MMAL_FALSE; + + mmal_clock_wake_thread(private); +} + +static int mmal_clock_is_paused(MMAL_CLOCK_T *clock) +{ + MMAL_CLOCK_PRIVATE_T *private = (MMAL_CLOCK_PRIVATE_T*)clock; + return private->scale == 0; +} + +/***************************************************************************** + * Clock module public functions + *****************************************************************************/ +/* Create new clock instance */ +MMAL_STATUS_T mmal_clock_create(MMAL_CLOCK_T **clock) +{ + unsigned int size = sizeof(MMAL_CLOCK_PRIVATE_T); + MMAL_RATIONAL_T scale = { 1, 1 }; + MMAL_CLOCK_PRIVATE_T *private; + + /* Sanity checking */ + if (clock == NULL) + return MMAL_EINVAL; + + private = vcos_calloc(1, size, "mmal-clock"); + if (!private) + { + LOG_ERROR("failed to allocate memory"); + return MMAL_ENOMEM; + } + + if (vcos_mutex_create(&private->lock, "mmal-clock lock") != VCOS_SUCCESS) + { + LOG_ERROR("failed to create lock mutex"); + vcos_free(private); + return MMAL_ENOSPC; + } + + /* Set the default threshold values */ + private->update_threshold_lower = CLOCK_UPDATE_THRESHOLD_LOWER; + private->update_threshold_upper = CLOCK_UPDATE_THRESHOLD_UPPER; + private->discont_threshold = CLOCK_DISCONT_THRESHOLD; + private->discont_duration = CLOCK_DISCONT_DURATION; + private->request_threshold = 0; + private->request_threshold_enable = MMAL_FALSE; + + /* Default scale = 1.0, i.e. normal playback speed */ + mmal_clock_scale_set(&private->clock, scale); + + *clock = &private->clock; + return MMAL_SUCCESS; +} + +/* Destroy a clock instance */ +MMAL_STATUS_T mmal_clock_destroy(MMAL_CLOCK_T *clock) +{ + MMAL_CLOCK_PRIVATE_T *private = (MMAL_CLOCK_PRIVATE_T*)clock; + + if (private->scheduling) + mmal_clock_destroy_scheduling(private); + + vcos_mutex_delete(&private->lock); + + vcos_free(private); + + return MMAL_SUCCESS; +} + +/* Add new client request to list of pending requests */ +MMAL_STATUS_T mmal_clock_request_add(MMAL_CLOCK_T *clock, int64_t media_time, + MMAL_CLOCK_REQUEST_CB cb, void *cb_data, MMAL_CLOCK_VOID_FP priv) +{ + MMAL_CLOCK_PRIVATE_T *private = (MMAL_CLOCK_PRIVATE_T*)clock; + MMAL_CLOCK_REQUEST_T *request; + MMAL_BOOL_T wake_thread = MMAL_FALSE; + int64_t media_time_now; + + LOG_TRACE("media time %"PRIi64, media_time); + + LOCK(private); + + media_time_now = mmal_clock_media_time_get_locked(private); + + /* Drop the request if request_threshold_enable and the frame exceeds the request threshold */ + if (private->request_threshold_enable && (media_time > (media_time_now + private->request_threshold))) + { + LOG_TRACE("dropping request: media time %"PRIi64" now %"PRIi64, media_time, media_time_now); + UNLOCK(private); + return MMAL_ECORRUPT; + } + + /* The clock module is usually only used for time-keeping, so all the + * objects needed to process client requests are not allocated by default + * and need to be created on the first client request received */ + if (!private->scheduling) + { + if (mmal_clock_create_scheduling(private) != MMAL_SUCCESS) + { + LOG_ERROR("failed to create scheduling objects"); + UNLOCK(private); + return MMAL_ENOSPC; + } + } + + request = (MMAL_CLOCK_REQUEST_T*)mmal_list_pop_front(private->request.list_free); + if (request == NULL) + { + LOG_ERROR("no more free clock request slots"); + UNLOCK(private); + return MMAL_ENOSPC; + } + + request->cb = cb; + request->cb_data = cb_data; + request->priv = priv; + request->media_time = media_time; + request->media_time_adj = media_time - (int64_t)(private->scale * CLOCK_TARGET_OFFSET >> 16); + + if (mmal_clock_request_insert(private, request)) + wake_thread = private->is_active; + + UNLOCK(private); + + /* Notify the worker thread */ + if (wake_thread) + mmal_clock_wake_thread(private); + + return MMAL_SUCCESS; +} + +/* Flush all pending requests */ +MMAL_STATUS_T mmal_clock_request_flush(MMAL_CLOCK_T *clock) +{ + MMAL_CLOCK_PRIVATE_T *private = (MMAL_CLOCK_PRIVATE_T*)clock; + + LOCK(private); + if (private->scheduling) + mmal_clock_request_flush_locked(private, MMAL_TIME_UNKNOWN); + UNLOCK(private); + + return MMAL_SUCCESS; +} + +/* Update the local media-time with the given reference */ +MMAL_STATUS_T mmal_clock_media_time_set(MMAL_CLOCK_T *clock, int64_t media_time) +{ + MMAL_CLOCK_PRIVATE_T *private = (MMAL_CLOCK_PRIVATE_T*)clock; + MMAL_BOOL_T wake_thread = MMAL_TRUE; + int64_t time_diff; + + LOCK(private); + + if (!private->is_active) + { + uint32_t time_now = vcos_getmicrosecs(); + private->wall_time = time_now; + private->media_time = media_time; + private->media_time_frac = 0; + private->rtc_at_update = time_now; + + UNLOCK(private); + return MMAL_SUCCESS; + } + + if (mmal_clock_is_paused(clock)) + { + LOG_TRACE("clock is paused; ignoring update"); + UNLOCK(private); + return MMAL_SUCCESS; + } + + /* Reset the local media-time with the given time reference */ + mmal_clock_update_local_time_locked(private); + + time_diff = private->media_time - media_time; + if (time_diff > private->update_threshold_upper || + time_diff < -private->update_threshold_upper) + { + LOG_TRACE("cur:%"PRIi64" new:%"PRIi64" diff:%"PRIi64, private->media_time, media_time, time_diff); + private->media_time = media_time; + private->average_ref_diff = 0; + } + else + { + private->average_ref_diff = ((private->average_ref_diff << 6) - private->average_ref_diff + time_diff) >> 6; + if(private->average_ref_diff > private->update_threshold_lower || + private->average_ref_diff < -private->update_threshold_lower) + { + LOG_TRACE("cur:%"PRIi64" new:%"PRIi64" ave:%"PRIi64, private->media_time, + private->media_time - private->average_ref_diff, private->average_ref_diff); + private->media_time -= private->average_ref_diff; + private->average_ref_diff = 0; + } + else + { + /* Don't update the media-time */ + wake_thread = MMAL_FALSE; + LOG_TRACE("cur:%"PRIi64" new:%"PRIi64" diff:%"PRIi64" ave:%"PRIi64" ignored", private->media_time, + media_time, private->media_time - media_time, private->average_ref_diff); + } + } + + UNLOCK(private); + + if (wake_thread) + mmal_clock_wake_thread(private); + + return MMAL_SUCCESS; +} + +/* Change the clock scale */ +MMAL_STATUS_T mmal_clock_scale_set(MMAL_CLOCK_T *clock, MMAL_RATIONAL_T scale) +{ + MMAL_CLOCK_PRIVATE_T *private = (MMAL_CLOCK_PRIVATE_T*)clock; + + LOG_TRACE("new scale %d/%d", scale.num, scale.den); + + LOCK(private); + + mmal_clock_update_local_time_locked(private); + + private->scale_rational = scale; + private->scale = mmal_rational_to_fixed_16_16(scale); + + if (private->scale) + private->scale_inv = (int32_t)((1LL << 32) / (int64_t)private->scale); + else + private->scale_inv = Q16_ONE; /* clock is paused */ + + UNLOCK(private); + + mmal_clock_wake_thread(private); + + return MMAL_SUCCESS; +} + +/* Set the clock state */ +MMAL_STATUS_T mmal_clock_active_set(MMAL_CLOCK_T *clock, MMAL_BOOL_T active) +{ + if (active) + mmal_clock_start(clock); + else + mmal_clock_stop(clock); + + return MMAL_SUCCESS; +} + +/* Get the clock's scale */ +MMAL_RATIONAL_T mmal_clock_scale_get(MMAL_CLOCK_T *clock) +{ + MMAL_CLOCK_PRIVATE_T *private = (MMAL_CLOCK_PRIVATE_T*)clock; + MMAL_RATIONAL_T scale; + + LOCK(private); + scale = private->scale_rational; + UNLOCK(private); + + return scale; +} + +/* Return the current local media-time */ +int64_t mmal_clock_media_time_get(MMAL_CLOCK_T *clock) +{ + int64_t media_time; + MMAL_CLOCK_PRIVATE_T *private = (MMAL_CLOCK_PRIVATE_T*)clock; + + LOCK(private); + media_time = mmal_clock_media_time_get_locked(private); + UNLOCK(private); + + return media_time; +} + +/* Get the clock's state */ +MMAL_BOOL_T mmal_clock_is_active(MMAL_CLOCK_T *clock) +{ + return ((MMAL_CLOCK_PRIVATE_T*)clock)->is_active; +} + +/* Get the clock's media-time update threshold values */ +MMAL_STATUS_T mmal_clock_update_threshold_get(MMAL_CLOCK_T *clock, MMAL_CLOCK_UPDATE_THRESHOLD_T *update_threshold) +{ + MMAL_CLOCK_PRIVATE_T *private = (MMAL_CLOCK_PRIVATE_T *)clock; + + LOCK(private); + update_threshold->threshold_lower = private->update_threshold_lower; + update_threshold->threshold_upper = private->update_threshold_upper; + UNLOCK(private); + + return MMAL_SUCCESS; +} + +/* Set the clock's media-time update threshold values */ +MMAL_STATUS_T mmal_clock_update_threshold_set(MMAL_CLOCK_T *clock, const MMAL_CLOCK_UPDATE_THRESHOLD_T *update_threshold) +{ + MMAL_CLOCK_PRIVATE_T *private = (MMAL_CLOCK_PRIVATE_T *)clock; + + LOG_TRACE("new clock update thresholds: upper %"PRIi64", lower %"PRIi64, + update_threshold->threshold_lower, update_threshold->threshold_upper); + + LOCK(private); + private->update_threshold_lower = update_threshold->threshold_lower; + private->update_threshold_upper = update_threshold->threshold_upper; + UNLOCK(private); + + return MMAL_SUCCESS; +} + +/* Get the clock's discontinuity threshold values */ +MMAL_STATUS_T mmal_clock_discont_threshold_get(MMAL_CLOCK_T *clock, MMAL_CLOCK_DISCONT_THRESHOLD_T *discont) +{ + MMAL_CLOCK_PRIVATE_T *private = (MMAL_CLOCK_PRIVATE_T *)clock; + + LOCK(private); + discont->threshold = private->discont_threshold; + discont->duration = private->discont_duration; + UNLOCK(private); + + return MMAL_SUCCESS; +} + +/* Set the clock's discontinuity threshold values */ +MMAL_STATUS_T mmal_clock_discont_threshold_set(MMAL_CLOCK_T *clock, const MMAL_CLOCK_DISCONT_THRESHOLD_T *discont) +{ + MMAL_CLOCK_PRIVATE_T *private = (MMAL_CLOCK_PRIVATE_T *)clock; + + LOG_TRACE("new clock discontinuity values: threshold %"PRIi64", duration %"PRIi64, + discont->threshold, discont->duration); + + LOCK(private); + private->discont_threshold = discont->threshold; + private->discont_duration = discont->duration; + UNLOCK(private); + + return MMAL_SUCCESS; +} + +/* Get the clock's request threshold values */ +MMAL_STATUS_T mmal_clock_request_threshold_get(MMAL_CLOCK_T *clock, MMAL_CLOCK_REQUEST_THRESHOLD_T *req) +{ + MMAL_CLOCK_PRIVATE_T *private = (MMAL_CLOCK_PRIVATE_T *)clock; + + LOCK(private); + req->threshold = private->request_threshold; + req->threshold_enable = private->request_threshold_enable; + UNLOCK(private); + + return MMAL_SUCCESS; +} + +/* Set the clock's request threshold values */ +MMAL_STATUS_T mmal_clock_request_threshold_set(MMAL_CLOCK_T *clock, const MMAL_CLOCK_REQUEST_THRESHOLD_T *req) +{ + MMAL_CLOCK_PRIVATE_T *private = (MMAL_CLOCK_PRIVATE_T *)clock; + + LOG_TRACE("new clock request values: threshold %"PRIi64, + req->threshold); + + LOCK(private); + private->request_threshold = req->threshold; + private->request_threshold_enable = req->threshold_enable; + UNLOCK(private); + + return MMAL_SUCCESS; +} diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/core/mmal_clock_private.h b/external_src/raspicam-0.1.3/dependencies/mmal/core/mmal_clock_private.h new file mode 100644 index 0000000..25ebc87 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/core/mmal_clock_private.h @@ -0,0 +1,204 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 MMAL_CLOCK_PRIVATE_H +#define MMAL_CLOCK_PRIVATE_H + +#include "interface/mmal/mmal.h" +#include "interface/mmal/mmal_clock.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** Handle to a clock. */ +typedef struct MMAL_CLOCK_T +{ + void *user_data; /**< Client-supplied data (not used by the clock). */ +} MMAL_CLOCK_T; + +/** Create a new instance of a clock. + * + * @param clock Returned clock + * + * @return MMAL_SUCCESS on success + */ +MMAL_STATUS_T mmal_clock_create(MMAL_CLOCK_T **clock); + +/** Destroy a previously created clock. + * + * @param clock The clock to destroy + * + * @return MMAL_SUCCESS on success + */ +MMAL_STATUS_T mmal_clock_destroy(MMAL_CLOCK_T *clock); + +/** Definition of a clock request callback. + * This is invoked when the media-time requested by the client is reached. + * + * @param clock The clock which serviced the request + * @param media_time The current media-time + * @param cb_data Client-supplied data + * @param priv Function pointer used by the framework + */ +typedef void (*MMAL_CLOCK_VOID_FP)(void); +typedef void (*MMAL_CLOCK_REQUEST_CB)(MMAL_CLOCK_T *clock, int64_t media_time, void *cb_data, MMAL_CLOCK_VOID_FP priv); + +/** Register a request with the clock. + * When the specified media-time is reached, the clock will invoke the supplied callback. + * + * @param clock The clock + * @param media_time The media-time at which the callback should be invoked (microseconds) + * @param cb Callback to invoke + * @param cb_data Client-supplied callback data + * @param priv Function pointer used by the framework + * + * @return MMAL_SUCCESS on success + */ +MMAL_STATUS_T mmal_clock_request_add(MMAL_CLOCK_T *clock, int64_t media_time, + MMAL_CLOCK_REQUEST_CB cb, void *cb_data, MMAL_CLOCK_VOID_FP priv); + +/** Remove all previously registered clock requests. + * + * @param clock The clock + * + * @return MMAL_SUCCESS on success + */ +MMAL_STATUS_T mmal_clock_request_flush(MMAL_CLOCK_T *clock); + +/** Update the clock's media-time. + * + * @param clock The clock to update + * @param media_time New media-time to be applied (microseconds) + * + * @return MMAL_SUCCESS on success + */ +MMAL_STATUS_T mmal_clock_media_time_set(MMAL_CLOCK_T *clock, int64_t media_time); + +/** Set the clock's scale. + * + * @param clock The clock + * @param scale Scale factor + * + * @return MMAL_SUCCESS on success + */ +MMAL_STATUS_T mmal_clock_scale_set(MMAL_CLOCK_T *clock, MMAL_RATIONAL_T scale); + +/** Set the clock state. + * + * @param clock The clock + * @param active TRUE -> clock is active and media-time is advancing + * + * @return MMAL_SUCCESS on success + */ +MMAL_STATUS_T mmal_clock_active_set(MMAL_CLOCK_T *clock, MMAL_BOOL_T active); + +/** Get the clock's scale. + * + * @param clock The clock + * + * @return Current clock scale + */ +MMAL_RATIONAL_T mmal_clock_scale_get(MMAL_CLOCK_T *clock); + +/** Get the clock's current media-time. + * This takes the clock scale and media-time offset into account. + * + * @param clock The clock to query + * + * @return Current media-time in microseconds + */ +int64_t mmal_clock_media_time_get(MMAL_CLOCK_T *clock); + +/** Get the clock's state. + * + * @param clock The clock to query + * + * @return TRUE if clock is running (i.e. local media-time is advancing) + */ +MMAL_BOOL_T mmal_clock_is_active(MMAL_CLOCK_T *clock); + +/** Get the clock's media-time update threshold values. + * + * @param clock The clock + * @param update_threshold Pointer to clock update threshold values to fill + * + * @return MMAL_SUCCESS on success + */ +MMAL_STATUS_T mmal_clock_update_threshold_get(MMAL_CLOCK_T *clock, MMAL_CLOCK_UPDATE_THRESHOLD_T *update_threshold); + +/** Set the clock's media-time update threshold values. + * + * @param clock The clock + * @param update_threshold Pointer to new clock update threshold values + * + * @return MMAL_SUCCESS on success + */ +MMAL_STATUS_T mmal_clock_update_threshold_set(MMAL_CLOCK_T *clock, const MMAL_CLOCK_UPDATE_THRESHOLD_T *update_threshold); + +/** Get the clock's discontinuity threshold values. + * + * @param clock The clock + * @param discont Pointer to clock discontinuity threshold values to fill + * + * @return MMAL_SUCCESS on success + */ +MMAL_STATUS_T mmal_clock_discont_threshold_get(MMAL_CLOCK_T *clock, MMAL_CLOCK_DISCONT_THRESHOLD_T *discont); + +/** Set the clock's discontinuity threshold values. + * + * @param clock The clock + * @param discont Pointer to new clock discontinuity threshold values + * + * @return MMAL_SUCCESS on success + */ +MMAL_STATUS_T mmal_clock_discont_threshold_set(MMAL_CLOCK_T *clock, const MMAL_CLOCK_DISCONT_THRESHOLD_T *discont); + +/** Get the clock's request threshold values. + * + * @param clock The clock + * @param future Pointer to clock request threshold values to fill + * + * @return MMAL_SUCCESS on success + */ +MMAL_STATUS_T mmal_clock_request_threshold_get(MMAL_CLOCK_T *clock, MMAL_CLOCK_REQUEST_THRESHOLD_T *req); + +/** Set the clock's request threshold values. + * + * @param clock The clock + * @param discont Pointer to new clock request threshold values + * + * @return MMAL_SUCCESS on success + */ +MMAL_STATUS_T mmal_clock_request_threshold_set(MMAL_CLOCK_T *clock, const MMAL_CLOCK_REQUEST_THRESHOLD_T *req); + +#ifdef __cplusplus +} +#endif + +#endif /* MMAL_CLOCK_PRIVATE_H */ diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/core/mmal_component.c b/external_src/raspicam-0.1.3/dependencies/mmal/core/mmal_component.c new file mode 100644 index 0000000..c621ca8 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/core/mmal_component.c @@ -0,0 +1,780 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 "mmal.h" +#include "core/mmal_component_private.h" +#include "core/mmal_port_private.h" +#include "core/mmal_core_private.h" +#include "mmal_logging.h" + +/* Minimum number of buffers that will be available on the control port */ +#define MMAL_CONTROL_PORT_BUFFERS_MIN 4 + +/** Definition of the core private context. */ +typedef struct +{ + MMAL_COMPONENT_PRIVATE_T private; + + /** Action registered by component and run when buffers are received by any of the ports */ + void (*pf_action)(MMAL_COMPONENT_T *component); + + /** Action thread */ + VCOS_THREAD_T action_thread; + VCOS_EVENT_T action_event; + VCOS_MUTEX_T action_mutex; + MMAL_BOOL_T action_quit; + + VCOS_MUTEX_T lock; /**< Used to lock access to the component */ + MMAL_BOOL_T destruction_pending; + +} MMAL_COMPONENT_CORE_PRIVATE_T; + +/*****************************************************************************/ +static void mmal_core_init(void); +static void mmal_core_deinit(void); + +static MMAL_STATUS_T mmal_component_supplier_create(const char *name, MMAL_COMPONENT_T *component); +static void mmal_component_init_control_port(MMAL_PORT_T *port); + +static MMAL_STATUS_T mmal_component_destroy_internal(MMAL_COMPONENT_T *component); +static MMAL_STATUS_T mmal_component_release_internal(MMAL_COMPONENT_T *component); + +/*****************************************************************************/ +static VCOS_MUTEX_T mmal_core_lock; +/** Used to generate a unique id for each MMAL component in this context. */ +static unsigned int mmal_core_instance_count; +static unsigned int mmal_core_refcount; +/*****************************************************************************/ + +/** Create an instance of a component */ +static MMAL_STATUS_T mmal_component_create_core(const char *name, + MMAL_STATUS_T (*constructor)(const char *name, MMAL_COMPONENT_T *), + struct MMAL_COMPONENT_MODULE_T *constructor_private, + MMAL_COMPONENT_T **component) +{ + MMAL_COMPONENT_CORE_PRIVATE_T *private; + MMAL_STATUS_T status = MMAL_ENOMEM; + unsigned int size = sizeof(MMAL_COMPONENT_T) + sizeof(MMAL_COMPONENT_CORE_PRIVATE_T); + unsigned int i, name_length = strlen(name) + 1; + unsigned int port_index; + char *component_name; + + if(!component) + return MMAL_EINVAL; + + mmal_core_init(); + + *component = vcos_calloc(1, size + name_length, "mmal component"); + if(!*component) + return MMAL_ENOMEM; + + private = (MMAL_COMPONENT_CORE_PRIVATE_T *)&(*component)[1]; + (*component)->priv = (MMAL_COMPONENT_PRIVATE_T *)private; + (*component)->name = component_name= (char *)&((MMAL_COMPONENT_CORE_PRIVATE_T *)(*component)->priv)[1]; + memcpy(component_name, name, name_length); + /* coverity[missing_lock] Component and mutex have just been created. No need to lock yet */ + (*component)->priv->refcount = 1; + (*component)->priv->priority = VCOS_THREAD_PRI_NORMAL; + + if(vcos_mutex_create(&private->lock, "mmal component lock") != VCOS_SUCCESS) + { + vcos_free(*component); + return MMAL_ENOMEM; + } + + vcos_mutex_lock(&mmal_core_lock); + (*component)->id=mmal_core_instance_count++; + vcos_mutex_unlock(&mmal_core_lock); + + /* Create the control port */ + (*component)->control = mmal_port_alloc(*component, MMAL_PORT_TYPE_CONTROL, 0); + if(!(*component)->control) + goto error; + mmal_component_init_control_port((*component)->control); + + /* Create the actual component */ + (*component)->priv->module = constructor_private; + if (!constructor) + constructor = mmal_component_supplier_create; + status = constructor(name, *component); + if (status != MMAL_SUCCESS) + { + if (status == MMAL_ENOSYS) + LOG_ERROR("could not find component '%s'", name); + else + LOG_ERROR("could not create component '%s' (%i)", name, status); + goto error; + } + + /* Make sure we have enough space for at least a MMAL_EVENT_FORMAT_CHANGED */ + if ((*component)->control->buffer_size_min < + sizeof(MMAL_ES_FORMAT_T) + sizeof(MMAL_ES_SPECIFIC_FORMAT_T) + sizeof(MMAL_EVENT_FORMAT_CHANGED_T)) + (*component)->control->buffer_size_min = sizeof(MMAL_ES_FORMAT_T) + + sizeof(MMAL_ES_SPECIFIC_FORMAT_T) + sizeof(MMAL_EVENT_FORMAT_CHANGED_T); + /* Make sure we have enough events */ + if ((*component)->control->buffer_num_min < MMAL_CONTROL_PORT_BUFFERS_MIN) + (*component)->control->buffer_num_min = MMAL_CONTROL_PORT_BUFFERS_MIN; + + /* Create the event pool */ + (*component)->priv->event_pool = mmal_pool_create((*component)->control->buffer_num_min, + (*component)->control->buffer_size_min); + if (!(*component)->priv->event_pool) + { + status = MMAL_ENOMEM; + LOG_ERROR("could not create event pool (%d, %d)", (*component)->control->buffer_num_min, + (*component)->control->buffer_size_min); + goto error; + } + + /* Build the list of all the ports */ + (*component)->port_num = (*component)->input_num + (*component)->output_num + (*component)->clock_num + 1; + (*component)->port = vcos_malloc((*component)->port_num * sizeof(MMAL_PORT_T *), "mmal ports"); + if (!(*component)->port) + { + status = MMAL_ENOMEM; + LOG_ERROR("could not create list of ports"); + goto error; + } + port_index = 0; + (*component)->port[port_index++] = (*component)->control; + for (i = 0; i < (*component)->input_num; i++) + (*component)->port[port_index++] = (*component)->input[i]; + for (i = 0; i < (*component)->output_num; i++) + (*component)->port[port_index++] = (*component)->output[i]; + for (i = 0; i < (*component)->clock_num; i++) + (*component)->port[port_index++] = (*component)->clock[i]; + for (i = 0; i < (*component)->port_num; i++) + (*component)->port[i]->index_all = i; + + LOG_INFO("created '%s' %d %p", name, (*component)->id, *component); + + /* Make sure the port types, indexes and buffer sizes are set correctly */ + (*component)->control->type = MMAL_PORT_TYPE_CONTROL; + (*component)->control->index = 0; + for (i = 0; i < (*component)->input_num; i++) + { + MMAL_PORT_T *port = (*component)->input[i]; + port->type = MMAL_PORT_TYPE_INPUT; + port->index = i; + } + for (i = 0; i < (*component)->output_num; i++) + { + MMAL_PORT_T *port = (*component)->output[i]; + port->type = MMAL_PORT_TYPE_OUTPUT; + port->index = i; + } + for (i = 0; i < (*component)->clock_num; i++) + { + MMAL_PORT_T *port = (*component)->clock[i]; + port->type = MMAL_PORT_TYPE_CLOCK; + port->index = i; + } + for (i = 0; i < (*component)->port_num; i++) + { + MMAL_PORT_T *port = (*component)->port[i]; + if (port->buffer_size < port->buffer_size_min) + port->buffer_size = port->buffer_size_min; + if (port->buffer_num < port->buffer_num_min) + port->buffer_num = port->buffer_num_min; + } + + return MMAL_SUCCESS; + + error: + mmal_component_destroy_internal(*component); + *component = 0; + return status; +} + +/** Create an instance of a component */ +MMAL_STATUS_T mmal_component_create(const char *name, + MMAL_COMPONENT_T **component) +{ + LOG_TRACE("%s", name); + return mmal_component_create_core(name, 0, 0, component); +} + +/** Create an instance of a component */ +MMAL_STATUS_T mmal_component_create_with_constructor(const char *name, + MMAL_STATUS_T (*constructor)(const char *name, MMAL_COMPONENT_T *), + struct MMAL_COMPONENT_MODULE_T *constructor_private, + MMAL_COMPONENT_T **component) +{ + LOG_TRACE("%s", name); + return mmal_component_create_core(name, constructor, constructor_private, component); +} + +/** Destroy a previously created component */ +static MMAL_STATUS_T mmal_component_destroy_internal(MMAL_COMPONENT_T *component) +{ + MMAL_COMPONENT_CORE_PRIVATE_T *private = (MMAL_COMPONENT_CORE_PRIVATE_T *)component->priv; + MMAL_STATUS_T status; + + LOG_TRACE("%s %d", component->name, component->id); + + mmal_component_action_deregister(component); + + /* Should pf_destroy be allowed to fail ? + * If so, what do we do if it fails ? + */ + if (component->priv->pf_destroy) + { + status = component->priv->pf_destroy(component); + if(!vcos_verify(status == MMAL_SUCCESS)) + return status; + } + + if (component->priv->event_pool) + mmal_pool_destroy(component->priv->event_pool); + + if (component->control) + mmal_port_free(component->control); + + if (component->port) + vcos_free(component->port); + + vcos_mutex_delete(&private->lock); + vcos_free(component); + mmal_core_deinit(); + return MMAL_SUCCESS; +} + +/** Release a reference to a component */ +static MMAL_STATUS_T mmal_component_release_internal(MMAL_COMPONENT_T *component) +{ + MMAL_COMPONENT_CORE_PRIVATE_T *private = (MMAL_COMPONENT_CORE_PRIVATE_T *)component->priv; + unsigned int i; + + if (!vcos_verify(component->priv->refcount > 0)) + return MMAL_EINVAL; + + vcos_mutex_lock(&private->lock); + if (--component->priv->refcount) + { + vcos_mutex_unlock(&private->lock); + return MMAL_SUCCESS; + } + private->destruction_pending = 1; + vcos_mutex_unlock(&private->lock); + + LOG_TRACE("%s %d preparing for destruction", component->name, component->id); + + /* Make sure the ports are all disabled */ + for(i = 0; i < component->input_num; i++) + if(component->input[i]->is_enabled) + mmal_port_disable(component->input[i]); + for(i = 0; i < component->output_num; i++) + if(component->output[i]->is_enabled) + mmal_port_disable(component->output[i]); + for(i = 0; i < component->clock_num; i++) + if(component->clock[i]->is_enabled) + mmal_port_disable(component->clock[i]); + if(component->control->is_enabled) + mmal_port_disable(component->control); + + /* Make sure all the ports are disconnected. This is necessary to prevent + * connected ports from referencing destroyed components */ + for(i = 0; i < component->input_num; i++) + mmal_port_disconnect(component->input[i]); + for(i = 0; i < component->output_num; i++) + mmal_port_disconnect(component->output[i]); + for(i = 0; i < component->clock_num; i++) + mmal_port_disconnect(component->clock[i]); + + /* If there is any reference pending on the ports we will delay the actual destruction */ + vcos_mutex_lock(&private->lock); + if (component->priv->refcount_ports) + { + private->destruction_pending = 0; + vcos_mutex_unlock(&private->lock); + LOG_TRACE("%s %d delaying destruction", component->name, component->id); + return MMAL_SUCCESS; + } + vcos_mutex_unlock(&private->lock); + + return mmal_component_destroy_internal(component); +} + +/** Destroy a component */ +MMAL_STATUS_T mmal_component_destroy(MMAL_COMPONENT_T *component) +{ + if(!component) + return MMAL_EINVAL; + + LOG_TRACE("%s %d", component->name, component->id); + + return mmal_component_release_internal(component); +} + +/** Acquire a reference to a component */ +void mmal_component_acquire(MMAL_COMPONENT_T *component) +{ + MMAL_COMPONENT_CORE_PRIVATE_T *private = (MMAL_COMPONENT_CORE_PRIVATE_T *)component->priv; + + LOG_TRACE("component %s(%d), refcount %i", component->name, component->id, + component->priv->refcount); + + vcos_mutex_lock(&private->lock); + component->priv->refcount++; + vcos_mutex_unlock(&private->lock); +} + +/** Release a reference to a component */ +MMAL_STATUS_T mmal_component_release(MMAL_COMPONENT_T *component) +{ + if(!component) + return MMAL_EINVAL; + + LOG_TRACE("component %s(%d), refcount %i", component->name, component->id, + component->priv->refcount); + + return mmal_component_release_internal(component); +} + +/** Enable processing on a component */ +MMAL_STATUS_T mmal_component_enable(MMAL_COMPONENT_T *component) +{ + MMAL_COMPONENT_CORE_PRIVATE_T *private; + MMAL_STATUS_T status = MMAL_ENOSYS; + unsigned int i; + + if(!component) + return MMAL_EINVAL; + + private = (MMAL_COMPONENT_CORE_PRIVATE_T *)component->priv; + + LOG_TRACE("%s %d", component->name, component->id); + + vcos_mutex_lock(&private->lock); + + /* Check we have anything to do */ + if (component->is_enabled) + { + vcos_mutex_unlock(&private->lock); + return MMAL_SUCCESS; + } + + if (component->priv->pf_enable) + status = component->priv->pf_enable(component); + + /* If the component does not support enable/disable, we handle that + * in the core itself */ + if (status == MMAL_ENOSYS) + { + status = MMAL_SUCCESS; + + /* Resume all input / output ports */ + for (i = 0; status == MMAL_SUCCESS && i < component->input_num; i++) + status = mmal_port_pause(component->input[i], MMAL_FALSE); + for (i = 0; status == MMAL_SUCCESS && i < component->output_num; i++) + status = mmal_port_pause(component->output[i], MMAL_FALSE); + } + + if (status == MMAL_SUCCESS) + component->is_enabled = 1; + + vcos_mutex_unlock(&private->lock); + + return status; +} + +/** Disable processing on a component */ +MMAL_STATUS_T mmal_component_disable(MMAL_COMPONENT_T *component) +{ + MMAL_COMPONENT_CORE_PRIVATE_T *private; + MMAL_STATUS_T status = MMAL_ENOSYS; + unsigned int i; + + if (!component) + return MMAL_EINVAL; + + private = (MMAL_COMPONENT_CORE_PRIVATE_T *)component->priv; + + LOG_TRACE("%s %d", component->name, component->id); + + vcos_mutex_lock(&private->lock); + + /* Check we have anything to do */ + if (!component->is_enabled) + { + vcos_mutex_unlock(&private->lock); + return MMAL_SUCCESS; + } + + if (component->priv->pf_disable) + status = component->priv->pf_disable(component); + + /* If the component does not support enable/disable, we handle that + * in the core itself */ + if (status == MMAL_ENOSYS) + { + status = MMAL_SUCCESS; + + /* Pause all input / output ports */ + for (i = 0; status == MMAL_SUCCESS && i < component->input_num; i++) + status = mmal_port_pause(component->input[i], MMAL_TRUE); + for (i = 0; status == MMAL_SUCCESS && i < component->output_num; i++) + status = mmal_port_pause(component->output[i], MMAL_TRUE); + } + + if (status == MMAL_SUCCESS) + component->is_enabled = 0; + + vcos_mutex_unlock(&private->lock); + + return status; +} + +static MMAL_STATUS_T mmal_component_enable_control_port(MMAL_PORT_T *port, MMAL_PORT_BH_CB_T cb) +{ + (void)port; + (void)cb; + return MMAL_SUCCESS; +} + +static MMAL_STATUS_T mmal_component_disable_control_port(MMAL_PORT_T *port) +{ + (void)port; + return MMAL_SUCCESS; +} + +MMAL_STATUS_T mmal_component_parameter_set(MMAL_PORT_T *control_port, + const MMAL_PARAMETER_HEADER_T *param) +{ + (void)control_port; + (void)param; + /* No generic component control parameters */ + LOG_ERROR("parameter id 0x%08x not supported", param->id); + return MMAL_ENOSYS; +} + +MMAL_STATUS_T mmal_component_parameter_get(MMAL_PORT_T *control_port, + MMAL_PARAMETER_HEADER_T *param) +{ + (void)control_port; + (void)param; + /* No generic component control parameters */ + LOG_ERROR("parameter id 0x%08x not supported", param->id); + return MMAL_ENOSYS; +} + +static void mmal_component_init_control_port(MMAL_PORT_T *port) +{ + port->format->type = MMAL_ES_TYPE_CONTROL; + port->buffer_num_min = MMAL_CONTROL_PORT_BUFFERS_MIN; + port->buffer_num = port->buffer_num_min; + port->buffer_size_min = sizeof(MMAL_ES_FORMAT_T) + sizeof(MMAL_ES_SPECIFIC_FORMAT_T); + port->buffer_size = port->buffer_size_min; + + /* Default to generic handling */ + port->priv->pf_enable = mmal_component_enable_control_port; + port->priv->pf_disable = mmal_component_disable_control_port; + port->priv->pf_parameter_set = mmal_component_parameter_set; + port->priv->pf_parameter_get = mmal_component_parameter_get; + /* No pf_set_format - format of control port cannot be changed */ + /* No pf_send - buffers cannot be sent to control port */ +} + +/** Acquire a reference on a port */ +void mmal_port_acquire(MMAL_PORT_T *port) +{ + MMAL_COMPONENT_T *component = port->component; + MMAL_COMPONENT_CORE_PRIVATE_T *private = (MMAL_COMPONENT_CORE_PRIVATE_T *)component->priv; + + LOG_TRACE("port %s(%p), refcount %i", port->name, port, + component->priv->refcount_ports); + + vcos_mutex_lock(&private->lock); + component->priv->refcount_ports++; + vcos_mutex_unlock(&private->lock); +} + +/** Release a reference on a port */ +MMAL_STATUS_T mmal_port_release(MMAL_PORT_T *port) +{ + MMAL_COMPONENT_T *component = port->component; + MMAL_COMPONENT_CORE_PRIVATE_T *private = (MMAL_COMPONENT_CORE_PRIVATE_T *)component->priv; + + LOG_TRACE("port %s(%p), refcount %i", port->name, port, + component->priv->refcount_ports); + + /* Sanity check the refcount */ + if (!vcos_verify(component->priv->refcount_ports > 0)) + return MMAL_EINVAL; + + vcos_mutex_lock(&private->lock); + if (--component->priv->refcount_ports || + component->priv->refcount || private->destruction_pending) + { + vcos_mutex_unlock(&private->lock); + return MMAL_SUCCESS; + } + vcos_mutex_unlock(&private->lock); + + return mmal_component_destroy_internal(component); +} + +/***************************************************************************** + * Actions support + *****************************************************************************/ + +/** Registers an action with the core */ +static void *mmal_component_action_thread_func(void *arg) +{ + MMAL_COMPONENT_T *component = (MMAL_COMPONENT_T *)arg; + MMAL_COMPONENT_CORE_PRIVATE_T *private = (MMAL_COMPONENT_CORE_PRIVATE_T *)component->priv; + VCOS_STATUS_T status; + + while (1) + { + status = vcos_event_wait(&private->action_event); + + if (status == VCOS_EAGAIN) + continue; + if (private->action_quit) + break; + if (!vcos_verify(status == VCOS_SUCCESS)) + break; + + vcos_mutex_lock(&private->action_mutex); + private->pf_action(component); + vcos_mutex_unlock(&private->action_mutex); + } + return 0; +} + +/** Registers an action with the core */ +MMAL_STATUS_T mmal_component_action_register(MMAL_COMPONENT_T *component, + void (*pf_action)(MMAL_COMPONENT_T *) ) +{ + MMAL_COMPONENT_CORE_PRIVATE_T *private = (MMAL_COMPONENT_CORE_PRIVATE_T *)component->priv; + VCOS_THREAD_ATTR_T attrs; + VCOS_STATUS_T status; + + if (private->pf_action) + return MMAL_EINVAL; + + status = vcos_event_create(&private->action_event, component->name); + if (status != VCOS_SUCCESS) + return MMAL_ENOMEM; + + status = vcos_mutex_create(&private->action_mutex, component->name); + if (status != VCOS_SUCCESS) + { + vcos_event_delete(&private->action_event); + return MMAL_ENOMEM; + } + + vcos_thread_attr_init(&attrs); + vcos_thread_attr_setpriority(&attrs, + private->private.priority); + status = vcos_thread_create(&private->action_thread, component->name, &attrs, + mmal_component_action_thread_func, component); + if (status != VCOS_SUCCESS) + { + vcos_mutex_delete(&private->action_mutex); + vcos_event_delete(&private->action_event); + return MMAL_ENOMEM; + } + + private->pf_action = pf_action; + return MMAL_SUCCESS; +} + +/** De-registers the current action with the core */ +MMAL_STATUS_T mmal_component_action_deregister(MMAL_COMPONENT_T *component) +{ + MMAL_COMPONENT_CORE_PRIVATE_T *private = (MMAL_COMPONENT_CORE_PRIVATE_T *)component->priv; + + if (!private->pf_action) + return MMAL_EINVAL; + + private->action_quit = 1; + vcos_event_signal(&private->action_event); + vcos_thread_join(&private->action_thread, NULL); + vcos_event_delete(&private->action_event); + vcos_mutex_delete(&private->action_mutex); + private->pf_action = NULL; + private->action_quit = 0; + return MMAL_SUCCESS; +} + +/** Triggers a registered action */ +MMAL_STATUS_T mmal_component_action_trigger(MMAL_COMPONENT_T *component) +{ + MMAL_COMPONENT_CORE_PRIVATE_T *private = (MMAL_COMPONENT_CORE_PRIVATE_T *)component->priv; + + if (!private->pf_action) + return MMAL_EINVAL; + + vcos_event_signal(&private->action_event); + return MMAL_SUCCESS; +} + +/** Lock an action to prevent it from running */ +MMAL_STATUS_T mmal_component_action_lock(MMAL_COMPONENT_T *component) +{ + MMAL_COMPONENT_CORE_PRIVATE_T *private = (MMAL_COMPONENT_CORE_PRIVATE_T *)component->priv; + + if (!private->pf_action) + return MMAL_EINVAL; + + vcos_mutex_lock(&private->action_mutex); + return MMAL_SUCCESS; +} + +/** Unlock an action to allow it to run again */ +MMAL_STATUS_T mmal_component_action_unlock(MMAL_COMPONENT_T *component) +{ + MMAL_COMPONENT_CORE_PRIVATE_T *private = (MMAL_COMPONENT_CORE_PRIVATE_T *)component->priv; + + if (!private->pf_action) + return MMAL_EINVAL; + + vcos_mutex_unlock(&private->action_mutex); + return MMAL_SUCCESS; +} + +/***************************************************************************** + * Initialisation / Deinitialisation of the MMAL core + *****************************************************************************/ +static void mmal_core_init_once(void) +{ + vcos_mutex_create(&mmal_core_lock, VCOS_FUNCTION); +} + +static void mmal_core_init(void) +{ + static VCOS_ONCE_T once = VCOS_ONCE_INIT; + vcos_init(); + vcos_once(&once, mmal_core_init_once); + + vcos_mutex_lock(&mmal_core_lock); + if (mmal_core_refcount++) + { + vcos_mutex_unlock(&mmal_core_lock); + return; + } + + mmal_logging_init(); + vcos_mutex_unlock(&mmal_core_lock); +} + +static void mmal_core_deinit(void) +{ + vcos_mutex_lock(&mmal_core_lock); + if (!mmal_core_refcount || --mmal_core_refcount) + { + vcos_mutex_unlock(&mmal_core_lock); + return; + } + + mmal_logging_deinit(); + vcos_mutex_unlock(&mmal_core_lock); + vcos_deinit(); +} + +/***************************************************************************** + * Supplier support + *****************************************************************************/ + +/** a component supplier gets passed a string and returns a + * component (if it can) based on that string. + */ + +#define SUPPLIER_PREFIX_LEN 32 +typedef struct MMAL_COMPONENT_SUPPLIER_T +{ + struct MMAL_COMPONENT_SUPPLIER_T *next; + MMAL_COMPONENT_SUPPLIER_FUNCTION_T create; + char prefix[SUPPLIER_PREFIX_LEN]; +} MMAL_COMPONENT_SUPPLIER_T; + +/** List of component suppliers. + * + * Does not need to be thread-safe if we assume that suppliers + * can never be removed. + */ +static MMAL_COMPONENT_SUPPLIER_T *suppliers; + +/** Create an instance of a component */ +static MMAL_STATUS_T mmal_component_supplier_create(const char *name, MMAL_COMPONENT_T *component) +{ + MMAL_COMPONENT_SUPPLIER_T *supplier = suppliers; + MMAL_STATUS_T status = MMAL_ENOSYS; + const char *dot = strchr(name, '.'); + size_t dot_size = dot ? dot - name : (int)strlen(name); + + /* walk list of suppliers to see if any can create this component */ + while (supplier) + { + if (strlen(supplier->prefix) == dot_size && !memcmp(supplier->prefix, name, dot_size)) + { + status = supplier->create(name, component); + if (status == MMAL_SUCCESS) + break; + } + supplier = supplier->next; + } + return status; +} + +void mmal_component_supplier_register(const char *prefix, + MMAL_COMPONENT_SUPPLIER_FUNCTION_T create_fn) +{ + MMAL_COMPONENT_SUPPLIER_T *supplier = vcos_calloc(1,sizeof(*supplier),NULL); + + LOG_TRACE("prefix %s fn %p", (prefix ? prefix : "NULL"), create_fn); + + if (vcos_verify(supplier)) + { + supplier->create = create_fn; + strncpy(supplier->prefix, prefix, SUPPLIER_PREFIX_LEN); + supplier->prefix[SUPPLIER_PREFIX_LEN-1] = '\0'; + + supplier->next = suppliers; + suppliers = supplier; + } + else + { + LOG_ERROR("no memory for supplier registry entry"); + } +} + +MMAL_DESTRUCTOR(mmal_component_supplier_destructor); +void mmal_component_supplier_destructor(void) +{ + MMAL_COMPONENT_SUPPLIER_T *supplier = suppliers; + + /* walk list of suppliers and free associated memory */ + while (supplier) + { + MMAL_COMPONENT_SUPPLIER_T *current = supplier; + supplier = supplier->next; + vcos_free(current); + } +} diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/core/mmal_component_private.h b/external_src/raspicam-0.1.3/dependencies/mmal/core/mmal_component_private.h new file mode 100644 index 0000000..26c7a7e --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/core/mmal_component_private.h @@ -0,0 +1,169 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 MMAL_COMPONENT_PRIVATE_H +#define MMAL_COMPONENT_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define MMAL_VIDEO_DECODE "video_decode" +#define MMAL_VIDEO_ENCODE "video_encode" +#define MMAL_VIDEO_RENDER "video_render" +#define MMAL_AUDIO_DECODE "audio_decode" +#define MMAL_AUDIO_ENCODE "audio_encode" +#define MMAL_AUDIO_RENDER "audio_render" +#define MMAL_CAMERA "camera" + +#if defined(__GNUC__) && (__GNUC__ > 2) +# define MMAL_CONSTRUCTOR(func) void __attribute__((constructor,used)) func(void) +# define MMAL_DESTRUCTOR(func) void __attribute__((destructor,used)) func(void) +#else +# define MMAL_CONSTRUCTOR(func) void func(void) +# define MMAL_DESTRUCTOR(func) void func(void) +#endif + +#include "mmal.h" +#include "mmal_component.h" + +/** Definition of a component. */ +struct MMAL_COMPONENT_PRIVATE_T +{ + /** Pointer to the private data of the component module in use */ + struct MMAL_COMPONENT_MODULE_T *module; + + MMAL_STATUS_T (*pf_enable)(MMAL_COMPONENT_T *component); + MMAL_STATUS_T (*pf_disable)(MMAL_COMPONENT_T *component); + MMAL_STATUS_T (*pf_destroy)(MMAL_COMPONENT_T *component); + + /** Pool of event buffer headers, for sending events from component to client. */ + MMAL_POOL_T *event_pool; + + /** Reference counting of the component */ + int refcount; + /** Reference counting of the ports. Component won't be destroyed until this + * goes to 0 */ + int refcount_ports; + + /** Priority associated with the 'action thread' for this component, when + * such action thread is applicable. */ + int priority; +}; + +/** Set a generic component control parameter. + * + * @param control_port control port of component on which to set the parameter. + * @param param parameter to be set. + * @return MMAL_SUCCESS or another status on error. + */ +MMAL_STATUS_T mmal_component_parameter_set(MMAL_PORT_T *control_port, + const MMAL_PARAMETER_HEADER_T *param); + +/** Get a generic component control parameter. + * + * @param contorl_port control port of component from which to get the parameter. + * @param param parameter to be retrieved. + * @return MMAL_SUCCESS or another status on error. + */ +MMAL_STATUS_T mmal_component_parameter_get(MMAL_PORT_T *control_port, + MMAL_PARAMETER_HEADER_T *param); + +/** Registers an action with the core. + * The MMAL core allows components to register an action which will be run + * from a separate thread context when the action is explicitly triggered by + * the component. + * + * @param component component registering the action. + * @param action action to register. + * @return MMAL_SUCCESS or another status on error. + */ +MMAL_STATUS_T mmal_component_action_register(MMAL_COMPONENT_T *component, + void (*pf_action)(MMAL_COMPONENT_T *)); + +/** De-registers the current action registered with the core. + * + * @param component component de-registering the action. + * @return MMAL_SUCCESS or another status on error. + */ +MMAL_STATUS_T mmal_component_action_deregister(MMAL_COMPONENT_T *component); + +/** Triggers a registered action. + * Explicitly triggers an action registered by a component. + * + * @param component component on which to trigger the action. + * @return MMAL_SUCCESS or another status on error. + */ +MMAL_STATUS_T mmal_component_action_trigger(MMAL_COMPONENT_T *component); + +/** Lock an action to prevent it from running. + * Allows a component to make sure no action is running while the lock is taken. + * + * @param component component. + * @return MMAL_SUCCESS or another status on error. + */ +MMAL_STATUS_T mmal_component_action_lock(MMAL_COMPONENT_T *component); + +/** Unlock an action to allow it to run again. + * + * @param component component. + * @return MMAL_SUCCESS or another status on error. + */ +MMAL_STATUS_T mmal_component_action_unlock(MMAL_COMPONENT_T *component); + +/** Prototype used by components to register themselves to the supplier. */ +typedef MMAL_STATUS_T (*MMAL_COMPONENT_SUPPLIER_FUNCTION_T)(const char *name, + MMAL_COMPONENT_T *component); + +/** Create an instance of a component given a constructor for the component. + * This allows the creation of client-side components which haven't been registered with the core. + * See \ref mmal_component_create for the public interface used to create components. + * + * @param name name assigned to the component by the client + * @param constructor constructor function for the component + * @param constructor_private private data for the constructor + * @param component returned component + * @return MMAL_SUCCESS on success + */ +MMAL_STATUS_T mmal_component_create_with_constructor(const char *name, + MMAL_STATUS_T (*constructor)(const char *name, MMAL_COMPONENT_T *), + struct MMAL_COMPONENT_MODULE_T *constructor_private, + MMAL_COMPONENT_T **component); + +/** Register a component with the mmal component supplier. + * + * @param prefix prefix for this supplier, e.g. "VC" + * @param create_fn function which will instantiate a component given a name. + */ +void mmal_component_supplier_register(const char *prefix, + MMAL_COMPONENT_SUPPLIER_FUNCTION_T create_fn); + +#ifdef __cplusplus +} +#endif + +#endif /* MMAL_COMPONENT_PRIVATE_H */ diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/core/mmal_core_private.h b/external_src/raspicam-0.1.3/dependencies/mmal/core/mmal_core_private.h new file mode 100644 index 0000000..8dc6cba --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/core/mmal_core_private.h @@ -0,0 +1,40 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 MMAL_CORE_PRIVATE_H +#define MMAL_CORE_PRIVATE_H + +/** Initialise the logging system. + */ +void mmal_logging_init(void); + +/** Deinitialise the logging system. + */ +void mmal_logging_deinit(void); + +#endif /* MMAL_CORE_PRIVATE_H */ + diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/core/mmal_events.c b/external_src/raspicam-0.1.3/dependencies/mmal/core/mmal_events.c new file mode 100644 index 0000000..80607f7 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/core/mmal_events.c @@ -0,0 +1,138 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 "mmal.h" +#include "mmal_port_private.h" +#include "mmal_buffer.h" +#include "mmal_logging.h" + +MMAL_EVENT_FORMAT_CHANGED_T *mmal_event_format_changed_get(MMAL_BUFFER_HEADER_T *buffer) +{ + MMAL_EVENT_FORMAT_CHANGED_T *event; + MMAL_ES_FORMAT_T *format; + uint32_t size; + + size = sizeof(MMAL_EVENT_FORMAT_CHANGED_T); + size += sizeof(MMAL_ES_FORMAT_T) + sizeof(MMAL_ES_SPECIFIC_FORMAT_T); + + if (!buffer || buffer->cmd != MMAL_EVENT_FORMAT_CHANGED || buffer->length < size) + return 0; + + event = (MMAL_EVENT_FORMAT_CHANGED_T *)buffer->data; + format = event->format = (MMAL_ES_FORMAT_T *)&event[1]; + format->es = (MMAL_ES_SPECIFIC_FORMAT_T *)&format[1]; + format->extradata = (uint8_t *)&format->es[1]; + format->extradata_size = buffer->length - size; + return event; +} + +MMAL_STATUS_T mmal_event_error_send(MMAL_COMPONENT_T *component, MMAL_STATUS_T error_status) +{ + MMAL_BUFFER_HEADER_T* event; + MMAL_STATUS_T status; + + if(!component) + { + LOG_ERROR("invalid component"); + return MMAL_EINVAL; + } + + status = mmal_port_event_get(component->control, &event, MMAL_EVENT_ERROR); + if (status != MMAL_SUCCESS) + { + LOG_ERROR("event not available for component %s %p, result %d", component->name, component, status); + return status; + } + + event->length = sizeof(MMAL_STATUS_T); + *(MMAL_STATUS_T *)event->data = error_status; + mmal_port_event_send(component->control, event); + + return MMAL_SUCCESS; +} + +MMAL_STATUS_T mmal_event_eos_send(MMAL_PORT_T *port) +{ + MMAL_EVENT_END_OF_STREAM_T *event; + MMAL_BUFFER_HEADER_T *buffer; + MMAL_STATUS_T status; + + if(!port) + { + LOG_ERROR("invalid port"); + return MMAL_EINVAL; + } + + status = mmal_port_event_get(port->component->control, &buffer, MMAL_EVENT_EOS); + if (status != MMAL_SUCCESS) + { + LOG_ERROR("event not available for port %s %p, result %d", port->name, port, status); + return status; + } + + buffer->length = sizeof(*event); + event = (MMAL_EVENT_END_OF_STREAM_T *)buffer->data; + event->port_type = port->type; + event->port_index = port->index; + mmal_port_event_send(port->component->control, buffer); + + return MMAL_SUCCESS; +} + +MMAL_STATUS_T mmal_event_forward(MMAL_BUFFER_HEADER_T *event, MMAL_PORT_T *port) +{ + MMAL_BUFFER_HEADER_T *buffer; + MMAL_STATUS_T status; + + if(!port || port->type != MMAL_PORT_TYPE_OUTPUT) + { + LOG_ERROR("invalid port"); + return MMAL_EINVAL; + } + + status = mmal_port_event_get(port->component->control, &buffer, event->cmd); + if (status != MMAL_SUCCESS) + { + LOG_ERROR("event not available for port %s %p, result %d", port->name, port, status); + return status; + } + + if (buffer->alloc_size < event->length) + { + LOG_ERROR("event buffer too small (%i/%i)", buffer->alloc_size, event->length); + mmal_buffer_header_release(buffer); + return MMAL_ENOSPC; + } + + memcpy(buffer->data, event->data, event->length); + buffer->length = event->length; + buffer->offset = event->offset; + buffer->flags = event->flags; + buffer->pts = event->pts; + mmal_port_event_send(port->component->control, buffer); + return MMAL_SUCCESS; +} diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/core/mmal_events_private.h b/external_src/raspicam-0.1.3/dependencies/mmal/core/mmal_events_private.h new file mode 100644 index 0000000..00d7307 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/core/mmal_events_private.h @@ -0,0 +1,67 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 MMAL_EVENTS_PRIVATE_H +#define MMAL_EVENTS_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "mmal_events.h" + +/** Send an error event through the component's control port. + * The error event data will be the MMAL_STATUS_T passed in. + * + * @param component component to receive the error event. + * @param status the error status to be sent. + * @return MMAL_SUCCESS or an error if the event could not be sent. + */ +MMAL_STATUS_T mmal_event_error_send(MMAL_COMPONENT_T *component, MMAL_STATUS_T status); + +/** Send an eos event through a specific port. + * + * @param port port to receive the error event. + * @return MMAL_SUCCESS or an error if the event could not be sent. + */ +MMAL_STATUS_T mmal_event_eos_send(MMAL_PORT_T *port); + +/** Forward an event onto an output port. + * This will allocate a new event buffer on the output port, make a copy + * of the event buffer which will then be forwarded. + * + * @event event to forward. + * @param port port to forward event to. + * @return MMAL_SUCCESS or an error if the event could not be forwarded. + */ +MMAL_STATUS_T mmal_event_forward(MMAL_BUFFER_HEADER_T *event, MMAL_PORT_T *port); + +#ifdef __cplusplus +} +#endif + +#endif /* MMAL_EVENTS_PRIVATE_H */ diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/core/mmal_format.c b/external_src/raspicam-0.1.3/dependencies/mmal/core/mmal_format.c new file mode 100644 index 0000000..7b8e25e --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/core/mmal_format.c @@ -0,0 +1,183 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 "mmal_types.h" +#include "mmal_format.h" +#include "util/mmal_util_rational.h" + +#define MMAL_ES_FORMAT_MAGIC MMAL_FOURCC('m','a','g','f') +#define EXTRADATA_SIZE_DEFAULT 32 +#define EXTRADATA_SIZE_MAX (10*1024) + +typedef struct MMAL_ES_FORMAT_PRIVATE_T +{ + MMAL_ES_FORMAT_T format; + MMAL_ES_SPECIFIC_FORMAT_T es; + + uint32_t magic; + + unsigned int extradata_size; + uint8_t *extradata; + + uint8_t buffer[EXTRADATA_SIZE_DEFAULT]; + +} MMAL_ES_FORMAT_PRIVATE_T; + +/** Allocate a format structure */ +MMAL_ES_FORMAT_T *mmal_format_alloc(void) +{ + MMAL_ES_FORMAT_PRIVATE_T *private; + + private = vcos_malloc(sizeof(*private), "mmal format"); + if(!private) return 0; + memset(private, 0, sizeof(*private)); + + private->magic = MMAL_ES_FORMAT_MAGIC; + private->format.es = (void *)&private->es; + private->extradata_size = EXTRADATA_SIZE_DEFAULT; + + return &private->format; +} + +/** Free a format structure */ +void mmal_format_free(MMAL_ES_FORMAT_T *format) +{ + MMAL_ES_FORMAT_PRIVATE_T *private = (MMAL_ES_FORMAT_PRIVATE_T *)format; + vcos_assert(private->magic == MMAL_ES_FORMAT_MAGIC); + if(private->extradata) vcos_free(private->extradata); + vcos_free(private); +} + +/** Copy a format structure */ +void mmal_format_copy(MMAL_ES_FORMAT_T *fmt_dst, MMAL_ES_FORMAT_T *fmt_src) +{ + void *backup = fmt_dst->es; + *fmt_dst->es = *fmt_src->es; + *fmt_dst = *fmt_src; + fmt_dst->es = backup; + fmt_dst->extradata = 0; + fmt_dst->extradata_size = 0; +} + +/** Full copy of a format structure (including extradata) */ +MMAL_STATUS_T mmal_format_full_copy(MMAL_ES_FORMAT_T *fmt_dst, MMAL_ES_FORMAT_T *fmt_src) +{ + mmal_format_copy(fmt_dst, fmt_src); + + if (fmt_src->extradata_size) + { + MMAL_STATUS_T status = mmal_format_extradata_alloc(fmt_dst, fmt_src->extradata_size); + if (status != MMAL_SUCCESS) + return status; + fmt_dst->extradata_size = fmt_src->extradata_size; + memcpy(fmt_dst->extradata, fmt_src->extradata, fmt_src->extradata_size); + } + return MMAL_SUCCESS; +} + +/** Compare 2 format structures */ +uint32_t mmal_format_compare(MMAL_ES_FORMAT_T *fmt1, MMAL_ES_FORMAT_T *fmt2) +{ + MMAL_VIDEO_FORMAT_T *video1, *video2; + uint32_t result = 0; + + if (fmt1->type != fmt2->type) + return MMAL_ES_FORMAT_COMPARE_FLAG_TYPE; + + if (fmt1->encoding != fmt2->encoding) + result |= MMAL_ES_FORMAT_COMPARE_FLAG_ENCODING; + if (fmt1->bitrate != fmt2->bitrate) + result |= MMAL_ES_FORMAT_COMPARE_FLAG_BITRATE; + if (fmt1->flags != fmt2->flags) + result |= MMAL_ES_FORMAT_COMPARE_FLAG_FLAGS; + if (fmt1->extradata_size != fmt2->extradata_size || + (fmt1->extradata_size && (!fmt1->extradata || !fmt2->extradata)) || + memcmp(fmt1->extradata, fmt2->extradata, fmt1->extradata_size)) + result |= MMAL_ES_FORMAT_COMPARE_FLAG_EXTRADATA; + + /* Compare the ES specific information */ + switch (fmt1->type) + { + case MMAL_ES_TYPE_VIDEO: + video1 = &fmt1->es->video; + video2 = &fmt2->es->video; + if (video1->width != video2->width || video1->height != video2->height) + result |= MMAL_ES_FORMAT_COMPARE_FLAG_VIDEO_RESOLUTION; + if (memcmp(&video1->crop, &video2->crop, sizeof(video1->crop))) + result |= MMAL_ES_FORMAT_COMPARE_FLAG_VIDEO_CROPPING; + if (!mmal_rational_equal(video1->par, video2->par)) + result |= MMAL_ES_FORMAT_COMPARE_FLAG_VIDEO_ASPECT_RATIO; + if (!mmal_rational_equal(video1->frame_rate, video2->frame_rate)) + result |= MMAL_ES_FORMAT_COMPARE_FLAG_VIDEO_FRAME_RATE; + if (video1->color_space != video2->color_space) + result |= MMAL_ES_FORMAT_COMPARE_FLAG_VIDEO_COLOR_SPACE; + /* coverity[overrun-buffer-arg] We're comparing the rest of the video format structure */ + if (memcmp(((char*)&video1->color_space) + sizeof(video1->color_space), + ((char*)&video2->color_space) + sizeof(video2->color_space), + sizeof(*video1) - offsetof(MMAL_VIDEO_FORMAT_T, color_space) - sizeof(video1->color_space))) + result |= MMAL_ES_FORMAT_COMPARE_FLAG_ES_OTHER; + break; + case MMAL_ES_TYPE_AUDIO: + if (memcmp(fmt1->es, fmt2->es, sizeof(MMAL_AUDIO_FORMAT_T))) + result |= MMAL_ES_FORMAT_COMPARE_FLAG_ES_OTHER; + break; + case MMAL_ES_TYPE_SUBPICTURE: + if (memcmp(fmt1->es, fmt2->es, sizeof(MMAL_SUBPICTURE_FORMAT_T))) + result |= MMAL_ES_FORMAT_COMPARE_FLAG_ES_OTHER; + break; + default: + break; + } + + return result; +} + +/** */ +MMAL_STATUS_T mmal_format_extradata_alloc(MMAL_ES_FORMAT_T *format, unsigned int size) +{ + MMAL_ES_FORMAT_PRIVATE_T *private = (MMAL_ES_FORMAT_PRIVATE_T *)format; + + /* Sanity check the size requested */ + if(size > EXTRADATA_SIZE_MAX) + return MMAL_EINVAL; + + /* Allocate memory if needed */ + if(private->extradata_size < size) + { + if(private->extradata) vcos_free(private->extradata); + private->extradata = vcos_malloc(size, "mmal format extradata"); + if(!private->extradata) + return MMAL_ENOMEM; + private->extradata_size = size; + } + + /* Set the fields in the actual format structure */ + if(private->extradata) private->format.extradata = private->extradata; + else private->format.extradata = private->buffer; + + return MMAL_SUCCESS; +} diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/core/mmal_logging.c b/external_src/raspicam-0.1.3/dependencies/mmal/core/mmal_logging.c new file mode 100644 index 0000000..e05bc92 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/core/mmal_logging.c @@ -0,0 +1,43 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 "mmal_logging.h" +#include "core/mmal_core_private.h" + +VCOS_LOG_CAT_T mmal_log_category; +static VCOS_LOG_LEVEL_T mmal_log_level = VCOS_LOG_ERROR; + +void mmal_logging_init(void) +{ + vcos_log_set_level(VCOS_LOG_CATEGORY, mmal_log_level); + vcos_log_register("mmal", VCOS_LOG_CATEGORY); +} + +void mmal_logging_deinit(void) +{ + mmal_log_level = mmal_log_category.level; + vcos_log_unregister(VCOS_LOG_CATEGORY); +} diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/core/mmal_pool.c b/external_src/raspicam-0.1.3/dependencies/mmal/core/mmal_pool.c new file mode 100644 index 0000000..1eac85f --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/core/mmal_pool.c @@ -0,0 +1,303 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 "mmal.h" +#include "mmal_pool.h" +#include "core/mmal_buffer_private.h" +#include "mmal_logging.h" + +/** Definition of a pool */ +typedef struct MMAL_POOL_PRIVATE_T +{ + MMAL_POOL_T pool; /**< Actual pool */ + + MMAL_POOL_BH_CB_T cb; /**< Buffer header release callback */ + void *userdata; /**< User provided data to pass with callback */ + + mmal_pool_allocator_alloc_t allocator_alloc; /**< Allocator for the payload buffers */ + mmal_pool_allocator_free_t allocator_free; /**< Allocator for the payload buffers */ + void *allocator_context; /**< Context for the allocator */ + + unsigned int header_size; /**< Size of an initialised buffer header structure */ + unsigned int payload_size; + + unsigned int headers_alloc_num; /**< Number of buffer headers allocated as part of the private structure */ + +} MMAL_POOL_PRIVATE_T; + +#define ROUND_UP(s,align) ((((unsigned long)(s)) & ~((align)-1)) + (align)) +#define ALIGN 8 + +static void mmal_pool_buffer_header_release(MMAL_BUFFER_HEADER_T *header); + +static void *mmal_pool_allocator_default_alloc(void *context, uint32_t size) +{ + MMAL_PARAM_UNUSED(context); + return vcos_malloc(size, "mmal_pool payload"); +} + +static void mmal_pool_allocator_default_free(void *context, void *mem) +{ + MMAL_PARAM_UNUSED(context); + vcos_free(mem); +} + +static MMAL_STATUS_T mmal_pool_initialise_buffer_headers(MMAL_POOL_T *pool, unsigned int headers, + MMAL_BOOL_T reinitialise) +{ + MMAL_POOL_PRIVATE_T *private = (MMAL_POOL_PRIVATE_T *)pool; + MMAL_BUFFER_HEADER_T *header; + uint8_t *payload = NULL; + unsigned int i; + + header = (MMAL_BUFFER_HEADER_T *)((uint8_t *)pool->header + ROUND_UP(sizeof(void *)*headers,ALIGN)); + + for (i = 0; i < headers; i++) + { + if (reinitialise) + header = mmal_buffer_header_initialise(header, private->header_size); + + if (private->payload_size && private->allocator_alloc) + { + LOG_TRACE("allocating %u bytes for payload %u/%u", private->payload_size, i, headers); + payload = (uint8_t*)private->allocator_alloc(private->allocator_context, private->payload_size); + if (! payload) + { + LOG_ERROR("failed to allocate payload %u/%u", i, headers); + return MMAL_ENOMEM; + } + } + else + { + if (header->priv->pf_payload_free && header->priv->payload && header->priv->payload_size) + { + LOG_TRACE("freeing %u bytes for payload %u/%u", header->priv->payload_size, i, headers); + header->priv->pf_payload_free(header->priv->payload_context, header->priv->payload); + } + } + header->data = payload; + header->alloc_size = private->payload_size; + header->priv->pf_release = mmal_pool_buffer_header_release; + header->priv->owner = (void *)pool; + header->priv->refcount = 1; + header->priv->payload = payload; + header->priv->payload_context = private->allocator_context; + header->priv->pf_payload_free = private->allocator_free; + header->priv->payload_size = private->payload_size; + pool->header[i] = header; + pool->headers_num = i+1; + header = (MMAL_BUFFER_HEADER_T *)((uint8_t*)header + private->header_size); + } + + return MMAL_SUCCESS; +} + +/** Create a pool of MMAL_BUFFER_HEADER_T */ +MMAL_POOL_T *mmal_pool_create(unsigned int headers, uint32_t payload_size) +{ + return mmal_pool_create_with_allocator(headers, payload_size, NULL, + mmal_pool_allocator_default_alloc, mmal_pool_allocator_default_free); +} + +/** Create a pool of MMAL_BUFFER_HEADER_T */ +MMAL_POOL_T *mmal_pool_create_with_allocator(unsigned int headers, uint32_t payload_size, + void *allocator_context, mmal_pool_allocator_alloc_t allocator_alloc, + mmal_pool_allocator_free_t allocator_free) +{ + unsigned int i, headers_array_size, header_size, pool_size; + MMAL_POOL_PRIVATE_T *private; + MMAL_BUFFER_HEADER_T **array; + MMAL_POOL_T *pool; + MMAL_QUEUE_T *queue; + + queue = mmal_queue_create(); + if (!queue) + { + LOG_ERROR("failed to create queue"); + return NULL; + } + + /* Calculate how much memory we need */ + pool_size = ROUND_UP(sizeof(MMAL_POOL_PRIVATE_T),ALIGN); + headers_array_size = ROUND_UP(sizeof(void *)*headers,ALIGN); + header_size = ROUND_UP(mmal_buffer_header_size(0),ALIGN); + + LOG_TRACE("allocating %u + %u + %u * %u bytes for pool", + pool_size, headers_array_size, header_size, headers); + private = vcos_calloc(pool_size, 1, "MMAL pool"); + array = vcos_calloc(headers_array_size + header_size * headers, 1, "MMAL buffer headers"); + if (!private || !array) + { + LOG_ERROR("failed to allocate pool"); + if (private) vcos_free(private); + if (array) vcos_free(array); + mmal_queue_destroy(queue); + return NULL; + } + pool = &private->pool; + pool->queue = queue; + pool->header = (MMAL_BUFFER_HEADER_T **)array; + private->header_size = header_size; + private->payload_size = payload_size; + private->headers_alloc_num = headers; + + /* Use default allocators if none has been specified by client */ + if (!allocator_alloc || !allocator_free) + { + allocator_alloc = mmal_pool_allocator_default_alloc; + allocator_free = mmal_pool_allocator_default_free; + allocator_context = NULL; + } + + /* Keep reference to the allocator to allow resizing the payloads at a later point */ + private->allocator_alloc = allocator_alloc; + private->allocator_free = allocator_free; + private->allocator_context = allocator_context; + + if (mmal_pool_initialise_buffer_headers(pool, headers, 1) != MMAL_SUCCESS) + { + mmal_pool_destroy(pool); + return NULL; + } + + /* Add all the headers to the queue */ + for (i = 0; i < pool->headers_num; i++) + mmal_queue_put(queue, pool->header[i]); + + return pool; +} + +/** Destroy a pool of MMAL_BUFFER_HEADER_T */ +void mmal_pool_destroy(MMAL_POOL_T *pool) +{ + unsigned int i; + + if (!pool) + return; + + /* If the payload_size is non-zero then the buffer header payload + * must be freed. Otherwise it is the caller's responsibility. */ + for (i = 0; i < pool->headers_num; ++i) + { + MMAL_BUFFER_HEADER_PRIVATE_T* priv = pool->header[i]->priv; + + if (priv->pf_payload_free && priv->payload && priv->payload_size) + priv->pf_payload_free(priv->payload_context, priv->payload); + } + + if (pool->header) + vcos_free(pool->header); + + if(pool->queue) mmal_queue_destroy(pool->queue); + vcos_free(pool); +} + +/** Resize a pool of MMAL_BUFFER_HEADER_T */ +MMAL_STATUS_T mmal_pool_resize(MMAL_POOL_T *pool, unsigned int headers, uint32_t payload_size) +{ + MMAL_POOL_PRIVATE_T *private = (MMAL_POOL_PRIVATE_T *)pool; + unsigned int i; + + if (!private || !headers) + return MMAL_EINVAL; + + /* Check if anything needs to be done */ + if (headers == pool->headers_num && payload_size == private->payload_size) + return MMAL_SUCCESS; + + /* Remove all the headers from the queue */ + for (i = 0; i < pool->headers_num; i++) + mmal_queue_get(pool->queue); + + /* Start by freeing the current payloads */ + private->payload_size = 0; + mmal_pool_initialise_buffer_headers(pool, pool->headers_num, 0); + pool->headers_num = 0; + + /* Check if we need to reallocate the buffer headers themselves */ + if (headers > private->headers_alloc_num) + { + private->headers_alloc_num = 0; + if (pool->header) + vcos_free(pool->header); + pool->header = + vcos_calloc(private->header_size * headers + ROUND_UP(sizeof(void *)*headers,ALIGN), + 1, "MMAL buffer headers"); + if (!pool->header) + return MMAL_ENOMEM; + private->headers_alloc_num = headers; + } + + /* Allocate the new payloads */ + private->payload_size = payload_size; + mmal_pool_initialise_buffer_headers(pool, headers, 1); + + /* Add all the headers to the queue */ + for (i = 0; i < pool->headers_num; i++) + mmal_queue_put(pool->queue, pool->header[i]); + + return MMAL_SUCCESS; +} + +/** Buffer header release callback. + * Call out to a further client callback and put the buffer back in the queue + * so it can be reused, unless the client callback prevents it. */ +static void mmal_pool_buffer_header_release(MMAL_BUFFER_HEADER_T *header) +{ + MMAL_POOL_T *pool = (MMAL_POOL_T *)header->priv->owner; + MMAL_POOL_PRIVATE_T *private = (MMAL_POOL_PRIVATE_T *)pool; + MMAL_BOOL_T queue_buffer = 1; + + header->priv->refcount = 1; + if(private->cb) + queue_buffer = private->cb(pool, header, private->userdata); + if (queue_buffer) + mmal_queue_put(pool->queue, header); +} + +/** Set a buffer header release callback to the pool */ +void mmal_pool_callback_set(MMAL_POOL_T *pool, MMAL_POOL_BH_CB_T cb, void *userdata) +{ + MMAL_POOL_PRIVATE_T *private = (MMAL_POOL_PRIVATE_T *)pool; + private->cb = cb; + private->userdata = userdata; +} + +/* Set a pre-release callback for all buffer headers in the pool */ +void mmal_pool_pre_release_callback_set(MMAL_POOL_T *pool, MMAL_BH_PRE_RELEASE_CB_T cb, void *userdata) +{ + unsigned int i; + MMAL_POOL_PRIVATE_T *private = (MMAL_POOL_PRIVATE_T *)pool; + MMAL_BUFFER_HEADER_T *header = + (MMAL_BUFFER_HEADER_T*)((uint8_t*)pool->header + ROUND_UP(sizeof(void*)*pool->headers_num,ALIGN)); + + for (i = 0; i < pool->headers_num; ++i) + { + mmal_buffer_header_pre_release_cb_set(header, cb, userdata); + header = (MMAL_BUFFER_HEADER_T *)((uint8_t*)header + private->header_size); + } +} diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/core/mmal_port.c b/external_src/raspicam-0.1.3/dependencies/mmal/core/mmal_port.c new file mode 100644 index 0000000..d7b00c1 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/core/mmal_port.c @@ -0,0 +1,1508 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 "mmal.h" +#include "util/mmal_util.h" +#include "core/mmal_component_private.h" +#include "core/mmal_port_private.h" +#include "interface/vcos/vcos.h" +#include "mmal_logging.h" +#include "interface/mmal/util/mmal_util.h" +#include "interface/mmal/mmal_parameters.h" +#include + +#ifdef _VIDEOCORE +#include "vcfw/rtos/common/rtos_common_mem.h" /* mem_alloc */ +#endif + +/** Only collect port stats if enabled in build. Performance could be + * affected on an ARM since gettimeofday() involves a system call. + */ +#if defined(MMAL_COLLECT_PORT_STATS) +# define MMAL_COLLECT_PORT_STATS_ENABLED 1 +#else +# define MMAL_COLLECT_PORT_STATS_ENABLED 0 +#endif + +static MMAL_STATUS_T mmal_port_private_parameter_get(MMAL_PORT_T *port, + MMAL_PARAMETER_HEADER_T *param); + +static MMAL_STATUS_T mmal_port_private_parameter_set(MMAL_PORT_T *port, + const MMAL_PARAMETER_HEADER_T *param); + +/* Define this if you want to log all buffer transfers */ +//#define ENABLE_MMAL_EXTRA_LOGGING + +/** Definition of the core's private structure for a port. */ +typedef struct MMAL_PORT_PRIVATE_CORE_T +{ + VCOS_MUTEX_T lock; /**< Used to lock access to the port */ + VCOS_MUTEX_T send_lock; /**< Used to lock access while sending buffer to the port */ + VCOS_MUTEX_T stats_lock; /**< Used to lock access to the stats */ + VCOS_MUTEX_T connection_lock; /**< Used to lock access to a connection */ + + /** Callback set by client to call when buffer headers need to be returned */ + MMAL_PORT_BH_CB_T buffer_header_callback; + + /** Keeps track of the number of buffer headers currently in transit in this port */ + int32_t transit_buffer_headers; + VCOS_MUTEX_T transit_lock; + VCOS_SEMAPHORE_T transit_sema; + + /** Copy of the public port format pointer, to detect accidental overwrites */ + MMAL_ES_FORMAT_T* format_ptr_copy; + + /** Port to which this port is connected, or NULL if disconnected */ + MMAL_PORT_T* connected_port; + + MMAL_BOOL_T core_owns_connection; /**< Connection is handled by the core */ + + /** Pool of buffers used between connected ports - output port only */ + MMAL_POOL_T* pool_for_connection; + + /** Indicates whether the port is paused or not. Buffers received on + * a paused port will be queued instead of being sent to the component. */ + MMAL_BOOL_T is_paused; + /** Queue for buffers received from the client when in paused state */ + MMAL_BUFFER_HEADER_T* queue_first; + /** Queue for buffers received from the client when in paused state */ + MMAL_BUFFER_HEADER_T** queue_last; + + /** Per-port statistics collected directly by the MMAL core */ + MMAL_CORE_PORT_STATISTICS_T stats; + + char *name; /**< Port name */ + unsigned int name_size; /** Size of the memory area reserved for the name string */ +} MMAL_PORT_PRIVATE_CORE_T; + +/***************************************************************************** + * Static declarations + *****************************************************************************/ +static MMAL_STATUS_T mmal_port_enable_internal(MMAL_PORT_T *port, MMAL_PORT_BH_CB_T cb); +static MMAL_STATUS_T mmal_port_disable_internal(MMAL_PORT_T *port); + +static MMAL_STATUS_T mmal_port_connection_enable(MMAL_PORT_T *port, MMAL_PORT_T *connected_port); +static MMAL_STATUS_T mmal_port_connection_disable(MMAL_PORT_T *port, MMAL_PORT_T *connected_port); +static MMAL_STATUS_T mmal_port_connection_start(MMAL_PORT_T *port, MMAL_PORT_T *connected_port); +static MMAL_STATUS_T mmal_port_populate_from_pool(MMAL_PORT_T* port, MMAL_POOL_T* pool); +static MMAL_STATUS_T mmal_port_populate_clock_ports(MMAL_PORT_T* output, MMAL_PORT_T* input, MMAL_POOL_T* pool); +static MMAL_STATUS_T mmal_port_connect_default(MMAL_PORT_T *port, MMAL_PORT_T *other_port); +static void mmal_port_connected_input_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer); +static void mmal_port_connected_output_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer); +static MMAL_BOOL_T mmal_port_connected_pool_cb(MMAL_POOL_T *pool, MMAL_BUFFER_HEADER_T *buffer, void *userdata); + +static void mmal_port_name_update(MMAL_PORT_T *port); +static void mmal_port_update_port_stats(MMAL_PORT_T *port, MMAL_CORE_STATS_DIR direction); + +/*****************************************************************************/ + +/* Macros used to make the port API thread safe */ +#define LOCK_PORT(a) vcos_mutex_lock(&(a)->priv->core->lock); +#define UNLOCK_PORT(a) vcos_mutex_unlock(&(a)->priv->core->lock); + +/* Macros used to make the buffer sending / flushing thread safe */ +#define LOCK_SENDING(a) vcos_mutex_lock(&(a)->priv->core->send_lock); +#define UNLOCK_SENDING(a) vcos_mutex_unlock(&(a)->priv->core->send_lock); + +/* Macros used to make the port connection API thread safe */ +#define LOCK_CONNECTION(a) vcos_mutex_lock(&(a)->priv->core->connection_lock); +#define UNLOCK_CONNECTION(a) vcos_mutex_unlock(&(a)->priv->core->connection_lock); + +/* Macros used to make mmal_port_disable() blocking until all + * the buffers have been sent back to the client */ +#define IN_TRANSIT_INCREMENT(a) \ + vcos_mutex_lock(&(a)->priv->core->transit_lock); \ + if (!(a)->priv->core->transit_buffer_headers++) \ + vcos_semaphore_wait(&(a)->priv->core->transit_sema); \ + vcos_mutex_unlock(&(a)->priv->core->transit_lock) +#define IN_TRANSIT_DECREMENT(a) \ + vcos_mutex_lock(&(a)->priv->core->transit_lock); \ + if (!--(a)->priv->core->transit_buffer_headers) \ + vcos_semaphore_post(&(a)->priv->core->transit_sema); \ + vcos_mutex_unlock(&(a)->priv->core->transit_lock) +#define IN_TRANSIT_WAIT(a) \ + vcos_semaphore_wait(&(a)->priv->core->transit_sema); \ + vcos_semaphore_post(&(a)->priv->core->transit_sema) +#define IN_TRANSIT_COUNT(a) \ + (a)->priv->core->transit_buffer_headers + +#define PORT_NAME_FORMAT "%s:%.2222s:%i%c%4.4s)" + +/*****************************************************************************/ + +/** Allocate a port structure */ +MMAL_PORT_T *mmal_port_alloc(MMAL_COMPONENT_T *component, MMAL_PORT_TYPE_T type, unsigned int extra_size) +{ + MMAL_PORT_T *port; + MMAL_PORT_PRIVATE_CORE_T *core; + unsigned int name_size = strlen(component->name) + sizeof(PORT_NAME_FORMAT); + unsigned int size = sizeof(*port) + sizeof(MMAL_PORT_PRIVATE_T) + + sizeof(MMAL_PORT_PRIVATE_CORE_T) + name_size + extra_size; + MMAL_BOOL_T lock = 0, lock_send = 0, lock_transit = 0, sema_transit = 0; + MMAL_BOOL_T lock_stats = 0, lock_connection = 0; + + LOG_TRACE("component:%s type:%u extra:%u", component->name, type, extra_size); + + port = vcos_calloc(1, size, "mmal port"); + if (!port) + { + LOG_ERROR("failed to allocate port, size %u", size); + return 0; + } + port->type = type; + + port->priv = (MMAL_PORT_PRIVATE_T *)(port+1); + port->priv->core = core = (MMAL_PORT_PRIVATE_CORE_T *)(port->priv+1); + if (extra_size) + port->priv->module = (struct MMAL_PORT_MODULE_T *)(port->priv->core+1); + port->component = component; + port->name = core->name = ((char *)(port->priv->core+1)) + extra_size; + core->name_size = name_size; + mmal_port_name_update(port); + core->queue_last = &core->queue_first; + + port->priv->pf_connect = mmal_port_connect_default; + + lock = vcos_mutex_create(&port->priv->core->lock, "mmal port lock") == VCOS_SUCCESS; + lock_send = vcos_mutex_create(&port->priv->core->send_lock, "mmal port send lock") == VCOS_SUCCESS; + lock_transit = vcos_mutex_create(&port->priv->core->transit_lock, "mmal port transit lock") == VCOS_SUCCESS; + sema_transit = vcos_semaphore_create(&port->priv->core->transit_sema, "mmal port transit sema", 1) == VCOS_SUCCESS; + lock_stats = vcos_mutex_create(&port->priv->core->stats_lock, "mmal stats lock") == VCOS_SUCCESS; + lock_connection = vcos_mutex_create(&port->priv->core->connection_lock, "mmal connection lock") == VCOS_SUCCESS; + + if (!lock || !lock_send || !lock_transit || !sema_transit || !lock_stats || !lock_connection) + { + LOG_ERROR("%s: failed to create sync objects (%u,%u,%u,%u,%u,%u)", + port->name, lock, lock_send, lock_transit, sema_transit, lock_stats, lock_connection); + goto error; + } + + port->format = mmal_format_alloc(); + if (!port->format) + { + LOG_ERROR("%s: failed to allocate format object", port->name); + goto error; + } + port->priv->core->format_ptr_copy = port->format; + + LOG_TRACE("%s: created at %p", port->name, port); + return port; + + error: + if (lock) vcos_mutex_delete(&port->priv->core->lock); + if (lock_send) vcos_mutex_delete(&port->priv->core->send_lock); + if (lock_transit) vcos_mutex_delete(&port->priv->core->transit_lock); + if (sema_transit) vcos_semaphore_delete(&port->priv->core->transit_sema); + if (lock_stats) vcos_mutex_delete(&port->priv->core->stats_lock); + if (lock_connection) vcos_mutex_delete(&port->priv->core->connection_lock); + if (port->format) mmal_format_free(port->format); + vcos_free(port); + return 0; +} + +/** Free a port structure */ +void mmal_port_free(MMAL_PORT_T *port) +{ + LOG_TRACE("%s at %p", port ? port->name : "", port); + + if (!port) + return; + + vcos_assert(port->format == port->priv->core->format_ptr_copy); + mmal_format_free(port->priv->core->format_ptr_copy); + vcos_mutex_delete(&port->priv->core->connection_lock); + vcos_mutex_delete(&port->priv->core->stats_lock); + vcos_semaphore_delete(&port->priv->core->transit_sema); + vcos_mutex_delete(&port->priv->core->transit_lock); + vcos_mutex_delete(&port->priv->core->send_lock); + vcos_mutex_delete(&port->priv->core->lock); + vcos_free(port); +} + +/** Allocate an array of ports */ +MMAL_PORT_T **mmal_ports_alloc(MMAL_COMPONENT_T *component, unsigned int ports_num, + MMAL_PORT_TYPE_T type, unsigned int extra_size) +{ + MMAL_PORT_T **ports; + unsigned int i; + + ports = vcos_malloc(sizeof(MMAL_PORT_T *) * ports_num, "mmal ports"); + if (!ports) + return 0; + + for (i = 0; i < ports_num; i++) + { + ports[i] = mmal_port_alloc(component, type, extra_size); + if (!ports[i]) + break; + ports[i]->index = i; + mmal_port_name_update(ports[i]); + } + + if (i != ports_num) + { + for (ports_num = i, i = 0; i < ports_num; i++) + mmal_port_free(ports[i]); + vcos_free(ports); + return 0; + } + + return ports; +} + +/** Free an array of ports */ +void mmal_ports_free(MMAL_PORT_T **ports, unsigned int ports_num) +{ + unsigned int i; + + for (i = 0; i < ports_num; i++) + mmal_port_free(ports[i]); + vcos_free(ports); +} + +/** Set format of a port */ +MMAL_STATUS_T mmal_port_format_commit(MMAL_PORT_T *port) +{ + MMAL_STATUS_T status; + char encoding_string[16]; + + if (!port || !port->priv) + { + LOG_ERROR("invalid port (%p/%p)", port, port ? port->priv : NULL); + return MMAL_EINVAL; + } + + if (port->format != port->priv->core->format_ptr_copy) + { + LOG_ERROR("%s: port format has been overwritten, resetting %p to %p", + port->name, port->format, port->priv->core->format_ptr_copy); + port->format = port->priv->core->format_ptr_copy; + return MMAL_EFAULT; + } + + if (port->format->encoding == 0) + snprintf(encoding_string, sizeof(encoding_string), ""); + else + snprintf(encoding_string, sizeof(encoding_string), "%4.4s", (char*)&port->format->encoding); + + LOG_TRACE("%s(%i:%i) port %p format %i:%s", + port->component->name, (int)port->type, (int)port->index, port, + (int)port->format->type, encoding_string); + + if (!port->priv->pf_set_format) + { + LOG_ERROR("%s: no component implementation", port->name); + return MMAL_ENOSYS; + } + + LOCK_PORT(port); + status = port->priv->pf_set_format(port); + mmal_port_name_update(port); + + /* Make sure the buffer size / num are sensible */ + if (port->buffer_size < port->buffer_size_min) + port->buffer_size = port->buffer_size_min; + if (port->buffer_num < port->buffer_num_min) + port->buffer_num = port->buffer_num_min; + /* The output port settings might have changed */ + if (port->type == MMAL_PORT_TYPE_INPUT) + { + MMAL_PORT_T **ports = port->component->output; + unsigned int i; + + for (i = 0; i < port->component->output_num; i++) + { + if (ports[i]->buffer_size < ports[i]->buffer_size_min) + ports[i]->buffer_size = ports[i]->buffer_size_min; + if (ports[i]->buffer_num < ports[i]->buffer_num_min) + ports[i]->buffer_num = ports[i]->buffer_num_min; + } + } + + UNLOCK_PORT(port); + return status; +} + +/** Enable processing on a port */ +MMAL_STATUS_T mmal_port_enable(MMAL_PORT_T *port, MMAL_PORT_BH_CB_T cb) +{ + MMAL_STATUS_T status; + MMAL_PORT_T *connected_port; + MMAL_PORT_PRIVATE_CORE_T *core; + + if (!port || !port->priv) + return MMAL_EINVAL; + + LOG_TRACE("%s port %p, cb %p, buffers (%i/%i/%i,%i/%i/%i)", + port->name, port, cb, + (int)port->buffer_num, (int)port->buffer_num_recommended, (int)port->buffer_num_min, + (int)port->buffer_size, (int)port->buffer_size_recommended, (int)port->buffer_size_min); + + if (!port->priv->pf_enable) + return MMAL_ENOSYS; + + core = port->priv->core; + LOCK_CONNECTION(port); + connected_port = core->connected_port; + + /* Sanity checking */ + if (port->is_enabled) + { + UNLOCK_CONNECTION(port); + LOG_ERROR("%s(%p) already enabled", port->name, port); + return MMAL_EINVAL; + } + if (connected_port && cb) /* Callback must be NULL for connected ports */ + { + UNLOCK_CONNECTION(port); + LOG_ERROR("callback (%p) not allowed for connected port (%s)%p", + cb, port->name, connected_port); + return MMAL_EINVAL; + } + + /* Start by preparing the port connection so that everything is ready for when + * both ports are enabled */ + if (connected_port) + { + LOCK_CONNECTION(connected_port); + status = mmal_port_connection_enable(port, connected_port); + if (status != MMAL_SUCCESS) + { + UNLOCK_CONNECTION(connected_port); + UNLOCK_CONNECTION(port); + return status; + } + + cb = connected_port->type == MMAL_PORT_TYPE_INPUT ? + mmal_port_connected_output_cb : mmal_port_connected_input_cb; + } + + /* Enable the input port of a connection first */ + if (connected_port && connected_port->type == MMAL_PORT_TYPE_INPUT) + { + status = mmal_port_enable_internal(connected_port, mmal_port_connected_input_cb); + if (status != MMAL_SUCCESS) + { + LOG_ERROR("failed to enable connected port (%s)%p (%s)", connected_port->name, + connected_port, mmal_status_to_string(status)); + goto error; + } + } + + status = mmal_port_enable_internal(port, cb); + if (status != MMAL_SUCCESS) + { + LOG_ERROR("failed to enable port %s(%p) (%s)", port->name, port, + mmal_status_to_string(status)); + goto error; + } + + /* Enable the output port of a connection last */ + if (connected_port && connected_port->type != MMAL_PORT_TYPE_INPUT) + { + status = mmal_port_enable_internal(connected_port, mmal_port_connected_output_cb); + if (status != MMAL_SUCCESS) + { + LOG_ERROR("failed to enable connected port (%s)%p (%s)", connected_port->name, + connected_port, mmal_status_to_string(status)); + goto error; + } + } + + /* Kick off the connection */ + if (connected_port && core->core_owns_connection) + { + status = mmal_port_connection_start(port, connected_port); + if (status != MMAL_SUCCESS) + { + LOG_ERROR("failed to start connection (%s)%p (%s)", port->name, + port, mmal_status_to_string(status)); + goto error; + } + } + + if (connected_port) + UNLOCK_CONNECTION(connected_port); + UNLOCK_CONNECTION(port); + return MMAL_SUCCESS; + +error: + if (connected_port && connected_port->is_enabled) + mmal_port_disable_internal(connected_port); + if (port->is_enabled) + mmal_port_disable_internal(port); + if (connected_port) + mmal_port_connection_disable(port, connected_port); + + if (connected_port) + UNLOCK_CONNECTION(connected_port); + UNLOCK_CONNECTION(port); + return status; +} + +static MMAL_STATUS_T mmal_port_enable_internal(MMAL_PORT_T *port, MMAL_PORT_BH_CB_T cb) +{ + MMAL_PORT_PRIVATE_CORE_T* core = port->priv->core; + MMAL_STATUS_T status = MMAL_SUCCESS; + + LOCK_PORT(port); + + if (port->is_enabled) + goto end; + + /* Sanity check the buffer requirements */ + if (port->buffer_num < port->buffer_num_min) + { + LOG_ERROR("buffer_num too small (%i/%i)", (int)port->buffer_num, (int)port->buffer_num_min); + status = MMAL_EINVAL; + goto end; + } + if (port->buffer_size < port->buffer_size_min) + { + LOG_ERROR("buffer_size too small (%i/%i)", (int)port->buffer_size, (int)port->buffer_size_min); + status = MMAL_EINVAL; + goto end; + } + + core->buffer_header_callback = cb; + status = port->priv->pf_enable(port, cb); + if (status != MMAL_SUCCESS) + goto end; + + LOCK_SENDING(port); + port->is_enabled = 1; + UNLOCK_SENDING(port); + +end: + UNLOCK_PORT(port); + return status; +} + +static MMAL_STATUS_T mmal_port_connection_enable(MMAL_PORT_T *port, MMAL_PORT_T *connected_port) +{ + MMAL_PORT_T *output = port->type == MMAL_PORT_TYPE_OUTPUT ? port : connected_port; + MMAL_PORT_T *input = connected_port->type == MMAL_PORT_TYPE_INPUT ? connected_port : port; + MMAL_PORT_T *pool_port = (output->capabilities & MMAL_PORT_CAPABILITY_ALLOCATION) ? output : input; + MMAL_PORT_PRIVATE_CORE_T *pool_core = pool_port->priv->core; + uint32_t buffer_size, buffer_num; + MMAL_POOL_T *pool; + + /* At this point both ports hold the connection lock */ + + /* Ensure that the buffer numbers and sizes used are the maxima between connected ports. */ + buffer_num = MMAL_MAX(port->buffer_num, connected_port->buffer_num); + buffer_size = MMAL_MAX(port->buffer_size, connected_port->buffer_size); + port->buffer_num = connected_port->buffer_num = buffer_num; + port->buffer_size = connected_port->buffer_size = buffer_size; + + if (output->capabilities & MMAL_PORT_CAPABILITY_PASSTHROUGH) + buffer_size = 0; + + if (!port->priv->core->core_owns_connection) + return MMAL_SUCCESS; + + pool = mmal_port_pool_create(pool_port, buffer_num, buffer_size); + if (!pool) + { + LOG_ERROR("failed to create pool for connection"); + return MMAL_ENOMEM; + } + + pool_core->pool_for_connection = pool; + mmal_pool_callback_set(pool, mmal_port_connected_pool_cb, output); + return MMAL_SUCCESS; +} + +static MMAL_STATUS_T mmal_port_connection_disable(MMAL_PORT_T *port, MMAL_PORT_T *connected_port) +{ + MMAL_POOL_T *pool = port->priv->core->pool_for_connection ? + port->priv->core->pool_for_connection : connected_port->priv->core->pool_for_connection; + + mmal_pool_destroy(pool); + port->priv->core->pool_for_connection = + connected_port->priv->core->pool_for_connection = NULL; + return MMAL_SUCCESS; +} + +static MMAL_STATUS_T mmal_port_connection_start(MMAL_PORT_T *port, MMAL_PORT_T *connected_port) +{ + MMAL_PORT_T *output = port->type == MMAL_PORT_TYPE_OUTPUT ? port : connected_port; + MMAL_PORT_T *input = connected_port->type == MMAL_PORT_TYPE_INPUT ? connected_port : port; + MMAL_POOL_T *pool = port->priv->core->pool_for_connection ? + port->priv->core->pool_for_connection : connected_port->priv->core->pool_for_connection; + MMAL_STATUS_T status; + + if (output->type == MMAL_PORT_TYPE_CLOCK && input->type == MMAL_PORT_TYPE_CLOCK) + { + /* Clock ports need buffers to send clock updates, so + * populate both clock ports */ + status = mmal_port_populate_clock_ports(output, input, pool); + } + else + { + /* Put the buffers into the output port */ + status = mmal_port_populate_from_pool(output, pool); + } + + return status; +} + +/** Disable processing on a port */ +MMAL_STATUS_T mmal_port_disable(MMAL_PORT_T *port) +{ + MMAL_STATUS_T status; + MMAL_PORT_T *connected_port; + MMAL_PORT_PRIVATE_CORE_T *core; + + if (!port || !port->priv) + return MMAL_EINVAL; + + LOG_TRACE("%s(%i:%i) port %p", port->component->name, + (int)port->type, (int)port->index, port); + + if (!port->priv->pf_disable) + return MMAL_ENOSYS; + + core = port->priv->core; + LOCK_CONNECTION(port); + connected_port = core->connected_port; + + /* Sanity checking */ + if (!port->is_enabled) + { + UNLOCK_CONNECTION(port); + LOG_ERROR("port %s(%p) is not enabled", port->name, port); + return MMAL_EINVAL; + } + + if (connected_port) + LOCK_CONNECTION(connected_port); + + /* Disable the output port of a connection first */ + if (connected_port && connected_port->type != MMAL_PORT_TYPE_INPUT) + { + status = mmal_port_disable_internal(connected_port); + if (status != MMAL_SUCCESS) + { + LOG_ERROR("failed to disable connected port (%s)%p (%s)", connected_port->name, + connected_port, mmal_status_to_string(status)); + goto end; + } + } + + status = mmal_port_disable_internal(port); + if (status != MMAL_SUCCESS) + { + LOG_ERROR("failed to disable port (%s)%p", port->name, port); + goto end; + } + + /* Disable the input port of a connection last */ + if (connected_port && connected_port->type == MMAL_PORT_TYPE_INPUT) + { + status = mmal_port_disable_internal(connected_port); + if (status != MMAL_SUCCESS) + { + LOG_ERROR("failed to disable connected port (%s)%p (%s)", connected_port->name, + connected_port, mmal_status_to_string(status)); + goto end; + } + } + + if (connected_port) + { + status = mmal_port_connection_disable(port, connected_port); + if (status != MMAL_SUCCESS) + LOG_ERROR("failed to disable connection (%s)%p (%s)", port->name, + port, mmal_status_to_string(status)); + } + +end: + if (connected_port) + UNLOCK_CONNECTION(connected_port); + UNLOCK_CONNECTION(port); + + return status; +} + +static MMAL_STATUS_T mmal_port_disable_internal(MMAL_PORT_T *port) +{ + MMAL_PORT_PRIVATE_CORE_T* core = port->priv->core; + MMAL_STATUS_T status = MMAL_SUCCESS; + MMAL_BUFFER_HEADER_T *buffer; + + LOCK_PORT(port); + + if (!port->is_enabled) + goto end; + + LOCK_SENDING(port); + port->is_enabled = 0; + UNLOCK_SENDING(port); + + mmal_component_action_lock(port->component); + + if (core->pool_for_connection) + mmal_pool_callback_set(core->pool_for_connection, NULL, NULL); + + status = port->priv->pf_disable(port); + + mmal_component_action_unlock(port->component); + + if (status != MMAL_SUCCESS) + { + LOG_ERROR("port %p could not be disabled (%s)", port->name, mmal_status_to_string(status)); + LOCK_SENDING(port); + port->is_enabled = 1; + UNLOCK_SENDING(port); + goto end; + } + + /* Flush our internal queue */ + buffer = port->priv->core->queue_first; + while (buffer) + { + MMAL_BUFFER_HEADER_T *next = buffer->next; + mmal_port_buffer_header_callback(port, buffer); + buffer = next; + } + port->priv->core->queue_first = 0; + port->priv->core->queue_last = &port->priv->core->queue_first; + + /* Wait for all the buffers to have come back from the component */ + LOG_DEBUG("%s waiting for %i buffers left in transit", port->name, (int)IN_TRANSIT_COUNT(port)); + IN_TRANSIT_WAIT(port); + LOG_DEBUG("%s has no buffers left in transit", port->name); + + port->priv->core->buffer_header_callback = NULL; + + end: + UNLOCK_PORT(port); + return status; +} + +/** Send a buffer header to a port */ +MMAL_STATUS_T mmal_port_send_buffer(MMAL_PORT_T *port, + MMAL_BUFFER_HEADER_T *buffer) +{ + MMAL_STATUS_T status = MMAL_SUCCESS; + + if (!port || !port->priv) + { + LOG_ERROR("invalid port"); + return MMAL_EINVAL; + } + +#ifdef ENABLE_MMAL_EXTRA_LOGGING + LOG_TRACE("%s(%i:%i) port %p, buffer %p (%p,%i,%i)", + port->component->name, (int)port->type, (int)port->index, port, buffer, + buffer ? buffer->data: 0, buffer ? (int)buffer->offset : 0, + buffer ? (int)buffer->length : 0); +#endif + + if (!buffer->data && !(port->capabilities & MMAL_PORT_CAPABILITY_PASSTHROUGH)) + { + LOG_ERROR("%s(%p) received invalid buffer header", port->name, port); + return MMAL_EINVAL; + } + + if (!port->priv->pf_send) + return MMAL_ENOSYS; + + LOCK_SENDING(port); + + if (!port->is_enabled) + { + UNLOCK_SENDING(port); + return MMAL_EINVAL; + } + + if (port->type == MMAL_PORT_TYPE_OUTPUT && buffer->length) + { + LOG_DEBUG("given an output buffer with length != 0"); + buffer->length = 0; + } + + /* coverity[lock] transit_sema is used for signalling, and is not a lock */ + /* coverity[lock_order] since transit_sema is not a lock, there is no ordering conflict */ + IN_TRANSIT_INCREMENT(port); + + if (port->priv->core->is_paused) + { + /* Add buffer to our internal queue */ + buffer->next = NULL; + *port->priv->core->queue_last = buffer; + port->priv->core->queue_last = &buffer->next; + } + else + { + /* Send buffer to component */ + status = port->priv->pf_send(port, buffer); + } + + if (status != MMAL_SUCCESS) + { + IN_TRANSIT_DECREMENT(port); + LOG_ERROR("%s: send failed: %s", port->name, mmal_status_to_string(status)); + } + else + { + mmal_port_update_port_stats(port, MMAL_CORE_STATS_RX); + } + + UNLOCK_SENDING(port); + return status; +} + +/** Flush a port */ +MMAL_STATUS_T mmal_port_flush(MMAL_PORT_T *port) +{ + MMAL_BUFFER_HEADER_T *buffer = 0; + MMAL_STATUS_T status; + + if (!port || !port->priv) + return MMAL_EINVAL; + + LOG_TRACE("%s(%i:%i) port %p", port->component->name, + (int)port->type, (int)port->index, port); + + if (!port->priv->pf_flush) + return MMAL_ENOSYS; + + /* N.B. must take action lock *before* sending lock */ + mmal_component_action_lock(port->component); + LOCK_SENDING(port); + + if (!port->is_enabled) + { + UNLOCK_SENDING(port); + mmal_component_action_unlock(port->component); + return MMAL_SUCCESS; + } + + status = port->priv->pf_flush(port); + if (status == MMAL_SUCCESS) + { + /* Flush our internal queue */ + buffer = port->priv->core->queue_first; + port->priv->core->queue_first = 0; + port->priv->core->queue_last = &port->priv->core->queue_first; + } + + UNLOCK_SENDING(port); + mmal_component_action_unlock(port->component); + + while (buffer) + { + MMAL_BUFFER_HEADER_T *next = buffer->next; + mmal_port_buffer_header_callback(port, buffer); + buffer = next; + } + return status; +} + +/* Set a parameter on a port. */ +MMAL_STATUS_T mmal_port_parameter_set(MMAL_PORT_T *port, + const MMAL_PARAMETER_HEADER_T *param) +{ + MMAL_STATUS_T status = MMAL_ENOSYS; + + if (!port) + { + LOG_ERROR("no port"); + return MMAL_EINVAL; + } + if (!param) + { + LOG_ERROR("param not supplied"); + return MMAL_EINVAL; + } + if (!port->priv) + { + LOG_ERROR("port not configured"); + return MMAL_EINVAL; + } + + LOG_TRACE("%s(%i:%i) port %p, param %p (%x,%i)", port->component->name, + (int)port->type, (int)port->index, port, + param, param ? param->id : 0, param ? (int)param->size : 0); + + LOCK_PORT(port); + if (port->priv->pf_parameter_set) + status = port->priv->pf_parameter_set(port, param); + if (status == MMAL_ENOSYS) + { + /* is this a core parameter? */ + status = mmal_port_private_parameter_set(port, param); + } + UNLOCK_PORT(port); + return status; +} + +/* Get a port parameter */ +MMAL_STATUS_T mmal_port_parameter_get(MMAL_PORT_T *port, + MMAL_PARAMETER_HEADER_T *param) +{ + MMAL_STATUS_T status = MMAL_ENOSYS; + + if (!port || !port->priv) + return MMAL_EINVAL; + + LOG_TRACE("%s(%i:%i) port %p, param %p (%x,%i)", port->component->name, + (int)port->type, (int)port->index, port, + param, param ? param->id : 0, param ? (int)param->size : 0); + + if (!param) + return MMAL_EINVAL; + + LOCK_PORT(port); + if (port->priv->pf_parameter_get) + status = port->priv->pf_parameter_get(port, param); + if (status == MMAL_ENOSYS) + { + /* is this a core parameter? */ + status = mmal_port_private_parameter_get(port, param); + } + + UNLOCK_PORT(port); + return status; +} + +/** Buffer header callback. */ +void mmal_port_buffer_header_callback(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) +{ +#ifdef ENABLE_MMAL_EXTRA_LOGGING + LOG_TRACE("%s(%i:%i) port %p, buffer %p (%i,%p,%i,%i)", + port->component->name, (int)port->type, (int)port->index, port, buffer, + buffer ? (int)buffer->cmd : 0, buffer ? buffer->data : 0, + buffer ? (int)buffer->offset : 0, buffer ? (int)buffer->length : 0); +#endif + + if (!vcos_verify(IN_TRANSIT_COUNT(port) >= 0)) + LOG_ERROR("%s: buffer headers in transit < 0 (%d)", port->name, (int)IN_TRANSIT_COUNT(port)); + + if (MMAL_COLLECT_PORT_STATS_ENABLED) + { + mmal_port_update_port_stats(port, MMAL_CORE_STATS_TX); + } + + port->priv->core->buffer_header_callback(port, buffer); + + IN_TRANSIT_DECREMENT(port); +} + +/** Event callback */ +void mmal_port_event_send(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) +{ + if (port->priv->core->buffer_header_callback) + { + port->priv->core->buffer_header_callback(port, buffer); + } + else + { + LOG_ERROR("event lost on port %i,%i (buffer header callback not defined)", + (int)port->type, (int)port->index); + mmal_buffer_header_release(buffer); + } +} + +/** Connect an output port to an input port. */ +MMAL_STATUS_T mmal_port_connect(MMAL_PORT_T *port, MMAL_PORT_T *other_port) +{ + MMAL_PORT_PRIVATE_CORE_T* core; + MMAL_PORT_PRIVATE_CORE_T* other_core; + MMAL_STATUS_T status = MMAL_SUCCESS; + MMAL_PORT_T* output_port = NULL; + + if (!port || !port->priv || !other_port || !other_port->priv) + { + LOG_ERROR("invalid port"); + return MMAL_EINVAL; + } + + if ((port->type == MMAL_PORT_TYPE_CLOCK) && (port->type != other_port->type)) + { + LOG_ERROR("invalid port connection"); + return MMAL_EINVAL; + } + + LOG_TRACE("connecting %s(%p) to %s(%p)", port->name, port, other_port->name, other_port); + + if (!port->priv->pf_connect || !other_port->priv->pf_connect) + { + LOG_ERROR("at least one pf_connect is NULL"); + return MMAL_ENOSYS; + } + + core = port->priv->core; + other_core = other_port->priv->core; + + LOCK_CONNECTION(port); + if (core->connected_port) + { + LOG_ERROR("port %p is already connected", port); + UNLOCK_CONNECTION(port); + return MMAL_EISCONN; + } + if (port->is_enabled) + { + LOG_ERROR("port %p should not be enabled", port); + UNLOCK_CONNECTION(port); + return MMAL_EINVAL; + } + + LOCK_CONNECTION(other_port); + if (other_core->connected_port) + { + LOG_ERROR("port %p is already connected", other_port); + status = MMAL_EISCONN; + goto finish; + } + if (other_port->is_enabled) + { + LOG_ERROR("port %p should not be enabled", other_port); + status = MMAL_EINVAL; + goto finish; + } + + core->connected_port = other_port; + other_core->connected_port = port; + + core->core_owns_connection = 0; + other_core->core_owns_connection = 0; + + /* Check to see if the port will manage the connection on its own. If not then the core + * will manage it. */ + output_port = port->type == MMAL_PORT_TYPE_OUTPUT ? port : other_port; + if (output_port->priv->pf_connect(port, other_port) == MMAL_SUCCESS) + goto finish; + + core->core_owns_connection = 1; + other_core->core_owns_connection = 1; + + +finish: + UNLOCK_CONNECTION(other_port); + UNLOCK_CONNECTION(port); + return status; +} + +/** Disconnect a connected port. */ +MMAL_STATUS_T mmal_port_disconnect(MMAL_PORT_T *port) +{ + MMAL_PORT_PRIVATE_CORE_T* core; + MMAL_PORT_T* other_port; + MMAL_STATUS_T status = MMAL_SUCCESS; + + if (!port || !port->priv) + { + LOG_ERROR("invalid port"); + return MMAL_EINVAL; + } + + LOG_TRACE("%s(%p)", port->name, port); + + LOCK_CONNECTION(port); + + core = port->priv->core; + other_port = core->connected_port; + + if (!other_port) + { + UNLOCK_CONNECTION(port); + LOG_DEBUG("%s(%p) is not connected", port->name, port); + return MMAL_ENOTCONN; + } + + LOCK_CONNECTION(other_port); + + /* Make sure the connection is disabled first */ + if (port->is_enabled) + { + MMAL_PORT_T *output = port->type == MMAL_PORT_TYPE_OUTPUT ? port : other_port; + MMAL_PORT_T *input = other_port->type == MMAL_PORT_TYPE_INPUT ? other_port : port; + + status = mmal_port_disable_internal(output); + if (status != MMAL_SUCCESS) + { + LOG_ERROR("failed to disable port (%s)%p", port->name, port); + goto end; + } + status = mmal_port_disable_internal(input); + if (status != MMAL_SUCCESS) + { + LOG_ERROR("failed to disable port (%s)%p", port->name, port); + goto end; + } + status = mmal_port_connection_disable(port, other_port); + } + + if (!core->core_owns_connection) + { + status = port->priv->pf_connect(port, NULL); + if (status != MMAL_SUCCESS) + { + LOG_ERROR("disconnection of %s(%p) failed (%i)", port->name, port, status); + goto end; + } + } + + core->connected_port = NULL; + other_port->priv->core->connected_port = NULL; + +end: + UNLOCK_CONNECTION(other_port); + UNLOCK_CONNECTION(port); + return status; +} + +/** Allocate a payload buffer */ +uint8_t *mmal_port_payload_alloc(MMAL_PORT_T *port, uint32_t payload_size) +{ + uint8_t *mem; + + if (!port || !port->priv) + return NULL; + + LOG_TRACE("%s(%i:%i) port %p, size %i", port->component->name, + (int)port->type, (int)port->index, port, (int)payload_size); + + if (!payload_size) + return NULL; + + /* TODO: keep track of the allocs so we can free them when the component is destroyed */ + + if (!port->priv->pf_payload_alloc) + { + /* Revert to using the heap */ +#ifdef _VIDEOCORE + mem = (void *)mem_alloc(payload_size, 32, MEM_FLAG_DIRECT, port->name); +#else + mem = vcos_malloc(payload_size, "mmal payload"); +#endif + goto end; + } + + LOCK_PORT(port); + mem = port->priv->pf_payload_alloc(port, payload_size); + UNLOCK_PORT(port); + + end: + /* Acquire the port if the allocation was successful. + * This will ensure that the component is not destroyed until the payload has been freed. */ + if (mem) + mmal_port_acquire(port); + return mem; +} + +/** Free a payload buffer */ +void mmal_port_payload_free(MMAL_PORT_T *port, uint8_t *payload) +{ + if (!port || !port->priv) + return; + + LOG_TRACE("%s(%i:%i) port %p, payload %p", port->component->name, + (int)port->type, (int)port->index, port, payload); + + if (!port->priv->pf_payload_alloc) + { + /* Revert to using the heap */ +#ifdef _VIDEOCORE + mem_release((MEM_HANDLE_T)payload); +#else + vcos_free(payload); +#endif + mmal_port_release(port); + return; + } + + LOCK_PORT(port); + port->priv->pf_payload_free(port, payload); + UNLOCK_PORT(port); + mmal_port_release(port); +} + +MMAL_STATUS_T mmal_port_event_get(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T **buffer, uint32_t event) +{ + if (!port || !port->priv || !buffer) + return MMAL_EINVAL; + + LOG_TRACE("%s(%i:%i) port %p, event %4.4s", port->component->name, + (int)port->type, (int)port->index, port, (char *)&event); + + /* Get an event buffer from our event pool */ + *buffer = mmal_queue_get(port->component->priv->event_pool->queue); + if (!*buffer) + { + LOG_ERROR("%s(%i:%i) port %p, no event buffer left for %4.4s", port->component->name, + (int)port->type, (int)port->index, port, (char *)&event); + return MMAL_ENOSPC; + } + + (*buffer)->cmd = event; + (*buffer)->length = 0; + + /* Special case for the FORMAT_CHANGED event. We need to properly initialise the event + * buffer so that it contains an initialised MMAL_ES_FORMAT_T structure. */ + if (event == MMAL_EVENT_FORMAT_CHANGED) + { + uint32_t size = sizeof(MMAL_EVENT_FORMAT_CHANGED_T); + size += sizeof(MMAL_ES_FORMAT_T) + sizeof(MMAL_ES_SPECIFIC_FORMAT_T); + + if ((*buffer)->alloc_size < size) + { + LOG_ERROR("%s(%i:%i) port %p, event buffer for %4.4s is too small (%i/%i)", + port->component->name, (int)port->type, (int)port->index, port, + (char *)&event, (int)(*buffer)->alloc_size, (int)size); + goto error; + } + + memset((*buffer)->data, 0, size); + (*buffer)->length = size; + } + + return MMAL_SUCCESS; + +error: + if (*buffer) + mmal_buffer_header_release(*buffer); + *buffer = NULL; + return MMAL_ENOSPC; +} + +/** Populate clock ports from the given pool */ +static MMAL_STATUS_T mmal_port_populate_clock_ports(MMAL_PORT_T* output, MMAL_PORT_T* input, MMAL_POOL_T* pool) +{ + MMAL_STATUS_T status = MMAL_SUCCESS; + MMAL_BUFFER_HEADER_T *buffer; + + if (!output->priv->pf_send || !input->priv->pf_send) + return MMAL_ENOSYS; + + LOG_TRACE("output %s %p, input %s %p, pool: %p", output->name, output, input->name, input, pool); + + buffer = mmal_queue_get(pool->queue); + while (buffer) + { + status = mmal_port_send_buffer(output, buffer); + if (status != MMAL_SUCCESS) + { + LOG_ERROR("failed to send buffer to clock port %s", output->name); + mmal_buffer_header_release(buffer); + break; + } + + buffer = mmal_queue_get(pool->queue); + if (buffer) + { + status = mmal_port_send_buffer(input, buffer); + if (status != MMAL_SUCCESS) + { + LOG_ERROR("failed to send buffer to clock port %s", output->name); + mmal_buffer_header_release(buffer); + break; + } + buffer = mmal_queue_get(pool->queue); + } + } + + return status; +} + +/** Populate an output port with a pool of buffers */ +static MMAL_STATUS_T mmal_port_populate_from_pool(MMAL_PORT_T* port, MMAL_POOL_T* pool) +{ + MMAL_STATUS_T status = MMAL_SUCCESS; + uint32_t buffer_idx; + MMAL_BUFFER_HEADER_T *buffer; + + if (!port->priv->pf_send) + return MMAL_ENOSYS; + + LOG_TRACE("%s port %p, pool: %p", port->name, port, pool); + + /* Populate port from pool */ + for (buffer_idx = 0; buffer_idx < port->buffer_num; buffer_idx++) + { + buffer = mmal_queue_get(pool->queue); + if (!buffer) + { + LOG_ERROR("too few buffers in the pool"); + status = MMAL_ENOMEM; + break; + } + + status = mmal_port_send_buffer(port, buffer); + if (status != MMAL_SUCCESS) + { + LOG_ERROR("failed to send buffer to port"); + mmal_buffer_header_release(buffer); + break; + } + } + + return status; +} + +/** Default behaviour when setting up or tearing down a connection to another port */ +static MMAL_STATUS_T mmal_port_connect_default(MMAL_PORT_T *port, MMAL_PORT_T *other_port) +{ + MMAL_PARAM_UNUSED(port); + MMAL_PARAM_UNUSED(other_port); + + LOG_TRACE("port %p, other_port %p", port, other_port); + return MMAL_ENOSYS; +} + +/** Connected input port buffer callback */ +static void mmal_port_connected_input_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) +{ + LOG_TRACE("buffer %p from connected input port %p: data %p, alloc_size %u, length %u", + buffer, port, buffer->data, buffer->alloc_size, buffer->length); + + /* Clock ports are bi-directional and a buffer coming from an "input" + * clock port can potentially have valid payload data, in which case + * it should be sent directly to the connected port. */ + if (port->type == MMAL_PORT_TYPE_CLOCK && buffer->length) + { + MMAL_PORT_T* connected_port = port->priv->core->connected_port; + mmal_port_send_buffer(connected_port, buffer); + return; + } + + /* Simply release buffer back into pool for re-use */ + mmal_buffer_header_release(buffer); +} + +/** Connected output port buffer callback */ +static void mmal_port_connected_output_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) +{ + MMAL_PORT_T* connected_port = port->priv->core->connected_port; + MMAL_STATUS_T status; + + LOG_TRACE("buffer %p from connected output port %p: data %p, alloc_size %u, length %u", + buffer, port, buffer->data, buffer->alloc_size, buffer->length); + + if (buffer->cmd) + { + MMAL_EVENT_FORMAT_CHANGED_T *event = mmal_event_format_changed_get(buffer); + + /* Handle format changed events */ + if (event) + { + /* Apply the change */ + status = mmal_format_full_copy(port->format, event->format); + if (status == MMAL_SUCCESS) + status = mmal_port_format_commit(port); + if (status != MMAL_SUCCESS) + LOG_ERROR("format commit failed on port %s (%i)", port->name, status); + + /* Forward to the connected port */ + if (status == MMAL_SUCCESS) + status = mmal_port_send_buffer(connected_port, buffer); + + if (status != MMAL_SUCCESS) + { + mmal_event_error_send(port->component, status); + mmal_buffer_header_release(buffer); + } + return; /* Event handled */ + } + + /* FIXME Release other event buffers for now, until we can deal with shared memory issues */ + mmal_buffer_header_release(buffer); + } + else + { + if (port->is_enabled) + { + /* Forward data buffers to the connected input port */ + status = mmal_port_send_buffer(connected_port, buffer); + if (status != MMAL_SUCCESS) + { + LOG_ERROR("%s could not send buffer on port %s (%s)", + port->name, connected_port->name, mmal_status_to_string(status)); + mmal_buffer_header_release(buffer); + } + } + else + { + /* This port is disabled. Buffer will be a flushed buffer, so + * return to the pool rather than delivering it. + */ + mmal_buffer_header_release(buffer); + } + } +} + +/** Callback for when a buffer from a connected input port is finally released */ +static MMAL_BOOL_T mmal_port_connected_pool_cb(MMAL_POOL_T *pool, MMAL_BUFFER_HEADER_T *buffer, void *userdata) +{ + MMAL_PORT_T* port = (MMAL_PORT_T*)userdata; + MMAL_STATUS_T status; + MMAL_PARAM_UNUSED(pool); + + LOG_TRACE("released buffer %p, data %p alloc_size %u length %u", + buffer, buffer->data, buffer->alloc_size, buffer->length); + + /* Pipe the buffer back to the output port */ + status = mmal_port_send_buffer(port, buffer); + + /* Put the buffer back in the pool if we were successful */ + return status != MMAL_SUCCESS; +} + +/*****************************************************************************/ +static void mmal_port_name_update(MMAL_PORT_T *port) +{ + MMAL_PORT_PRIVATE_CORE_T* core = port->priv->core; + + vcos_snprintf(core->name, core->name_size - 1, PORT_NAME_FORMAT, + port->component->name, mmal_port_type_to_string(port->type), (int)port->index, + port->format && port->format->encoding ? '(' : '\0', + port->format && port->format->encoding ? (char *)&port->format->encoding : ""); +} + +static MMAL_STATUS_T mmal_port_get_core_stats(MMAL_PORT_T *port, MMAL_PARAMETER_HEADER_T *param) +{ + MMAL_PARAMETER_CORE_STATISTICS_T *stats_param = (MMAL_PARAMETER_CORE_STATISTICS_T*)param; + MMAL_CORE_STATISTICS_T *stats = &stats_param->stats; + MMAL_CORE_STATISTICS_T *src_stats; + MMAL_PORT_PRIVATE_CORE_T *core = port->priv->core; + vcos_mutex_lock(&core->stats_lock); + switch (stats_param->dir) + { + case MMAL_CORE_STATS_RX: + src_stats = &port->priv->core->stats.rx; + break; + default: + src_stats = &port->priv->core->stats.tx; + break; + } + *stats = *src_stats; + if (stats_param->reset) + memset(src_stats, 0, sizeof(*src_stats)); + vcos_mutex_unlock(&core->stats_lock); + return MMAL_SUCCESS; +} + +/** Update the port stats, called per buffer. + * + */ +static void mmal_port_update_port_stats(MMAL_PORT_T *port, MMAL_CORE_STATS_DIR direction) +{ + MMAL_PORT_PRIVATE_CORE_T *core = port->priv->core; + MMAL_CORE_STATISTICS_T *stats; + unsigned stc = vcos_getmicrosecs(); + + vcos_mutex_lock(&core->stats_lock); + + stats = direction == MMAL_CORE_STATS_RX ? &core->stats.rx : &core->stats.tx; + + stats->buffer_count++; + + if (!stats->first_buffer_time) + { + stats->last_buffer_time = stats->first_buffer_time = stc; + } + else + { + stats->max_delay = vcos_max(stats->max_delay, stc-stats->last_buffer_time); + stats->last_buffer_time = stc; + } + vcos_mutex_unlock(&core->stats_lock); +} + +static MMAL_STATUS_T mmal_port_private_parameter_get(MMAL_PORT_T *port, + MMAL_PARAMETER_HEADER_T *param) +{ + switch (param->id) + { + case MMAL_PARAMETER_CORE_STATISTICS: + return mmal_port_get_core_stats(port, param); + default: + return MMAL_ENOSYS; + } +} + +static MMAL_STATUS_T mmal_port_private_parameter_set(MMAL_PORT_T *port, + const MMAL_PARAMETER_HEADER_T *param) +{ + (void)port; + switch (param->id) + { + default: + return MMAL_ENOSYS; + } +} + +MMAL_STATUS_T mmal_port_pause(MMAL_PORT_T *port, MMAL_BOOL_T pause) +{ + MMAL_STATUS_T status = MMAL_SUCCESS; + + LOCK_SENDING(port); + + /* When resuming from pause, we send all our queued buffers to the port */ + if (!pause && port->is_enabled) + { + MMAL_BUFFER_HEADER_T *buffer = port->priv->core->queue_first; + while (buffer) + { + MMAL_BUFFER_HEADER_T *next = buffer->next; + status = port->priv->pf_send(port, buffer); + if (status != MMAL_SUCCESS) + { + buffer->next = next; + break; + } + buffer = next; + } + + /* If for some reason we could not send one of the buffers, we just + * leave all the buffers in our internal queue and return an error. */ + if (status != MMAL_SUCCESS) + { + port->priv->core->queue_first = buffer; + } + else + { + port->priv->core->queue_first = 0; + port->priv->core->queue_last = &port->priv->core->queue_first; + } + } + + if (status == MMAL_SUCCESS) + port->priv->core->is_paused = pause; + + UNLOCK_SENDING(port); + return status; +} + +MMAL_BOOL_T mmal_port_is_connected(MMAL_PORT_T *port) +{ + return !!port->priv->core->connected_port; +} diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/core/mmal_port_clock.c b/external_src/raspicam-0.1.3/dependencies/mmal/core/mmal_port_clock.c new file mode 100644 index 0000000..1eb7d10 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/core/mmal_port_clock.c @@ -0,0 +1,803 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 "mmal_clock.h" +#include "mmal_logging.h" +#include "core/mmal_clock_private.h" +#include "core/mmal_port_private.h" +#include "util/mmal_util.h" + +#ifdef __VIDEOCORE__ +# include "vcfw/rtos/common/rtos_common_mem.h" +#endif + +/** Minimum number of buffers required on a clock port */ +#define MMAL_PORT_CLOCK_BUFFERS_MIN 16 + +/** Private clock port context */ +typedef struct MMAL_PORT_CLOCK_T +{ + MMAL_PORT_CLOCK_EVENT_CB event_cb; /**< callback for notifying the component of clock events */ + MMAL_QUEUE_T *queue; /**< queue for empty buffers sent to the port */ + MMAL_CLOCK_T *clock; /**< clock module for scheduling requests */ + MMAL_BOOL_T is_reference; /**< TRUE -> clock port is a reference, therefore + will forward time updates */ + MMAL_BOOL_T buffer_info_reporting; /**< controls buffer info reporting */ +} MMAL_PORT_CLOCK_T; + +/***************************************************************************** + * Private functions + *****************************************************************************/ +#ifdef __VIDEOCORE__ +/* FIXME: mmal_buffer_header_mem_lock() assumes that payload memory is on the + * relocatable heap when on VC. However that is not always the case. The MMAL + * framework will allocate memory from the normal heap when ports are connected. + * To work around this, override the default behaviour by providing a payload + * allocator for clock ports which always allocates from the relocatable heap. */ +static uint8_t* mmal_port_clock_payload_alloc(MMAL_PORT_T *port, uint32_t payload_size) +{ + int alignment = port->buffer_alignment_min; + uint8_t *mem; + + if (!alignment) + alignment = 32; + vcos_assert((alignment & (alignment-1)) == 0); + + mem = (uint8_t*)mem_alloc(payload_size, alignment, MEM_FLAG_DIRECT, port->name); + if (!mem) + { + LOG_ERROR("could not allocate %u bytes", payload_size); + return NULL; + } + return mem; +} + +static void mmal_port_clock_payload_free(MMAL_PORT_T *port, uint8_t *payload) +{ + MMAL_PARAM_UNUSED(port); + mem_release((MEM_HANDLE_T)payload); +} +#endif + + +/* Callback invoked by the clock module in response to a client request */ +static void mmal_port_clock_request_cb(MMAL_CLOCK_T* clock, int64_t media_time, void *cb_data, MMAL_CLOCK_VOID_FP cb) +{ + MMAL_PORT_CLOCK_REQUEST_CB cb_client = (MMAL_PORT_CLOCK_REQUEST_CB)cb; + + /* Forward to the client */ + cb_client((MMAL_PORT_T*)clock->user_data, media_time, cb_data); +} + +/* Process buffers received from other clock ports */ +static MMAL_STATUS_T mmal_port_clock_process_buffer(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) +{ + MMAL_PORT_CLOCK_T *priv_clock = port->priv->clock; + MMAL_STATUS_T status = MMAL_SUCCESS; + MMAL_CLOCK_EVENT_T event = MMAL_CLOCK_EVENT_INIT(MMAL_CLOCK_EVENT_INVALID); + + if (buffer->length != sizeof(MMAL_CLOCK_EVENT_T)) + { + LOG_ERROR("invalid buffer length %d expected %d", + buffer->length, sizeof(MMAL_CLOCK_EVENT_T)); + return MMAL_EINVAL; + } + + mmal_buffer_header_mem_lock(buffer); + memcpy(&event, buffer->data, sizeof(MMAL_CLOCK_EVENT_T)); + mmal_buffer_header_mem_unlock(buffer); + + if (event.magic != MMAL_CLOCK_EVENT_MAGIC) + { + LOG_ERROR("buffer corrupt (magic %4.4s)", (char*)&event.magic); + buffer->length = 0; + mmal_port_buffer_header_callback(port, buffer); + return MMAL_EINVAL; + } + + LOG_TRACE("port %s id %4.4s", port->name, (char*)&event.id); + + switch (event.id) + { + case MMAL_CLOCK_EVENT_ACTIVE: + status = mmal_clock_active_set(priv_clock->clock, event.data.enable); + break; + case MMAL_CLOCK_EVENT_TIME: + status = mmal_clock_media_time_set(priv_clock->clock, event.data.media_time); + break; + case MMAL_CLOCK_EVENT_SCALE: + status = mmal_clock_scale_set(priv_clock->clock, event.data.scale); + break; + case MMAL_CLOCK_EVENT_UPDATE_THRESHOLD: + status = mmal_clock_update_threshold_set(priv_clock->clock, &event.data.update_threshold); + break; + case MMAL_CLOCK_EVENT_DISCONT_THRESHOLD: + status = mmal_clock_discont_threshold_set(priv_clock->clock, &event.data.discont_threshold); + break; + case MMAL_CLOCK_EVENT_REQUEST_THRESHOLD: + status = mmal_clock_request_threshold_set(priv_clock->clock, &event.data.request_threshold); + break; + case MMAL_CLOCK_EVENT_INPUT_BUFFER_INFO: + case MMAL_CLOCK_EVENT_OUTPUT_BUFFER_INFO: + /* nothing to do - just forward to the client */ + break; + default: + LOG_ERROR("invalid event %4.4s", (char*)&event.id); + status = MMAL_EINVAL; + break; + } + + if (priv_clock->event_cb && status == MMAL_SUCCESS) + { + /* Notify the component, but don't return the buffer */ + event.buffer = buffer; + priv_clock->event_cb(port, &event); + } + else + { + /* Finished with the buffer, so return it */ + buffer->length = 0; + mmal_port_buffer_header_callback(port, buffer); + } + + return status; +} + +static MMAL_STATUS_T mmal_port_clock_send(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) +{ + MMAL_PORT_CLOCK_T *priv_clock = port->priv->clock; + + if (buffer->length) + return mmal_port_clock_process_buffer(port, buffer); + + /* Queue empty buffers to be used later when forwarding clock updates */ + mmal_queue_put(priv_clock->queue, buffer); + + return MMAL_SUCCESS; +} + +static MMAL_STATUS_T mmal_port_clock_flush(MMAL_PORT_T *port) +{ + MMAL_BUFFER_HEADER_T *buffer; + + /* Flush empty buffers */ + buffer = mmal_queue_get(port->priv->clock->queue); + while (buffer) + { + mmal_port_buffer_header_callback(port, buffer); + buffer = mmal_queue_get(port->priv->clock->queue); + } + + return MMAL_SUCCESS; +} + +static MMAL_STATUS_T mmal_port_clock_parameter_set(MMAL_PORT_T *port, const MMAL_PARAMETER_HEADER_T *param) +{ + MMAL_STATUS_T status = MMAL_SUCCESS; + MMAL_CLOCK_EVENT_T event = MMAL_CLOCK_EVENT_INIT(MMAL_CLOCK_EVENT_INVALID); + + switch (param->id) + { + case MMAL_PARAMETER_CLOCK_REFERENCE: + { + const MMAL_PARAMETER_BOOLEAN_T *p = (const MMAL_PARAMETER_BOOLEAN_T*)param; + status = mmal_port_clock_reference_set(port, p->enable); + event.id = MMAL_CLOCK_EVENT_REFERENCE; + event.data.enable = p->enable; + } + break; + case MMAL_PARAMETER_CLOCK_ACTIVE: + { + const MMAL_PARAMETER_BOOLEAN_T *p = (const MMAL_PARAMETER_BOOLEAN_T*)param; + status = mmal_port_clock_active_set(port, p->enable); + event.id = MMAL_CLOCK_EVENT_ACTIVE; + event.data.enable = p->enable; + } + break; + case MMAL_PARAMETER_CLOCK_SCALE: + { + const MMAL_PARAMETER_RATIONAL_T *p = (const MMAL_PARAMETER_RATIONAL_T*)param; + status = mmal_port_clock_scale_set(port, p->value); + event.id = MMAL_CLOCK_EVENT_SCALE; + event.data.scale = p->value; + } + break; + case MMAL_PARAMETER_CLOCK_TIME: + { + const MMAL_PARAMETER_INT64_T *p = (const MMAL_PARAMETER_INT64_T*)param; + status = mmal_port_clock_media_time_set(port, p->value); + event.id = MMAL_CLOCK_EVENT_TIME; + event.data.media_time = p->value; + } + break; + case MMAL_PARAMETER_CLOCK_UPDATE_THRESHOLD: + { + const MMAL_PARAMETER_CLOCK_UPDATE_THRESHOLD_T *p = (const MMAL_PARAMETER_CLOCK_UPDATE_THRESHOLD_T *)param; + status = mmal_port_clock_update_threshold_set(port, &p->value); + event.id = MMAL_CLOCK_EVENT_UPDATE_THRESHOLD; + event.data.update_threshold = p->value; + } + break; + case MMAL_PARAMETER_CLOCK_DISCONT_THRESHOLD: + { + const MMAL_PARAMETER_CLOCK_DISCONT_THRESHOLD_T *p = (const MMAL_PARAMETER_CLOCK_DISCONT_THRESHOLD_T *)param; + status = mmal_port_clock_discont_threshold_set(port, &p->value); + event.id = MMAL_CLOCK_EVENT_DISCONT_THRESHOLD; + event.data.discont_threshold = p->value; + } + break; + case MMAL_PARAMETER_CLOCK_REQUEST_THRESHOLD: + { + const MMAL_PARAMETER_CLOCK_REQUEST_THRESHOLD_T *p = (const MMAL_PARAMETER_CLOCK_REQUEST_THRESHOLD_T *)param; + status = mmal_port_clock_request_threshold_set(port, &p->value); + event.id = MMAL_CLOCK_EVENT_REQUEST_THRESHOLD; + event.data.request_threshold = p->value; + } + break; + case MMAL_PARAMETER_CLOCK_ENABLE_BUFFER_INFO: + { + const MMAL_PARAMETER_BOOLEAN_T *p = (const MMAL_PARAMETER_BOOLEAN_T*)param; + port->priv->clock->buffer_info_reporting = p->enable; + return MMAL_SUCCESS; + } + default: + LOG_ERROR("unsupported clock parameter 0x%x", param->id); + return MMAL_ENOSYS; + } + + /* Notify the component */ + if (port->priv->clock->event_cb && status == MMAL_SUCCESS) + port->priv->clock->event_cb(port, &event); + + return status; +} + +static MMAL_STATUS_T mmal_port_clock_parameter_get(MMAL_PORT_T *port, MMAL_PARAMETER_HEADER_T *param) +{ + MMAL_PORT_CLOCK_T *priv_clock = port->priv->clock; + MMAL_STATUS_T status = MMAL_SUCCESS; + + switch (param->id) + { + case MMAL_PARAMETER_CLOCK_REFERENCE: + { + MMAL_PARAMETER_BOOLEAN_T *p = (MMAL_PARAMETER_BOOLEAN_T*)param; + p->enable = priv_clock->is_reference; + } + break; + case MMAL_PARAMETER_CLOCK_ACTIVE: + { + MMAL_PARAMETER_BOOLEAN_T *p = (MMAL_PARAMETER_BOOLEAN_T*)param; + p->enable = mmal_clock_is_active(priv_clock->clock); + } + break; + case MMAL_PARAMETER_CLOCK_SCALE: + { + MMAL_PARAMETER_RATIONAL_T *p = (MMAL_PARAMETER_RATIONAL_T*)param; + p->value = mmal_clock_scale_get(priv_clock->clock); + } + break; + case MMAL_PARAMETER_CLOCK_TIME: + { + MMAL_PARAMETER_INT64_T *p = (MMAL_PARAMETER_INT64_T*)param; + p->value = mmal_clock_media_time_get(priv_clock->clock); + } + break; + case MMAL_PARAMETER_CLOCK_UPDATE_THRESHOLD: + { + MMAL_PARAMETER_CLOCK_UPDATE_THRESHOLD_T *p = (MMAL_PARAMETER_CLOCK_UPDATE_THRESHOLD_T *)param; + status = mmal_clock_update_threshold_get(priv_clock->clock, &p->value); + } + break; + case MMAL_PARAMETER_CLOCK_DISCONT_THRESHOLD: + { + MMAL_PARAMETER_CLOCK_DISCONT_THRESHOLD_T *p = (MMAL_PARAMETER_CLOCK_DISCONT_THRESHOLD_T *)param; + status = mmal_clock_discont_threshold_get(priv_clock->clock, &p->value); + } + break; + case MMAL_PARAMETER_CLOCK_REQUEST_THRESHOLD: + { + MMAL_PARAMETER_CLOCK_REQUEST_THRESHOLD_T *p = (MMAL_PARAMETER_CLOCK_REQUEST_THRESHOLD_T *)param; + status = mmal_clock_request_threshold_get(priv_clock->clock, &p->value); + } + break; + case MMAL_PARAMETER_CLOCK_ENABLE_BUFFER_INFO: + { + MMAL_PARAMETER_BOOLEAN_T *p = (MMAL_PARAMETER_BOOLEAN_T*)param; + p->enable = priv_clock->buffer_info_reporting; + } + break; + default: + LOG_ERROR("unsupported clock parameter 0x%x", param->id); + return MMAL_ENOSYS; + } + + return status; +} + +static MMAL_STATUS_T mmal_port_clock_enable(MMAL_PORT_T *port, MMAL_PORT_BH_CB_T cb) +{ + MMAL_PARAM_UNUSED(port); + MMAL_PARAM_UNUSED(cb); + return MMAL_SUCCESS; +} + +static MMAL_STATUS_T mmal_port_clock_disable(MMAL_PORT_T *port) +{ + MMAL_PORT_CLOCK_T *priv_clock = port->priv->clock; + + if (mmal_clock_is_active(priv_clock->clock)) + mmal_clock_active_set(priv_clock->clock, MMAL_FALSE); + + mmal_port_clock_flush(port); + + return MMAL_SUCCESS; +} + +static MMAL_STATUS_T mmal_port_clock_set_format(MMAL_PORT_T *port) +{ + MMAL_PARAM_UNUSED(port); + return MMAL_SUCCESS; +} + +static MMAL_STATUS_T mmal_port_clock_connect(MMAL_PORT_T *port, MMAL_PORT_T *other_port) +{ + MMAL_PARAM_UNUSED(port); + MMAL_PARAM_UNUSED(other_port); + return MMAL_ENOSYS; +} + +/* Send an event buffer to a connected port */ +static MMAL_STATUS_T mmal_port_clock_forward_event(MMAL_PORT_T *port, const MMAL_CLOCK_EVENT_T *event) +{ + MMAL_STATUS_T status; + MMAL_BUFFER_HEADER_T *buffer; + + buffer = mmal_queue_get(port->priv->clock->queue); + if (!buffer) + { + LOG_INFO("%s: no free event buffers available for event %4.4s", port->name, (const char*)&event->id); + return MMAL_ENOSPC; + } + + status = mmal_buffer_header_mem_lock(buffer); + if (status != MMAL_SUCCESS) + { + LOG_ERROR("failed to lock buffer %s", mmal_status_to_string(status)); + mmal_queue_put_back(port->priv->clock->queue, buffer); + goto end; + } + buffer->length = sizeof(MMAL_CLOCK_EVENT_T); + memcpy(buffer->data, event, buffer->length); + mmal_buffer_header_mem_unlock(buffer); + + mmal_port_buffer_header_callback(port, buffer); + +end: + return status; +} + +/* Send a clock active state to a connected port */ +static MMAL_STATUS_T mmal_port_clock_forward_active_state(MMAL_PORT_T *port, MMAL_BOOL_T active) +{ + MMAL_CLOCK_EVENT_T event; + + event.id = MMAL_CLOCK_EVENT_ACTIVE; + event.magic = MMAL_CLOCK_EVENT_MAGIC; + event.data.enable = active; + + return mmal_port_clock_forward_event(port, &event); +} + +/* Send a clock scale update to a connected port */ +static MMAL_STATUS_T mmal_port_clock_forward_scale(MMAL_PORT_T *port, MMAL_RATIONAL_T scale) +{ + MMAL_CLOCK_EVENT_T event; + + event.id = MMAL_CLOCK_EVENT_SCALE; + event.magic = MMAL_CLOCK_EVENT_MAGIC; + event.data.scale = scale; + + return mmal_port_clock_forward_event(port, &event); +} + +/* Send a clock time update to a connected port */ +static MMAL_STATUS_T mmal_port_clock_forward_media_time(MMAL_PORT_T *port, int64_t media_time) +{ + MMAL_CLOCK_EVENT_T event; + + event.id = MMAL_CLOCK_EVENT_TIME; + event.magic = MMAL_CLOCK_EVENT_MAGIC; + event.data.media_time = media_time; + + return mmal_port_clock_forward_event(port, &event); +} + +/* Send a clock update threshold to a connected port */ +static MMAL_STATUS_T mmal_port_clock_forward_update_threshold(MMAL_PORT_T *port, + const MMAL_CLOCK_UPDATE_THRESHOLD_T *threshold) +{ + MMAL_CLOCK_EVENT_T event; + + event.id = MMAL_CLOCK_EVENT_UPDATE_THRESHOLD; + event.magic = MMAL_CLOCK_EVENT_MAGIC; + event.data.update_threshold = *threshold; + + return mmal_port_clock_forward_event(port, &event); +} + +/* Send a clock discontinuity threshold to a connected port */ +static MMAL_STATUS_T mmal_port_clock_forward_discont_threshold(MMAL_PORT_T *port, + const MMAL_CLOCK_DISCONT_THRESHOLD_T *threshold) +{ + MMAL_CLOCK_EVENT_T event; + + event.id = MMAL_CLOCK_EVENT_DISCONT_THRESHOLD; + event.magic = MMAL_CLOCK_EVENT_MAGIC; + event.data.discont_threshold = *threshold; + + return mmal_port_clock_forward_event(port, &event); +} + +/* Send a clock request threshold to a connected port */ +static MMAL_STATUS_T mmal_port_clock_forward_request_threshold(MMAL_PORT_T *port, + const MMAL_CLOCK_REQUEST_THRESHOLD_T *threshold) +{ + MMAL_CLOCK_EVENT_T event; + + event.id = MMAL_CLOCK_EVENT_REQUEST_THRESHOLD; + event.magic = MMAL_CLOCK_EVENT_MAGIC; + event.data.request_threshold = *threshold; + + return mmal_port_clock_forward_event(port, &event); +} + +/* Send information regarding an input buffer to connected port */ +static MMAL_STATUS_T mmal_port_clock_forward_input_buffer_info(MMAL_PORT_T *port, const MMAL_CLOCK_BUFFER_INFO_T *info) +{ + MMAL_CLOCK_EVENT_T event; + + event.id = MMAL_CLOCK_EVENT_INPUT_BUFFER_INFO; + event.magic = MMAL_CLOCK_EVENT_MAGIC; + event.data.buffer = *info; + + return mmal_port_clock_forward_event(port, &event); +} + +/* Send information regarding an output buffer to connected port */ +static MMAL_STATUS_T mmal_port_clock_forward_output_buffer_info(MMAL_PORT_T *port, const MMAL_CLOCK_BUFFER_INFO_T *info) +{ + MMAL_CLOCK_EVENT_T event; + + event.id = MMAL_CLOCK_EVENT_OUTPUT_BUFFER_INFO; + event.magic = MMAL_CLOCK_EVENT_MAGIC; + event.data.buffer = *info; + + return mmal_port_clock_forward_event(port, &event); +} + +/* Initialise all callbacks and setup internal resources */ +static MMAL_STATUS_T mmal_port_clock_setup(MMAL_PORT_T *port, unsigned int extra_size, + MMAL_PORT_CLOCK_EVENT_CB event_cb) +{ + MMAL_STATUS_T status; + + port->priv->clock = (MMAL_PORT_CLOCK_T*)((char*)(port->priv->module) + extra_size); + + status = mmal_clock_create(&port->priv->clock->clock); + if (status != MMAL_SUCCESS) + { + LOG_ERROR("failed to create clock module on port %s (%s)", + port->name, mmal_status_to_string(status)); + return status; + } + port->priv->clock->clock->user_data = port; + + port->buffer_size = sizeof(MMAL_CLOCK_EVENT_T); + port->buffer_size_min = sizeof(MMAL_CLOCK_EVENT_T); + port->buffer_num_min = MMAL_PORT_CLOCK_BUFFERS_MIN; + port->buffer_num_recommended = MMAL_PORT_CLOCK_BUFFERS_MIN; + + port->priv->clock->event_cb = event_cb; + port->priv->clock->queue = mmal_queue_create(); + if (!port->priv->clock->queue) + { + mmal_clock_destroy(port->priv->clock->clock); + return MMAL_ENOMEM; + } + + port->priv->pf_set_format = mmal_port_clock_set_format; + port->priv->pf_enable = mmal_port_clock_enable; + port->priv->pf_disable = mmal_port_clock_disable; + port->priv->pf_send = mmal_port_clock_send; + port->priv->pf_flush = mmal_port_clock_flush; + port->priv->pf_parameter_set = mmal_port_clock_parameter_set; + port->priv->pf_parameter_get = mmal_port_clock_parameter_get; + port->priv->pf_connect = mmal_port_clock_connect; +#ifdef __VIDEOCORE__ + port->priv->pf_payload_alloc = mmal_port_clock_payload_alloc; + port->priv->pf_payload_free = mmal_port_clock_payload_free; + port->capabilities = MMAL_PORT_CAPABILITY_ALLOCATION; +#endif + + return status; +} + +/* Release all internal resources */ +static void mmal_port_clock_teardown(MMAL_PORT_T *port) +{ + if (!port) + return; + mmal_queue_destroy(port->priv->clock->queue); + mmal_clock_destroy(port->priv->clock->clock); +} + +/***************************************************************************** + * Public functions + *****************************************************************************/ +/* Allocate a clock port */ +MMAL_PORT_T* mmal_port_clock_alloc(MMAL_COMPONENT_T *component, unsigned int extra_size, + MMAL_PORT_CLOCK_EVENT_CB event_cb) +{ + MMAL_PORT_T *port; + + port = mmal_port_alloc(component, MMAL_PORT_TYPE_CLOCK, + extra_size + sizeof(MMAL_PORT_CLOCK_T)); + if (!port) + return NULL; + + if (mmal_port_clock_setup(port, extra_size, event_cb) != MMAL_SUCCESS) + { + mmal_port_free(port); + return NULL; + } + + return port; +} + +/* Free a clock port */ +void mmal_port_clock_free(MMAL_PORT_T *port) +{ + mmal_port_clock_teardown(port); + mmal_port_free(port); +} + +/* Allocate an array of clock ports */ +MMAL_PORT_T **mmal_ports_clock_alloc(MMAL_COMPONENT_T *component, unsigned int ports_num, + unsigned int extra_size, MMAL_PORT_CLOCK_EVENT_CB event_cb) +{ + unsigned int i; + MMAL_PORT_T **ports; + + ports = mmal_ports_alloc(component, ports_num, MMAL_PORT_TYPE_CLOCK, + extra_size + sizeof(MMAL_PORT_CLOCK_T)); + if (!ports) + return NULL; + + for (i = 0; i < ports_num; i++) + { + if (mmal_port_clock_setup(ports[i], extra_size, event_cb) != MMAL_SUCCESS) + break; + } + + if (i != ports_num) + { + for (ports_num = i, i = 0; i < ports_num; i++) + mmal_port_clock_free(ports[i]); + vcos_free(ports); + return NULL; + } + + return ports; +} + +/* Free an array of clock ports */ +void mmal_ports_clock_free(MMAL_PORT_T **ports, unsigned int ports_num) +{ + unsigned int i; + + for (i = 0; i < ports_num; i++) + mmal_port_clock_free(ports[i]); + vcos_free(ports); +} + +/* Register a callback request */ +MMAL_STATUS_T mmal_port_clock_request_add(MMAL_PORT_T *port, int64_t media_time, + MMAL_PORT_CLOCK_REQUEST_CB cb, void *cb_data) +{ + return mmal_clock_request_add(port->priv->clock->clock, media_time, + mmal_port_clock_request_cb, cb_data, (MMAL_CLOCK_VOID_FP)cb); +} + +/* Flush all pending clock requests */ +MMAL_STATUS_T mmal_port_clock_request_flush(MMAL_PORT_T *port) +{ + return mmal_clock_request_flush(port->priv->clock->clock); +} + +/* Set the clock port's reference state */ +MMAL_STATUS_T mmal_port_clock_reference_set(MMAL_PORT_T *port, MMAL_BOOL_T reference) +{ + port->priv->clock->is_reference = reference; + return MMAL_SUCCESS; +} + +/* Get the clock port's reference state */ +MMAL_BOOL_T mmal_port_clock_reference_get(MMAL_PORT_T *port) +{ + return port->priv->clock->is_reference; +} + +/* Set the clock port's active state */ +MMAL_STATUS_T mmal_port_clock_active_set(MMAL_PORT_T *port, MMAL_BOOL_T active) +{ + MMAL_STATUS_T status; + + status = mmal_clock_active_set(port->priv->clock->clock, active); + if (status != MMAL_SUCCESS) + return status; + + if (port->priv->clock->is_reference) + status = mmal_port_clock_forward_active_state(port, active); + + return status; +} + +/* Get the clock port's active state */ +MMAL_BOOL_T mmal_port_clock_active_get(MMAL_PORT_T *port) +{ + return mmal_clock_is_active(port->priv->clock->clock); +} + +/* Set the clock port's scale */ +MMAL_STATUS_T mmal_port_clock_scale_set(MMAL_PORT_T *port, MMAL_RATIONAL_T scale) +{ + MMAL_STATUS_T status; + + status = mmal_clock_scale_set(port->priv->clock->clock, scale); + if (status != MMAL_SUCCESS) + return status; + + if (port->priv->clock->is_reference) + status = mmal_port_clock_forward_scale(port, scale); + + return status; +} + +/* Get the clock port's scale */ +MMAL_RATIONAL_T mmal_port_clock_scale_get(MMAL_PORT_T *port) +{ + return mmal_clock_scale_get(port->priv->clock->clock); +} + +/* Set the clock port's media-time */ +MMAL_STATUS_T mmal_port_clock_media_time_set(MMAL_PORT_T *port, int64_t media_time) +{ + MMAL_STATUS_T status; + + status = mmal_clock_media_time_set(port->priv->clock->clock, media_time); + if (status != MMAL_SUCCESS) + { + LOG_DEBUG("clock media-time update ignored"); + return status; + } + + if (port->priv->clock->is_reference) + status = mmal_port_clock_forward_media_time(port, media_time); + + return status; +} + +/* Get the clock port's media-time */ +int64_t mmal_port_clock_media_time_get(MMAL_PORT_T *port) +{ + return mmal_clock_media_time_get(port->priv->clock->clock); +} + +/* Set the clock port's update threshold */ +MMAL_STATUS_T mmal_port_clock_update_threshold_set(MMAL_PORT_T *port, + const MMAL_CLOCK_UPDATE_THRESHOLD_T *threshold) +{ + MMAL_STATUS_T status; + + status = mmal_clock_update_threshold_set(port->priv->clock->clock, threshold); + if (status != MMAL_SUCCESS) + return status; + + if (port->priv->clock->is_reference) + status = mmal_port_clock_forward_update_threshold(port, threshold); + + return status; +} + +/* Get the clock port's update threshold */ +MMAL_STATUS_T mmal_port_clock_update_threshold_get(MMAL_PORT_T *port, + MMAL_CLOCK_UPDATE_THRESHOLD_T *threshold) +{ + return mmal_clock_update_threshold_get(port->priv->clock->clock, threshold); +} + +/* Set the clock port's discontinuity threshold */ +MMAL_STATUS_T mmal_port_clock_discont_threshold_set(MMAL_PORT_T *port, + const MMAL_CLOCK_DISCONT_THRESHOLD_T *threshold) +{ + MMAL_STATUS_T status; + + status = mmal_clock_discont_threshold_set(port->priv->clock->clock, threshold); + if (status != MMAL_SUCCESS) + return status; + + if (port->priv->clock->is_reference) + status = mmal_port_clock_forward_discont_threshold(port, threshold); + + return status; +} + +/* Get the clock port's discontinuity threshold */ +MMAL_STATUS_T mmal_port_clock_discont_threshold_get(MMAL_PORT_T *port, + MMAL_CLOCK_DISCONT_THRESHOLD_T *threshold) +{ + return mmal_clock_discont_threshold_get(port->priv->clock->clock, threshold); +} + +/* Set the clock port's request threshold */ +MMAL_STATUS_T mmal_port_clock_request_threshold_set(MMAL_PORT_T *port, + const MMAL_CLOCK_REQUEST_THRESHOLD_T *threshold) +{ + MMAL_STATUS_T status; + + status = mmal_clock_request_threshold_set(port->priv->clock->clock, threshold); + if (status != MMAL_SUCCESS) + return status; + + if (port->priv->clock->is_reference) + status = mmal_port_clock_forward_request_threshold(port, threshold); + + return status; +} + +/* Get the clock port's request threshold */ +MMAL_STATUS_T mmal_port_clock_request_threshold_get(MMAL_PORT_T *port, + MMAL_CLOCK_REQUEST_THRESHOLD_T *threshold) +{ + return mmal_clock_request_threshold_get(port->priv->clock->clock, threshold); +} + +/* Provide input buffer information */ +void mmal_port_clock_input_buffer_info(MMAL_PORT_T *port, const MMAL_CLOCK_BUFFER_INFO_T *info) +{ + if (port->priv->clock->buffer_info_reporting) + mmal_port_clock_forward_input_buffer_info(port, info); +} + +/* Provide output buffer information */ +void mmal_port_clock_output_buffer_info(MMAL_PORT_T *port, const MMAL_CLOCK_BUFFER_INFO_T *info) +{ + if (port->priv->clock->buffer_info_reporting) + mmal_port_clock_forward_output_buffer_info(port, info); +} + diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/core/mmal_port_private.h b/external_src/raspicam-0.1.3/dependencies/mmal/core/mmal_port_private.h new file mode 100644 index 0000000..1e538c5 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/core/mmal_port_private.h @@ -0,0 +1,213 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 MMAL_PORT_PRIVATE_H +#define MMAL_PORT_PRIVATE_H + +#include "interface/mmal/mmal.h" +#include "interface/mmal/mmal_clock.h" +#include "interface/mmal/core/mmal_events_private.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** Definition of a port. */ +typedef struct MMAL_PORT_PRIVATE_T +{ + /** Pointer to the private data of the core */ + struct MMAL_PORT_PRIVATE_CORE_T *core; + /** Pointer to the private data of the module in use */ + struct MMAL_PORT_MODULE_T *module; + /** Pointer to the private data used by clock ports */ + struct MMAL_PORT_CLOCK_T *clock; + + MMAL_STATUS_T (*pf_set_format)(MMAL_PORT_T *port); + MMAL_STATUS_T (*pf_enable)(MMAL_PORT_T *port, MMAL_PORT_BH_CB_T); + MMAL_STATUS_T (*pf_disable)(MMAL_PORT_T *port); + MMAL_STATUS_T (*pf_send)(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *); + MMAL_STATUS_T (*pf_flush)(MMAL_PORT_T *port); + MMAL_STATUS_T (*pf_parameter_set)(MMAL_PORT_T *port, const MMAL_PARAMETER_HEADER_T *param); + MMAL_STATUS_T (*pf_parameter_get)(MMAL_PORT_T *port, MMAL_PARAMETER_HEADER_T *param); + MMAL_STATUS_T (*pf_connect)(MMAL_PORT_T *port, MMAL_PORT_T *other_port); + + uint8_t *(*pf_payload_alloc)(MMAL_PORT_T *port, uint32_t payload_size); + void (*pf_payload_free)(MMAL_PORT_T *port, uint8_t *payload); + +} MMAL_PORT_PRIVATE_T; + +/** Callback called by components when a \ref MMAL_BUFFER_HEADER_T needs to be sent back to the + * user */ +void mmal_port_buffer_header_callback(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer); + +/** Callback called by components when an event \ref MMAL_BUFFER_HEADER_T needs to be sent to the + * user. Events differ from ordinary buffer headers because they originate from the component + * and do not return data from the client to the component. */ +void mmal_port_event_send(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer); + +/** Allocate a port structure */ +MMAL_PORT_T *mmal_port_alloc(MMAL_COMPONENT_T *, MMAL_PORT_TYPE_T type, unsigned int extra_size); +/** Free a port structure */ +void mmal_port_free(MMAL_PORT_T *port); +/** Allocate an array of ports */ +MMAL_PORT_T **mmal_ports_alloc(MMAL_COMPONENT_T *, unsigned int ports_num, MMAL_PORT_TYPE_T type, + unsigned int extra_size); +/** Free an array of ports */ +void mmal_ports_free(MMAL_PORT_T **ports, unsigned int ports_num); + +/** Acquire a reference on a port */ +void mmal_port_acquire(MMAL_PORT_T *port); + +/** Release a reference on a port */ +MMAL_STATUS_T mmal_port_release(MMAL_PORT_T *port); + +/** Pause processing on a port */ +MMAL_STATUS_T mmal_port_pause(MMAL_PORT_T *port, MMAL_BOOL_T pause); + +/** Returns whether a port is connected or not */ +MMAL_BOOL_T mmal_port_is_connected(MMAL_PORT_T *port); + +/***************************************************************************** + * Clock Port API + *****************************************************************************/ +/** Definition of a clock port event callback. + * Used to inform the client of a clock event that has occurred. + * + * @param port The clock port where the event occurred + * @param event The event that has occurred + */ +typedef void (*MMAL_PORT_CLOCK_EVENT_CB)(MMAL_PORT_T *port, const MMAL_CLOCK_EVENT_T *event); + +/** Allocate a clock port. + * + * @param component The component requesting the alloc + * @param extra_size Size of the port module + * @param event_cb Clock event callback + * + * @return Pointer to new clock port or NULL on failure. + */ +MMAL_PORT_T* mmal_port_clock_alloc(MMAL_COMPONENT_T *component, unsigned int extra_size, + MMAL_PORT_CLOCK_EVENT_CB event_cb); + +/** Free a clock port. + * + * @param port The clock port to free + */ +void mmal_port_clock_free(MMAL_PORT_T *port); + +/** Allocate an array of clock ports. + * + * @param component The component requesting the alloc + * @param ports_num Number of ports to allocate + * @param extra_size Size of the port module + * @param event_cb Clock event callback + * + * @return Pointer to a new array of clock ports or NULL on failure. + */ +MMAL_PORT_T **mmal_ports_clock_alloc(MMAL_COMPONENT_T *component, unsigned int ports_num, + unsigned int extra_size, MMAL_PORT_CLOCK_EVENT_CB event_cb); + +/** Free an array of clock ports. + * + * @param ports The clock ports to free + * @param ports_num Number of ports to free + */ +void mmal_ports_clock_free(MMAL_PORT_T **ports, unsigned int ports_num); + +/** Definition of a clock port request callback. + * This is invoked when the media-time requested by the client is reached. + * + * @param port The clock port which serviced the request + * @param media_time The current media-time + * @param cb_data Client-supplied data + */ +typedef void (*MMAL_PORT_CLOCK_REQUEST_CB)(MMAL_PORT_T *port, int64_t media_time, void *cb_data); + +/** Register a request with the clock port. + * When the specified media-time is reached, the clock port will invoke the supplied callback. + * + * @param port The clock port + * @param media_time The media-time at which the callback should be invoked (microseconds) + * @param cb Callback to invoke + * @param cb_data Client-supplied callback data + * + * @return MMAL_SUCCESS on success + */ +MMAL_STATUS_T mmal_port_clock_request_add(MMAL_PORT_T *port, int64_t media_time, + MMAL_PORT_CLOCK_REQUEST_CB cb, void *cb_data); + +/** Remove all previously registered clock port requests. + * + * @param port The clock port + * + * @return MMAL_SUCCESS on success + */ +MMAL_STATUS_T mmal_port_clock_request_flush(MMAL_PORT_T *port); + +/** Get/set the clock port's reference state */ +MMAL_STATUS_T mmal_port_clock_reference_set(MMAL_PORT_T *port, MMAL_BOOL_T reference); +MMAL_BOOL_T mmal_port_clock_reference_get(MMAL_PORT_T *port); + +/** Get/set the clock port's active state */ +MMAL_STATUS_T mmal_port_clock_active_set(MMAL_PORT_T *port, MMAL_BOOL_T active); +MMAL_BOOL_T mmal_port_clock_active_get(MMAL_PORT_T *port); + +/** Get/set the clock port's scale */ +MMAL_STATUS_T mmal_port_clock_scale_set(MMAL_PORT_T *port, MMAL_RATIONAL_T scale); +MMAL_RATIONAL_T mmal_port_clock_scale_get(MMAL_PORT_T *port); + +/** Get/set the clock port's media-time */ +MMAL_STATUS_T mmal_port_clock_media_time_set(MMAL_PORT_T *port, int64_t media_time); +int64_t mmal_port_clock_media_time_get(MMAL_PORT_T *port); + +/** Get/set the clock port's update threshold */ +MMAL_STATUS_T mmal_port_clock_update_threshold_set(MMAL_PORT_T *port, + const MMAL_CLOCK_UPDATE_THRESHOLD_T *threshold); +MMAL_STATUS_T mmal_port_clock_update_threshold_get(MMAL_PORT_T *port, + MMAL_CLOCK_UPDATE_THRESHOLD_T *threshold); + +/** Get/set the clock port's discontinuity threshold */ +MMAL_STATUS_T mmal_port_clock_discont_threshold_set(MMAL_PORT_T *port, + const MMAL_CLOCK_DISCONT_THRESHOLD_T *threshold); +MMAL_STATUS_T mmal_port_clock_discont_threshold_get(MMAL_PORT_T *port, + MMAL_CLOCK_DISCONT_THRESHOLD_T *threshold); + +/** Get/set the clock port's request threshold */ +MMAL_STATUS_T mmal_port_clock_request_threshold_set(MMAL_PORT_T *port, + const MMAL_CLOCK_REQUEST_THRESHOLD_T *threshold); +MMAL_STATUS_T mmal_port_clock_request_threshold_get(MMAL_PORT_T *port, + MMAL_CLOCK_REQUEST_THRESHOLD_T *threshold); + +/** Provide information regarding a buffer received on the component's input/output port */ +void mmal_port_clock_input_buffer_info(MMAL_PORT_T *port, const MMAL_CLOCK_BUFFER_INFO_T *info); +void mmal_port_clock_output_buffer_info(MMAL_PORT_T *port, const MMAL_CLOCK_BUFFER_INFO_T *info); + +#ifdef __cplusplus +} +#endif + +#endif /* MMAL_PORT_PRIVATE_H */ diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/core/mmal_queue.c b/external_src/raspicam-0.1.3/dependencies/mmal/core/mmal_queue.c new file mode 100644 index 0000000..ad802cb --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/core/mmal_queue.c @@ -0,0 +1,166 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 "mmal.h" +#include "mmal_queue.h" + +/** Definition of the QUEUE */ +struct MMAL_QUEUE_T +{ + VCOS_MUTEX_T lock; + unsigned int length; + MMAL_BUFFER_HEADER_T *first; + MMAL_BUFFER_HEADER_T **last; + VCOS_SEMAPHORE_T semaphore; +}; + +/** Create a QUEUE of MMAL_BUFFER_HEADER_T */ +MMAL_QUEUE_T *mmal_queue_create(void) +{ + MMAL_QUEUE_T *queue; + + queue = vcos_malloc(sizeof(*queue), "MMAL queue"); + if(!queue) return 0; + + if(vcos_mutex_create(&queue->lock, "MMAL queue lock") != VCOS_SUCCESS ) + { + vcos_free(queue); + return 0; + } + + if(vcos_semaphore_create(&queue->semaphore, "MMAL queue sema", 0) != VCOS_SUCCESS ) + { + vcos_mutex_delete(&queue->lock); + vcos_free(queue); + return 0; + } + + /* gratuitous lock for coverity */ vcos_mutex_lock(&queue->lock); + queue->length = 0; + queue->first = 0; + queue->last = &queue->first; + /* gratuitous unlock for coverity */ vcos_mutex_unlock(&queue->lock); + + return queue; +} + +/** Put a MMAL_BUFFER_HEADER_T into a QUEUE */ +void mmal_queue_put(MMAL_QUEUE_T *queue, MMAL_BUFFER_HEADER_T *buffer) +{ + if(!queue || !buffer) return; + + vcos_mutex_lock(&queue->lock); + queue->length++; + *queue->last = buffer; + buffer->next = 0; + queue->last = &buffer->next; + vcos_semaphore_post(&queue->semaphore); + vcos_mutex_unlock(&queue->lock); +} + +/** Put a MMAL_BUFFER_HEADER_T back at the start of a QUEUE. */ +void mmal_queue_put_back(MMAL_QUEUE_T *queue, MMAL_BUFFER_HEADER_T *buffer) +{ + if(!queue || !buffer) return; + + vcos_mutex_lock(&queue->lock); + queue->length++; + buffer->next = queue->first; + queue->first = buffer; + if(queue->last == &queue->first) queue->last = &buffer->next; + vcos_semaphore_post(&queue->semaphore); + vcos_mutex_unlock(&queue->lock); +} + +/** Get a MMAL_BUFFER_HEADER_T from a QUEUE. */ +MMAL_BUFFER_HEADER_T *mmal_queue_get(MMAL_QUEUE_T *queue) +{ + MMAL_BUFFER_HEADER_T *buffer; + + if(!queue) return 0; + + vcos_mutex_lock(&queue->lock); + buffer = queue->first; + if(!buffer) + { + vcos_mutex_unlock(&queue->lock); + return 0; + } + + /* coverity[lock] This semaphore isn't being used as a mutex */ + vcos_semaphore_wait(&queue->semaphore); /* Will always succeed */ + + queue->first = buffer->next; + if(!queue->first) queue->last = &queue->first; + + queue->length--; + vcos_mutex_unlock(&queue->lock); + + return buffer; +} + +/** Wait for a MMAL_BUFFER_HEADER_T from a QUEUE. */ +MMAL_BUFFER_HEADER_T *mmal_queue_wait(MMAL_QUEUE_T *queue) +{ + if(!queue) return 0; + + vcos_semaphore_wait(&queue->semaphore); + vcos_semaphore_post(&queue->semaphore); + return mmal_queue_get(queue); +} + +MMAL_BUFFER_HEADER_T *mmal_queue_timedwait(MMAL_QUEUE_T *queue, VCOS_UNSIGNED timeout) +{ + int ret = 0; + if (!queue) + return NULL; + + ret = vcos_semaphore_wait_timeout(&queue->semaphore, timeout); + + if (ret != VCOS_SUCCESS) + return NULL; + + vcos_semaphore_post(&queue->semaphore); + return mmal_queue_get(queue); +} + +/** Get the number of MMAL_BUFFER_HEADER_T currently in a QUEUE */ +unsigned int mmal_queue_length(MMAL_QUEUE_T *queue) +{ + if(!queue) return 0; + + return queue->length; +} + +/** Destroy a queue of MMAL_BUFFER_HEADER_T */ +void mmal_queue_destroy(MMAL_QUEUE_T *queue) +{ + if(!queue) return; + vcos_mutex_delete(&queue->lock); + vcos_semaphore_delete(&queue->semaphore); + vcos_free(queue); +} diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/mmal.h b/external_src/raspicam-0.1.3/dependencies/mmal/mmal.h new file mode 100644 index 0000000..e613f94 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/mmal.h @@ -0,0 +1,390 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. +*/ + +/** \file + * Multi-Media Abstraction Layer API + */ + +#ifndef MMAL_H +#define MMAL_H + +/** + * + * \mainpage Multi-Media Abstraction Layer (MMAL). Draft Version 0.1. + * + * \par Contents + * - \ref intro_sec + * - \ref features + * - \ref concepts + * - \ref comp + * - \ref create + * - \ref port + * - \ref buf + * - \ref metadata + * - \ref queue + * - \ref pool + * - \ref param + * - \ref events + * - \ref version + * - \ref example + * + * \section intro_sec Introduction + * + * MMAL (Multi-Media Abstraction Layer) is a framework which is used to provide a host-side, + * simple and relatively low-level interface to multimedia components running on VideoCore. + * It also provides a component interface so that new components can be easily created and + * integrated into the framework. + * + * There is no requirement that all the components be running on VideoCore as MMAL doesn't + * put any restriction on where components live. The current implementation for instance + * provides some components which can be run on both host-side or VideoCore (e.g. the splitter + * component). + * + * \section features Features + * + * The MMAL API has been designed to support all the following features: + * - Sufficiently generic to support different kinds of multimedia component. + * - Simple to use from client side (mostly synchronous except where it matters). + * - Straightforward API for designing components (e.g. avoids multiple data paths, as found in RIL). + * - Allows for fully-optimised implementation of components (e.g. zero-copy buffer passing). + * - Portability (API is self-contained). + * - Supports multiple instances (e.g. of VideoCore). + * - Extensible without breaking source or binary backward compatibility. + * + * \section concepts API concepts + * + * The MMAL API is based on the concept of components, ports and buffer headers. + * Clients create MMAL components which expose ports for each individual + * elementary stream of data they support (e.g. audio/video). Components expose + * input ports to receive data from the client, and expose output ports + * to return data to the client. + * + * Data sent to or received from the component needs to be attached to a buffer header. + * Buffer headers are necessary because they contain buffer specific ancillary data which is + * necessary for the component and client to do their processing (e.g timestamps). + * + * \section comp Components + * + * MMAL lets clients create multi-media components (video encoders, + * video decoders, camera, and so-on) using a common API. Clients exchange + * data with components using buffer headers. A buffer header + * has a pointer to the payload data and optional metadata. + * Buffer headers are sent to and received from ports that are provided by components. + * + * A typical decoder component would have a single input port and a + * single output port, but the same architecture could also be used + * for components with different layouts (e.g. a camera with a + * capture and preview port, or a debugging component with just an input port). + * + * \subsection create Component Creation + * + * Each component is identified by a unique name. To create a specific component + * the client needs to call \ref mmal_component_create with the desired component's + * name as an argument. + * This call will return a context (\ref MMAL_COMPONENT_T) to the component. This + * context will expose the input and output ports (\ref MMAL_PORT_T) supported + * by this specific component. + * + * \note All VideoCore components have a name starting with the "vc." prefix (this prefix + * is used to distinguish when a creation request needs to be forwarded to VideoCore). + * + * \section port Component Ports + * + * A port (\ref MMAL_PORT_T) is the entity which exposes an elementary stream + * (\ref MMAL_ES_FORMAT_T) on a component. It is also the entity to which buffer headers + * (\ref MMAL_BUFFER_HEADER_T) are sent or from which they are received. + * + * Clients do not need to create ports. They are created automatically by + * the component when this one is created but the format of a port might need to + * be set by the client depending on the type of component the client is using. + * + * For example, for a video decoding component, one input port and one output port + * will be available. The format of the input port must be set by the + * client (using \ref mmal_port_format_commit) while the format of the output port + * will be automatically set by the component once the component has enough information + * to find out what its format should be. + * + * If the input port format contains enough information for the component to determine + * the format of the output port straight away, then the output port will be set to the proper + * format when \ref mmal_port_format_commit returns. Otherwise the output format will be set to + * \ref MMAL_ENCODING_UNKNOWN until the component is fed enough data to determine the format + * of the output port. + * When this happens, the client will receive an event on the output port, signalling + * that its format has changed. + * + * \section buf Buffer Headers + * + * Buffer headers (\ref MMAL_BUFFER_HEADER_T) are used to exchange data with components. + * They do not contain the data directly but instead contain a pointer to the data being + * transferred. + * + * Separating the buffer headers from the payload means that the memory for the data can + * be allocated outside of MMAL (e.g. if it is supplied by an external library) while still + * providing a consistent way to exchange data between clients and components. + * + * Buffer headers are allocated from pools and are reference counted. The refcount + * will drop when \ref mmal_buffer_header_release is called and the buffer header + * will be recycled to its pool when it reaches zero. + * The client can be notified when the buffer header is recycled so that it can recycle the + * associated payload memory as well. + * + * A pool of buffer headers should be created after committing the format of the port. When + * the format is changed, the minimum and recommended size and number of buffers may change. + * + * \note The current number of buffers and their size (\ref MMAL_PORT_T::buffer_num and \ref + * MMAL_PORT_T::buffer_size) are not modified by MMAL, and must be updated by the client as + * required after changes to a port's format. + * + * \subsection metadata Buffer Metadata + * + * The API provides a way for clients or components to associate metadata with buffer headers. + * A camera component could for example store information like exposure time or focal length + * as metadata within the buffer header containing the frame just captured. + * \note This area needs more work + * + * \subsection queue Queues of Buffer Headers + * + * Queues (\ref MMAL_QUEUE_T) are a facility that allows thread-safe processing of buffer headers + * from the client. Callbacks triggered by a MMAL component when it sends a buffer header to the + * client can simply put the buffer in a queue and let the main processing thread of the client + * get its data from the queue. + * + * \subsection pool Pools of Buffer Headers + * + * Pools (\ref MMAL_POOL_T) let clients allocate a fixed number of buffer headers, and + * a queue (\ref MMAL_QUEUE_T). They are used for buffer header allocation. + * Optionally a pool can also allocate the payload memory for the client. + * + * Pools can also be resized after creation, for example, if the port format is changed leading + * to a new number or size of buffers being required. + * + * \section param Port Parameters + * + * Components support setting and getting component specific parameters using + * \ref mmal_port_parameter_set and \ref mmal_port_parameter_get. Parameters + * are identified using an integer index; parameter data is binary. See the \ref MMAL_PARAMETER_IDS + * "Pre-defined MMAL parameter IDs" page for more information on the pre-defined parameters. + * + * \section events Port Events + * + * Components can generate events on their ports. Events are sent to clients + * as buffer headers and thus when the client receives a buffer header on one + * of the component's port it should check if the buffer header is an event + * and in which case process it and then release it (\ref mmal_buffer_header_release). + * The reason for transmitting events in-band with the actual data is that it + * is often very valuable to know exactly when the event happens relative to the + * the actual data (e.g. with a focus event, from which video frame are we in focus).\n + * Buffer headers used to transmit events are allocated internally by the framework + * so it is important to release the buffer headers with \ref mmal_buffer_header_release + * so the buffer headers make it back to their actual owner. + * + * Event buffer headers are allocated when the component is created, based on the + * minimum number and size of control port buffers set by the component. Component + * wide events (not port specific) are sent to the control port callback when that + * port is enabled. Port events are sent to the port callback, the same as data + * buffers, but the 'cmd' field is non-zero. + * + * \section version Versioning + * + * The API requires that the MMAL core be the same or more recent version + * as the components and clients. Clients and components can be older and + * the API will still work both at compile-time and run-time. + * + * \section example Example Code + * + * The following code is a simple example on how to do video decoding using MMAL. Note that + * the code is intended to be clear and illustrate how to use MMAL at its most fundamental + * level, not necessarily the most efficient way to achieve the same result. Use of opaque + * images, tunneling and zero-copy inter-processor buffers can all improve the performance + * or reduce the load. + * + * The \ref MmalConnectionUtility "Port Connection Utility" functions can also be used to + * replace much of the common "boilerplate" code, especially when a pipeline of several + * components needs to be processed. + * + * \code + * #include + * ... + * static void input_callback(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) + * { + * // The decoder is done with the data, just recycle the buffer header into its pool + * mmal_buffer_header_release(buffer); + * } + * static void output_callback(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) + * { + * MMAL_QUEUE_T *queue = (MMAL_QUEUE_T *)port->userdata; + * mmal_queue_put(queue, buffer); // Queue the decoded video frame + * } + * ... + * + * MMAL_COMPONENT_T *decoder = 0; + * MMAL_STATUS_T status; + * + * // Create the video decoder component on VideoCore + * status = mmal_component_create("vc.ril.video_decoder", &decoder); + * ABORT_IF_ERROR(status); + * + * // Set format of video decoder input port + * MMAL_ES_FORMAT_T *format_in = decoder->input[0]->format; + * format_in->type = MMAL_ES_TYPE_VIDEO; + * format_in->encoding = MMAL_ENCODING_H264; + * format_in->es->video.width = 1280; + * format_in->es->video.height = 720; + * format_in->es->video.frame_rate.num = 30; + * format_in->es->video.frame_rate.den = 1; + * format_in->es->video.par.num = 1; + * format_in->es->video.par.den = 1; + * format_in->flags = MMAL_ES_FORMAT_FLAG_FRAMED; + * status = mmal_format_extradata_alloc(format_in, YOUR_H264_CODEC_HEADER_BYTES_SIZE); + * ABORT_IF_ERROR(status); + * format_in->extradata_size = YOUR_H264_CODEC_HEADER_BYTES_SIZE; + * memcpy(format_in->extradata, YOUR_H264_CODEC_HEADER_BYTES, format_in->extradata_size); + * + * status = mmal_port_format_commit(decoder->input[0]); + * ABORT_IF_ERROR(status); + * + * // Once the call to mmal_port_format_commit() on the input port returns, the decoder will + * // have set the format of the output port. + * // If the decoder still doesn t have enough information to determine the format of the + * // output port, the encoding will be set to unknown. As soon as the decoder receives + * // enough stream data to determine the format of the output port it will send an event + * // to the client to signal that the format of the port has changed. + * // However, for the sake of simplicity this example assumes that the decoder was given + * // all the necessary information right at the start (i.e. video format and codec header bytes) + * MMAL_FORMAT_T *format_out = decoder->output[0]->format; + * if (format_out->encoding == MMAL_ENCODING_UNKNOWN) + * ABORT(); + * + * // Now we know the format of both ports and the requirements of the decoder, we can create + * // our buffer headers and their associated memory buffers. We use the buffer pool API for this. + * decoder->input[0]->buffer_num = decoder->input[0]->buffer_num_min; + * decoder->input[0]->buffer_size = decoder->input[0]->buffer_size_min; + * MMAL_POOL_T *pool_in = mmal_pool_create(decoder->input[0]->buffer_num, + * decoder->input[0]->buffer_size); + * decoder->output[0]->buffer_num = decoder->output[0]->buffer_num_min; + * decoder->output[0]->buffer_size = decoder->output[0]->buffer_size_min; + * MMAL_POOL_T *pool_out = mmal_pool_create(decoder->output[0]->buffer_num, + * decoder->output[0]->buffer_size); + * + * // Create a queue to store our decoded video frames. The callback we will get when + * // a frame has been decoded will put the frame into this queue. + * MMAL_QUEUE_T *queue_decoded_frames = mmal_queue_create(); + * decoder->output[0]->userdata = (void)queue_decoded_frames; + * + * // Enable all the input port and the output port. + * // The callback specified here is the function which will be called when the buffer header + * // we sent to the component has been processed. + * status = mmal_port_enable(decoder->input[0], input_callback); + * ABORT_IF_ERROR(status); + * status = mmal_port_enable(decoder->output[0], output_callback); + * ABORT_IF_ERROR(status); + * + * // Enable the component. Components will only process data when they are enabled. + * status = mmal_component_enable(decoder); + * ABORT_IF_ERROR(status); + * + * // Data processing loop + * while (1) + * { + * MMAL_BUFFER_HEADER_T *header; + * + * // The client needs to implement its own blocking code. + * // (e.g. a semaphore which is posted when a buffer header is put in one of the queues) + * WAIT_FOR_QUEUES_TO_HAVE_BUFFERS(); + * + * // Send empty buffers to the output port of the decoder to allow the decoder to start + * // producing frames as soon as it gets input data + * while ((buffer = mmal_queue_get(pool_out->queue)) != NULL) + * { + * status = mmal_port_send_buffer(decoder->output[0], buffer); + * ABORT_IF_ERROR(status); + * } + * + * // Send data to decode to the input port of the video decoder + * if ((buffer = mmal_queue_get(pool_in->queue)) != NULL) + * { + * READ_DATA_INTO_BUFFER(buffer); + * + * status = mmal_port_send_buffer(decoder->input[0], buffer); + * ABORT_IF_ERROR(status); + * } + * + * // Get our decoded frames. We also need to cope with events + * // generated from the component here. + * while ((buffer = mmal_queue_get(queue_decoded_frames)) != NULL) + * { + * if (buffer->cmd) + * { + * // This is an event. Do something with it and release the buffer. + * mmal_buffer_header_release(buffer); + * continue; + * } + * + * // We have a frame, do something with it (why not display it for instance?). + * // Once we're done with it, we release it. It will magically go back + * // to its original pool so it can be reused for a new video frame. + * mmal_buffer_header_release(buffer); + * } + * } + * + * // Cleanup everything + * mmal_component_destroy(decoder); + * mmal_pool_destroy(pool_in); + * mmal_pool_destroy(pool_out); + * mmal_queue_destroy(queue_decode_frames); + * + * \endcode + */ + +#include "mmal_common.h" +#include "mmal_types.h" +#include "mmal_port.h" +#include "mmal_component.h" +#include "mmal_parameters.h" +#include "mmal_metadata.h" +#include "mmal_queue.h" +#include "mmal_pool.h" +#include "mmal_events.h" + +/**/ +/** \name API Version + * The following define the version number of the API */ +/* @{ */ +/** Major version number. + * This changes when the API breaks in a way which is not backward compatible. */ +#define MMAL_VERSION_MAJOR 0 +/** Minor version number. + * This changes each time the API is extended in a way which is still source and + * binary compatible. */ +#define MMAL_VERSION_MINOR 1 + +#define MMAL_VERSION (MMAL_VERSION_MAJOR << 16 | MMAL_VERSION_MINOR) +#define MMAL_VERSION_TO_MAJOR(a) (a >> 16) +#define MMAL_VERSION_TO_MINOR(a) (a & 0xFFFF) +/* @} */ + +#endif /* MMAL_H */ diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/mmal_buffer.h b/external_src/raspicam-0.1.3/dependencies/mmal/mmal_buffer.h new file mode 100644 index 0000000..7c91fce --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/mmal_buffer.h @@ -0,0 +1,250 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 MMAL_BUFFER_H +#define MMAL_BUFFER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup MmalBufferHeader Buffer headers + * Definition of a buffer header and its associated API. + * Buffer headers are the basic element used to pass data and information between different + * parts of the system. They are passed to components via ports and sent back to the client + * using a callback mechanism. + */ +/* @{ */ + +/** Specific data associated with video frames */ +typedef struct { + uint32_t planes; /**< Number of planes composing the video frame */ + uint32_t offset[4]; /**< Offsets to the different planes. These must point within the + payload buffer */ + uint32_t pitch[4]; /**< Pitch (size in bytes of a line of a plane) of the different + planes */ + uint32_t flags; /**< Flags describing video specific properties of a buffer header + (see \ref videobufferheaderflags "Video buffer header flags") */ + /* TBD stereoscopic support */ +} MMAL_BUFFER_HEADER_VIDEO_SPECIFIC_T; + +/** Type specific data that's associated with a payload buffer */ +typedef union +{ + /** Specific data associated with video frames */ + MMAL_BUFFER_HEADER_VIDEO_SPECIFIC_T video; + +} MMAL_BUFFER_HEADER_TYPE_SPECIFIC_T; + +/** Definition of the buffer header structure. + * A buffer header does not directly carry the data to be passed to a component but instead + * it references the actual data using a pointer (and an associated length). + * It also contains an internal area which can be used to store command or metadata to be + * associated with the external data. + */ +typedef struct MMAL_BUFFER_HEADER_T +{ + struct MMAL_BUFFER_HEADER_T *next; /**< Used to link several buffer headers together */ + + struct MMAL_BUFFER_HEADER_PRIVATE_T *priv; /**< Data private to the framework */ + + uint32_t cmd; /**< Defines what the buffer header contains. This is a FourCC + with 0 as a special value meaning stream data */ + + uint8_t *data; /**< Pointer to the start of the payload buffer (should not be + changed by component) */ + uint32_t alloc_size; /**< Allocated size in bytes of payload buffer */ + uint32_t length; /**< Number of bytes currently used in the payload buffer (starting + from offset) */ + uint32_t offset; /**< Offset in bytes to the start of valid data in the payload buffer */ + + uint32_t flags; /**< Flags describing properties of a buffer header (see + \ref bufferheaderflags "Buffer header flags") */ + + int64_t pts; /**< Presentation timestamp in microseconds. \ref MMAL_TIME_UNKNOWN + is used when the pts is unknown. */ + int64_t dts; /**< Decode timestamp in microseconds (dts = pts, except in the case + of video streams with B frames). \ref MMAL_TIME_UNKNOWN + is used when the dts is unknown. */ + + /** Type specific data that's associated with a payload buffer */ + MMAL_BUFFER_HEADER_TYPE_SPECIFIC_T *type; + + void *user_data; /**< Field reserved for use by the client */ + +} MMAL_BUFFER_HEADER_T; + +/** \name Buffer header flags + * \anchor bufferheaderflags + * The following flags describe properties of a buffer header */ +/* @{ */ +/** Signals that the current payload is the end of the stream of data */ +#define MMAL_BUFFER_HEADER_FLAG_EOS (1<<0) +/** Signals that the start of the current payload starts a frame */ +#define MMAL_BUFFER_HEADER_FLAG_FRAME_START (1<<1) +/** Signals that the end of the current payload ends a frame */ +#define MMAL_BUFFER_HEADER_FLAG_FRAME_END (1<<2) +/** Signals that the current payload contains only complete frames (1 or more) */ +#define MMAL_BUFFER_HEADER_FLAG_FRAME (MMAL_BUFFER_HEADER_FLAG_FRAME_START|MMAL_BUFFER_HEADER_FLAG_FRAME_END) +/** Signals that the current payload is a keyframe (i.e. self decodable) */ +#define MMAL_BUFFER_HEADER_FLAG_KEYFRAME (1<<3) +/** Signals a discontinuity in the stream of data (e.g. after a seek). + * Can be used for instance by a decoder to reset its state */ +#define MMAL_BUFFER_HEADER_FLAG_DISCONTINUITY (1<<4) +/** Signals a buffer containing some kind of config data for the component + * (e.g. codec config data) */ +#define MMAL_BUFFER_HEADER_FLAG_CONFIG (1<<5) +/** Signals an encrypted payload */ +#define MMAL_BUFFER_HEADER_FLAG_ENCRYPTED (1<<6) +/** Signals a buffer containing side information */ +#define MMAL_BUFFER_HEADER_FLAG_CODECSIDEINFO (1<<7) +/** Signals a buffer which is the snapshot/postview image from a stills capture */ +#define MMAL_BUFFER_HEADER_FLAGS_SNAPSHOT (1<<8) +/** Signals a buffer which contains data known to be corrupted */ +#define MMAL_BUFFER_HEADER_FLAG_CORRUPTED (1<<9) +/** Signals that a buffer failed to be transmitted */ +#define MMAL_BUFFER_HEADER_FLAG_TRANSMISSION_FAILED (1<<10) +/** Signals the output buffer won't be used, just update reference frames */ +#define MMAL_BUFFER_HEADER_FLAG_DECODEONLY (1<<11) +/** User flags - can be passed in and will get returned */ +#define MMAL_BUFFER_HEADER_FLAG_USER0 (1<<28) +#define MMAL_BUFFER_HEADER_FLAG_USER1 (1<<29) +#define MMAL_BUFFER_HEADER_FLAG_USER2 (1<<30) +#define MMAL_BUFFER_HEADER_FLAG_USER3 (1<<31) +/* @} */ + +/** \name Video buffer header flags + * \anchor videobufferheaderflags + * The following flags describe properties of a video buffer header */ +/* @{ */ +/** Signals an interlaced video frame */ +#define MMAL_BUFFER_HEADER_VIDEO_FLAG_INTERLACED (1<<0) +/** Signals that the top field of the current interlaced frame should be displayed first */ +#define MMAL_BUFFER_HEADER_VIDEO_FLAG_TOP_FIELD_FIRST (1<<2) +/** Signals that the buffer should be displayed on external display if attached. */ +#define MMAL_BUFFER_HEADER_VIDEO_FLAG_DISPLAY_EXTERNAL (1<<3) +/** Signals that contents of the buffer requires copy protection. */ +#define MMAL_BUFFER_HEADER_VIDEO_FLAG_PROTECTED (1<<4) +/* @} */ + +/** Acquire a buffer header. + * Acquiring a buffer header increases a reference counter on it and makes sure that the + * buffer header won't be recycled until all the references to it are gone. + * This is useful for instance if a component needs to return a buffer header but still needs + * access to it for some internal processing (e.g. reference frames in video codecs). + * + * @param header buffer header to acquire + */ +void mmal_buffer_header_acquire(MMAL_BUFFER_HEADER_T *header); + +/** Reset a buffer header. + * Resets all header variables to default values. + * + * @param header buffer header to reset + */ +void mmal_buffer_header_reset(MMAL_BUFFER_HEADER_T *header); + +/** 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); + +/** Continue the buffer header release process. + * This should be called to complete buffer header recycling once all pre-release activity + * has been completed. + * + * @param header buffer header to release + */ +void mmal_buffer_header_release_continue(MMAL_BUFFER_HEADER_T *header); + +/** Buffer header pre-release callback. + * The callback is invoked just before a buffer is released back into a + * pool. This is used by clients who need to trigger additional actions + * before the buffer can finally be released (e.g. wait for a bulk transfer + * to complete). + * + * The callback should return TRUE if the buffer release need to be post-poned. + * + * @param header buffer header about to be released + * @param userdata user-specific data + * + * @return TRUE if the buffer should not be released + */ +typedef MMAL_BOOL_T (*MMAL_BH_PRE_RELEASE_CB_T)(MMAL_BUFFER_HEADER_T *header, void *userdata); + +/** Set a buffer header pre-release callback. + * If the callback is NULL, the buffer will be released back into the pool + * immediately as usual. + * + * @param header buffer header to associate callback with + * @param cb pre-release callback to invoke + * @param userdata user-specific data + */ +void mmal_buffer_header_pre_release_cb_set(MMAL_BUFFER_HEADER_T *header, MMAL_BH_PRE_RELEASE_CB_T cb, void *userdata); + +/** Replicate a buffer header into another one. + * Replicating a buffer header will not only do an exact copy of all the public fields of the + * buffer header (including data and alloc_size), but it will also acquire a reference to the + * source buffer header which will only be released once the replicate has been released. + * + * @param dest buffer header into which to replicate + * @param src buffer header to use as the source for the replication + * @return MMAL_SUCCESS on success + */ +MMAL_STATUS_T mmal_buffer_header_replicate(MMAL_BUFFER_HEADER_T *dest, MMAL_BUFFER_HEADER_T *src); + +/** Lock the data buffer contained in the buffer header in memory. + * This call does nothing on all platforms except VideoCore where it is needed to pin a + * buffer in memory before any access to it. + * + * @param header buffer header to lock + */ +MMAL_STATUS_T mmal_buffer_header_mem_lock(MMAL_BUFFER_HEADER_T *header); + +/** Unlock the data buffer contained in the buffer header. + * This call does nothing on all platforms except VideoCore where it is needed to un-pin a + * buffer in memory after any access to it. + * + * @param header buffer header to unlock + */ +void mmal_buffer_header_mem_unlock(MMAL_BUFFER_HEADER_T *header); + +/* @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* MMAL_BUFFER_H */ diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/mmal_clock.h b/external_src/raspicam-0.1.3/dependencies/mmal/mmal_clock.h new file mode 100644 index 0000000..e12509d --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/mmal_clock.h @@ -0,0 +1,202 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 MMAL_CLOCK_H +#define MMAL_CLOCK_H + +#include "vcos/vcos.h" +#include "mmal_types.h" +#include "mmal_common.h" +#include +/** \defgroup MmalClock Clock Framework + * The MMAL clock framework provides scheduling facilities to the rest of + * MMAL. + * + * The framework consists mainly of clock ports and a clock module. Client + * applications and components interact directly with clock ports, while + * the clock module is only used internally by clock ports. + * + * Clock ports ensure that the local media-time for each component is + * synchronised across all components. This is done by passing buffers between + * clock ports which contain clock-specific data. + * + * One clock port will normally act as the reference clock for the rest of the + * system. This is usually chosen to be the clock port of the audio render + * component, but is configurable by the client and could potentially be any + * other clock port (or even the client application itself). + * + * Components that are responsible for timed delivery of frames, do so by + * registering callback requests for a particular time-stamp with the clock + * port. These requests are scheduled using the clock module which maintains + * an internal media-time. + * + * The clock framework also provides the ability to perform playback at different + * speeds. This is achieved with a clock scale factor which determines the speed + * at which the media-time advances relative to real-time, with: + * scale = 1.0 -> normal playback speed + * scale = 0 -> playback paused + * scale > 1.0 -> fast-forward + * scale < 1.0 -> slow motion + */ + +/** Clock event magic */ +#define MMAL_CLOCK_EVENT_MAGIC MMAL_FOURCC('C','K','L','M') + +/** Clock reference update */ +#define MMAL_CLOCK_EVENT_REFERENCE MMAL_FOURCC('C','R','E','F') + +/** Clock state update */ +#define MMAL_CLOCK_EVENT_ACTIVE MMAL_FOURCC('C','A','C','T') + +/** Clock scale update */ +#define MMAL_CLOCK_EVENT_SCALE MMAL_FOURCC('C','S','C','A') + +/** Clock media-time update */ +#define MMAL_CLOCK_EVENT_TIME MMAL_FOURCC('C','T','I','M') + +/** Clock update threshold */ +#define MMAL_CLOCK_EVENT_UPDATE_THRESHOLD MMAL_FOURCC('C','U','T','H') + +/** Clock discontinuity threshold */ +#define MMAL_CLOCK_EVENT_DISCONT_THRESHOLD MMAL_FOURCC('C','D','T','H') + +/** Clock request threshold */ +#define MMAL_CLOCK_EVENT_REQUEST_THRESHOLD MMAL_FOURCC('C','R','T','H') + +/** Buffer statistics */ +#define MMAL_CLOCK_EVENT_INPUT_BUFFER_INFO MMAL_FOURCC('C','I','B','I') +#define MMAL_CLOCK_EVENT_OUTPUT_BUFFER_INFO MMAL_FOURCC('C','O','B','I') + +/** Clock latency setting */ +#define MMAL_CLOCK_EVENT_LATENCY MMAL_FOURCC('C','L','A','T') + +/** Clock event not valid */ +#define MMAL_CLOCK_EVENT_INVALID 0 + + +/** Thresholds used when updating a clock's media-time */ +typedef struct MMAL_CLOCK_UPDATE_THRESHOLD_T +{ + /** Time differences below this threshold are ignored (microseconds) */ + int64_t threshold_lower; + + /** Time differences above this threshold reset media-time (microseconds) */ + int64_t threshold_upper; +} MMAL_CLOCK_UPDATE_THRESHOLD_T; + +/** Threshold for detecting a discontinuity in media-time */ +typedef struct MMAL_CLOCK_DISCONT_THRESHOLD_T +{ + /** Threshold after which backward jumps in media-time are treated as a + * discontinuity (microseconds) */ + int64_t threshold; + + /** Duration in microseconds for which a discontinuity applies (wall-time) */ + int64_t duration; +} MMAL_CLOCK_DISCONT_THRESHOLD_T; + +/** Threshold applied to client callback requests */ +typedef struct MMAL_CLOCK_REQUEST_THRESHOLD_T +{ + /** Frames with a media-time difference (compared to current media-time) + * above this threshold are dropped (microseconds) */ + int64_t threshold; + + /** Enable/disable the request threshold */ + MMAL_BOOL_T threshold_enable; +} MMAL_CLOCK_REQUEST_THRESHOLD_T; + +/** Structure for passing buffer information to a clock port */ +typedef struct MMAL_CLOCK_BUFFER_INFO_T +{ + int64_t time_stamp; + uint32_t arrival_time; +} MMAL_CLOCK_BUFFER_INFO_T; + +/** Clock latency settings used by the clock component */ +typedef struct MMAL_CLOCK_LATENCY_T +{ + int64_t target; /**< target latency (microseconds) */ + int64_t attack_period; /**< duration of one attack period (microseconds) */ + int64_t attack_rate; /**< amount by which media-time will be adjusted + every attack_period (microseconds) */ +} MMAL_CLOCK_LATENCY_T; + +/** Clock event used to pass data between clock ports and a client. */ +typedef struct MMAL_CLOCK_EVENT_T +{ + /** 4cc event id */ + uint32_t id; + + /** 4cc event magic */ + uint32_t magic; + + /** buffer associated with this event (can be NULL) */ + struct MMAL_BUFFER_HEADER_T *buffer; + + /** pad to 64-bit boundary */ + uint32_t padding0; + + /** additional event data (type-specific) */ + union + { + /** used either for clock reference or clock state */ + MMAL_BOOL_T enable; + + /** new clock scale */ + MMAL_RATIONAL_T scale; + + /** new media-time */ + int64_t media_time; + + /** media-time update threshold */ + MMAL_CLOCK_UPDATE_THRESHOLD_T update_threshold; + + /** media-time discontinuity threshold */ + MMAL_CLOCK_DISCONT_THRESHOLD_T discont_threshold; + + /** client callback request threshold */ + MMAL_CLOCK_REQUEST_THRESHOLD_T request_threshold; + + /** input/output buffer information */ + MMAL_CLOCK_BUFFER_INFO_T buffer; + + /** clock latency setting */ + MMAL_CLOCK_LATENCY_T latency; + } data; + + /** pad to 64-bit boundary */ + uint64_t padding1; +} MMAL_CLOCK_EVENT_T; + +/* Make sure MMAL_CLOCK_EVENT_T will preserve 64-bit alignment */ +static_assert(!(sizeof(MMAL_CLOCK_EVENT_T) & 0x7),"mmal error"); + +#define MMAL_CLOCK_EVENT_INIT(id) { id, MMAL_CLOCK_EVENT_MAGIC, NULL, 0, {0}, 0 } + +#endif /* MMAL_CLOCK_H */ diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/mmal_common.h b/external_src/raspicam-0.1.3/dependencies/mmal/mmal_common.h new file mode 100644 index 0000000..2482dd1 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/mmal_common.h @@ -0,0 +1,83 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. +*/ + +/** \file mmal_common.h + * Multi-Media Abstraction Layer - Common definitions + */ + +#ifndef MMAL_COMMON_H +#define MMAL_COMMON_H + +#include +#include +#include +#include + +#include + +/* C99 64bits integers */ +#ifndef INT64_C +# define INT64_C(value) value##LL +# define UINT64_C(value) value##ULL +#endif + +#define MMAL_TSRING(s) #s +#define MMAL_TO_STRING(s) MMAL_TSRING(s) + +#define MMAL_COUNTOF(x) (sizeof((x))/sizeof((x)[0])) +#define MMAL_MIN(a,b) ((a)<(b)?(a):(b)) +#define MMAL_MAX(a,b) ((a)<(b)?(b):(a)) + +/* FIXME: should be different for big endian */ +#define MMAL_FOURCC(a,b,c,d) ((a) | (b << 8) | (c << 16) | (d << 24)) +#define MMAL_PARAM_UNUSED(a) (void)(a) +#define MMAL_MAGIC MMAL_FOURCC('m','m','a','l') + +typedef int32_t MMAL_BOOL_T; +#define MMAL_FALSE 0 +#define MMAL_TRUE 1 + +typedef struct MMAL_CORE_STATISTICS_T +{ + uint32_t buffer_count; /**< Total buffer count on this port */ + uint32_t first_buffer_time; /**< Time (us) of first buffer seen on this port */ + uint32_t last_buffer_time; /**< Time (us) of most recently buffer on this port */ + uint32_t max_delay; /**< Max delay (us) between buffers, ignoring first few frames */ +} MMAL_CORE_STATISTICS_T; + +/** Statistics collected by the core on all ports, if enabled in the build. + */ +typedef struct MMAL_CORE_PORT_STATISTICS_T +{ + MMAL_CORE_STATISTICS_T rx; + MMAL_CORE_STATISTICS_T tx; +} MMAL_CORE_PORT_STATISTICS_T; + +/** Unsigned 16.16 fixed point value, also known as Q16.16 */ +typedef uint32_t MMAL_FIXED_16_16_T; + +#endif /* MMAL_COMMON_H */ diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/mmal_component.h b/external_src/raspicam-0.1.3/dependencies/mmal/mmal_component.h new file mode 100644 index 0000000..6c9d104 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/mmal_component.h @@ -0,0 +1,148 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 MMAL_COMPONENT_H +#define MMAL_COMPONENT_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup MmalComponent Components + * Definition of a MMAL component and its associated API. A component will always expose ports + * which it uses to send and receive data in the form of buffer headers + * (\ref MMAL_BUFFER_HEADER_T) */ +/* @{ */ + +#include "mmal_types.h" +#include "mmal_port.h" + +struct MMAL_COMPONENT_PRIVATE_T; +typedef struct MMAL_COMPONENT_PRIVATE_T MMAL_COMPONENT_PRIVATE_T; + +/** Definition of a component. */ +typedef struct MMAL_COMPONENT_T +{ + /** Pointer to the private data of the module in use */ + struct MMAL_COMPONENT_PRIVATE_T *priv; + + /** Pointer to private data of the client */ + struct MMAL_COMPONENT_USERDATA_T *userdata; + + /** Component name */ + const char *name; + + /** Specifies whether the component is enabled or not */ + uint32_t is_enabled; + + /** All components expose a control port. + * The control port is used by clients to set / get parameters that are global to the + * component. It is also used to receive events, which again are global to the component. + * To be able to receive events, the client needs to enable and register a callback on the + * control port. */ + MMAL_PORT_T *control; + + uint32_t input_num; /**< Number of input ports */ + MMAL_PORT_T **input; /**< Array of input ports */ + + uint32_t output_num; /**< Number of output ports */ + MMAL_PORT_T **output; /**< Array of output ports */ + + uint32_t clock_num; /**< Number of clock ports */ + MMAL_PORT_T **clock; /**< Array of clock ports */ + + uint32_t port_num; /**< Total number of ports */ + MMAL_PORT_T **port; /**< Array of all the ports (control/input/output/clock) */ + + /** Uniquely identifies the component's instance within the MMAL + * context / process. For debugging. */ + uint32_t id; + +} MMAL_COMPONENT_T; + +/** 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); + +/** 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); + +/** 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); + +/** 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); + +/** 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); + +/** 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); + +/* @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* MMAL_COMPONENT_H */ diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/mmal_encodings.h b/external_src/raspicam-0.1.3/dependencies/mmal/mmal_encodings.h new file mode 100644 index 0000000..5421a6d --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/mmal_encodings.h @@ -0,0 +1,208 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 MMAL_ENCODINGS_H +#define MMAL_ENCODINGS_H + +#include "mmal_common.h" + +/** \defgroup MmalEncodings List of pre-defined encodings + * This defines a list of common encodings. This list isn't exhaustive and is only + * provided as a convenience to avoid clients having to use FourCC codes directly. + * However components are allowed to define and use their own FourCC codes. */ +/* @{ */ + +/** \name Pre-defined video encodings */ +/* @{ */ +#define MMAL_ENCODING_H264 MMAL_FOURCC('H','2','6','4') +#define MMAL_ENCODING_H263 MMAL_FOURCC('H','2','6','3') +#define MMAL_ENCODING_MP4V MMAL_FOURCC('M','P','4','V') +#define MMAL_ENCODING_MP2V MMAL_FOURCC('M','P','2','V') +#define MMAL_ENCODING_MP1V MMAL_FOURCC('M','P','1','V') +#define MMAL_ENCODING_WMV3 MMAL_FOURCC('W','M','V','3') +#define MMAL_ENCODING_WMV2 MMAL_FOURCC('W','M','V','2') +#define MMAL_ENCODING_WMV1 MMAL_FOURCC('W','M','V','1') +#define MMAL_ENCODING_WVC1 MMAL_FOURCC('W','V','C','1') +#define MMAL_ENCODING_VP8 MMAL_FOURCC('V','P','8',' ') +#define MMAL_ENCODING_VP7 MMAL_FOURCC('V','P','7',' ') +#define MMAL_ENCODING_VP6 MMAL_FOURCC('V','P','6',' ') +#define MMAL_ENCODING_THEORA MMAL_FOURCC('T','H','E','O') +#define MMAL_ENCODING_SPARK MMAL_FOURCC('S','P','R','K') +#define MMAL_ENCODING_MJPEG MMAL_FOURCC('M','J','P','G') + +#define MMAL_ENCODING_JPEG MMAL_FOURCC('J','P','E','G') +#define MMAL_ENCODING_GIF MMAL_FOURCC('G','I','F',' ') +#define MMAL_ENCODING_PNG MMAL_FOURCC('P','N','G',' ') +#define MMAL_ENCODING_PPM MMAL_FOURCC('P','P','M',' ') +#define MMAL_ENCODING_TGA MMAL_FOURCC('T','G','A',' ') +#define MMAL_ENCODING_BMP MMAL_FOURCC('B','M','P',' ') + +#define MMAL_ENCODING_I420 MMAL_FOURCC('I','4','2','0') +#define MMAL_ENCODING_I420_SLICE MMAL_FOURCC('S','4','2','0') +#define MMAL_ENCODING_YV12 MMAL_FOURCC('Y','V','1','2') +#define MMAL_ENCODING_I422 MMAL_FOURCC('I','4','2','2') +#define MMAL_ENCODING_I422_SLICE MMAL_FOURCC('S','4','2','2') +#define MMAL_ENCODING_YUYV MMAL_FOURCC('Y','U','Y','V') +#define MMAL_ENCODING_YVYU MMAL_FOURCC('Y','V','Y','U') +#define MMAL_ENCODING_UYVY MMAL_FOURCC('U','Y','V','Y') +#define MMAL_ENCODING_VYUY MMAL_FOURCC('V','Y','U','Y') +#define MMAL_ENCODING_NV12 MMAL_FOURCC('N','V','1','2') +#define MMAL_ENCODING_NV21 MMAL_FOURCC('N','V','2','1') +#define MMAL_ENCODING_ARGB MMAL_FOURCC('A','R','G','B') +#define MMAL_ENCODING_RGBA MMAL_FOURCC('R','G','B','A') +#define MMAL_ENCODING_ABGR MMAL_FOURCC('A','B','G','R') +#define MMAL_ENCODING_BGRA MMAL_FOURCC('B','G','R','A') +#define MMAL_ENCODING_RGB16 MMAL_FOURCC('R','G','B','2') +#define MMAL_ENCODING_RGB24 MMAL_FOURCC('R','G','B','3') +#define MMAL_ENCODING_RGB32 MMAL_FOURCC('R','G','B','4') +#define MMAL_ENCODING_BGR16 MMAL_FOURCC('B','G','R','2') +#define MMAL_ENCODING_BGR24 MMAL_FOURCC('B','G','R','3') +#define MMAL_ENCODING_BGR32 MMAL_FOURCC('B','G','R','4') + +/** SAND Video (YUVUV128) format, native format understood by VideoCore. + * This format is *not* opaque - if requested you will receive full frames + * of YUV_UV video. + */ +#define MMAL_ENCODING_YUVUV128 MMAL_FOURCC('S','A','N','D') + +/** VideoCore opaque image format, image handles are returned to + * the host but not the actual image data. + */ +#define MMAL_ENCODING_OPAQUE MMAL_FOURCC('O','P','Q','V') + +/** An EGL image handle + */ +#define MMAL_ENCODING_EGL_IMAGE MMAL_FOURCC('E','G','L','I') + +/* }@ */ + +/** \name Pre-defined audio encodings */ +/* @{ */ +#define MMAL_ENCODING_PCM_UNSIGNED_BE MMAL_FOURCC('P','C','M','U') +#define MMAL_ENCODING_PCM_UNSIGNED_LE MMAL_FOURCC('p','c','m','u') +#define MMAL_ENCODING_PCM_SIGNED_BE MMAL_FOURCC('P','C','M','S') +#define MMAL_ENCODING_PCM_SIGNED_LE MMAL_FOURCC('p','c','m','s') +#define MMAL_ENCODING_PCM_FLOAT_BE MMAL_FOURCC('P','C','M','F') +#define MMAL_ENCODING_PCM_FLOAT_LE MMAL_FOURCC('p','c','m','f') +/* Defines for native endianness */ +#ifdef MMAL_IS_BIG_ENDIAN +#define MMAL_ENCODING_PCM_UNSIGNED MMAL_ENCODING_PCM_UNSIGNED_BE +#define MMAL_ENCODING_PCM_SIGNED MMAL_ENCODING_PCM_SIGNED_BE +#define MMAL_ENCODING_PCM_FLOAT MMAL_ENCODING_PCM_FLOAT_BE +#else +#define MMAL_ENCODING_PCM_UNSIGNED MMAL_ENCODING_PCM_UNSIGNED_LE +#define MMAL_ENCODING_PCM_SIGNED MMAL_ENCODING_PCM_SIGNED_LE +#define MMAL_ENCODING_PCM_FLOAT MMAL_ENCODING_PCM_FLOAT_LE +#endif + +#define MMAL_ENCODING_MP4A MMAL_FOURCC('M','P','4','A') +#define MMAL_ENCODING_MPGA MMAL_FOURCC('M','P','G','A') +#define MMAL_ENCODING_ALAW MMAL_FOURCC('A','L','A','W') +#define MMAL_ENCODING_MULAW MMAL_FOURCC('U','L','A','W') +#define MMAL_ENCODING_ADPCM_MS MMAL_FOURCC('M','S',0x0,0x2) +#define MMAL_ENCODING_ADPCM_IMA_MS MMAL_FOURCC('M','S',0x0,0x1) +#define MMAL_ENCODING_ADPCM_SWF MMAL_FOURCC('A','S','W','F') +#define MMAL_ENCODING_WMA1 MMAL_FOURCC('W','M','A','1') +#define MMAL_ENCODING_WMA2 MMAL_FOURCC('W','M','A','2') +#define MMAL_ENCODING_WMAP MMAL_FOURCC('W','M','A','P') +#define MMAL_ENCODING_WMAL MMAL_FOURCC('W','M','A','L') +#define MMAL_ENCODING_WMAV MMAL_FOURCC('W','M','A','V') +#define MMAL_ENCODING_AMRNB MMAL_FOURCC('A','M','R','N') +#define MMAL_ENCODING_AMRWB MMAL_FOURCC('A','M','R','W') +#define MMAL_ENCODING_AMRWBP MMAL_FOURCC('A','M','R','P') +#define MMAL_ENCODING_AC3 MMAL_FOURCC('A','C','3',' ') +#define MMAL_ENCODING_EAC3 MMAL_FOURCC('E','A','C','3') +#define MMAL_ENCODING_DTS MMAL_FOURCC('D','T','S',' ') +#define MMAL_ENCODING_MLP MMAL_FOURCC('M','L','P',' ') +#define MMAL_ENCODING_FLAC MMAL_FOURCC('F','L','A','C') +#define MMAL_ENCODING_VORBIS MMAL_FOURCC('V','O','R','B') +#define MMAL_ENCODING_SPEEX MMAL_FOURCC('S','P','X',' ') +#define MMAL_ENCODING_ATRAC3 MMAL_FOURCC('A','T','R','3') +#define MMAL_ENCODING_ATRACX MMAL_FOURCC('A','T','R','X') +#define MMAL_ENCODING_ATRACL MMAL_FOURCC('A','T','R','L') +#define MMAL_ENCODING_MIDI MMAL_FOURCC('M','I','D','I') +#define MMAL_ENCODING_EVRC MMAL_FOURCC('E','V','R','C') +#define MMAL_ENCODING_NELLYMOSER MMAL_FOURCC('N','E','L','Y') +#define MMAL_ENCODING_QCELP MMAL_FOURCC('Q','C','E','L') +#define MMAL_ENCODING_MP4V_DIVX_DRM MMAL_FOURCC('M','4','V','D') +/* @} */ + +/* @} MmalEncodings List */ + +/** \defgroup MmalEncodingVariants List of pre-defined encoding variants + * This defines a list of common encoding variants. This list isn't exhaustive and is only + * provided as a convenience to avoid clients having to use FourCC codes directly. + * However components are allowed to define and use their own FourCC codes. */ +/* @{ */ + +/** \name Pre-defined H264 encoding variants */ +/* @{ */ +/** ISO 14496-10 Annex B byte stream format */ +#define MMAL_ENCODING_VARIANT_H264_DEFAULT 0 +/** ISO 14496-15 AVC stream format */ +#define MMAL_ENCODING_VARIANT_H264_AVC1 MMAL_FOURCC('A','V','C','1') +/** Implicitly delineated NAL units without emulation prevention */ +#define MMAL_ENCODING_VARIANT_H264_RAW MMAL_FOURCC('R','A','W',' ') +/* @} */ + +/** \name Pre-defined MPEG4 audio encoding variants */ +/* @{ */ +/** Raw stream format */ +#define MMAL_ENCODING_VARIANT_MP4A_DEFAULT 0 +/** ADTS stream format */ +#define MMAL_ENCODING_VARIANT_MP4A_ADTS MMAL_FOURCC('A','D','T','S') +/* @} */ + +/* @} MmalEncodingVariants List */ + +/** \defgroup MmalColorSpace List of pre-defined video color spaces + * This defines a list of common color spaces. This list isn't exhaustive and is only + * provided as a convenience to avoid clients having to use FourCC codes directly. + * However components are allowed to define and use their own FourCC codes. */ +/* @{ */ + +/** Unknown color space */ +#define MMAL_COLOR_SPACE_UNKNOWN 0 +/** ITU-R BT.601-5 [SDTV] */ +#define MMAL_COLOR_SPACE_ITUR_BT601 MMAL_FOURCC('Y','6','0','1') +/** ITU-R BT.709-3 [HDTV] */ +#define MMAL_COLOR_SPACE_ITUR_BT709 MMAL_FOURCC('Y','7','0','9') +/** JPEG JFIF */ +#define MMAL_COLOR_SPACE_JPEG_JFIF MMAL_FOURCC('Y','J','F','I') +/** Title 47 Code of Federal Regulations (2003) 73.682 (a) (20) */ +#define MMAL_COLOR_SPACE_FCC MMAL_FOURCC('Y','F','C','C') +/** Society of Motion Picture and Television Engineers 240M (1999) */ +#define MMAL_COLOR_SPACE_SMPTE240M MMAL_FOURCC('Y','2','4','0') +/** ITU-R BT.470-2 System M */ +#define MMAL_COLOR_SPACE_BT470_2_M MMAL_FOURCC('Y','_','_','M') +/** ITU-R BT.470-2 System BG */ +#define MMAL_COLOR_SPACE_BT470_2_BG MMAL_FOURCC('Y','_','B','G') +/** JPEG JFIF, but with 16..255 luma */ +#define MMAL_COLOR_SPACE_JFIF_Y16_255 MMAL_FOURCC('Y','Y','1','6') +/* @} MmalColorSpace List */ + +#endif /* MMAL_ENCODINGS_H */ diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/mmal_events.h b/external_src/raspicam-0.1.3/dependencies/mmal/mmal_events.h new file mode 100644 index 0000000..94ccd56 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/mmal_events.h @@ -0,0 +1,109 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 MMAL_EVENTS_H +#define MMAL_EVENTS_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "mmal_common.h" +#include "mmal_parameters.h" +#include "mmal_port.h" + +/** \defgroup MmalEvents List of pre-defined event types + * This defines a list of standard event types. Components can still define proprietary + * event types by using their own FourCC and defining their own event structures. */ +/* @{ */ + +/** \name Pre-defined event FourCCs */ +/* @{ */ + +/** Error event. Data contains a \ref MMAL_STATUS_T */ +#define MMAL_EVENT_ERROR MMAL_FOURCC('E','R','R','O') + +/** End-of-stream event. Data contains a \ref MMAL_EVENT_END_OF_STREAM_T */ +#define MMAL_EVENT_EOS MMAL_FOURCC('E','E','O','S') + +/** Format changed event. Data contains a \ref MMAL_EVENT_FORMAT_CHANGED_T */ +#define MMAL_EVENT_FORMAT_CHANGED MMAL_FOURCC('E','F','C','H') + +/** Parameter changed event. Data contains the new parameter value, see + * \ref MMAL_EVENT_PARAMETER_CHANGED_T + */ +#define MMAL_EVENT_PARAMETER_CHANGED MMAL_FOURCC('E','P','C','H') + +/* @} */ + + +/** End-of-stream event. */ +typedef struct MMAL_EVENT_END_OF_STREAM_T +{ + MMAL_PORT_TYPE_T port_type; /**< Type of port that received the end of stream */ + uint32_t port_index; /**< Index of port that received the end of stream */ +} MMAL_EVENT_END_OF_STREAM_T; + +/** Format changed event data. */ +typedef struct MMAL_EVENT_FORMAT_CHANGED_T +{ + uint32_t buffer_size_min; /**< Minimum size of buffers the port requires */ + uint32_t buffer_num_min; /**< Minimum number of buffers the port requires */ + uint32_t buffer_size_recommended; /**< Size of buffers the port recommends for optimal performance. + A value of zero means no special recommendation. */ + uint32_t buffer_num_recommended; /**< Number of buffers the port recommends for optimal + performance. A value of zero means no special recommendation. */ + + MMAL_ES_FORMAT_T *format; /**< New elementary stream format */ +} MMAL_EVENT_FORMAT_CHANGED_T; + +/** Parameter changed event data. + * This is a variable sized event. The full parameter is included in the event + * data, not just the header. Use the \ref MMAL_PARAMETER_HEADER_T::id field to determine how to + * cast the structure. The \ref MMAL_PARAMETER_HEADER_T::size field can be used to check validity. + */ +typedef struct MMAL_EVENT_PARAMETER_CHANGED_T +{ + MMAL_PARAMETER_HEADER_T hdr; +} MMAL_EVENT_PARAMETER_CHANGED_T; + +/** Get a pointer to the \ref MMAL_EVENT_FORMAT_CHANGED_T structure contained in the buffer header. + * Note that the pointer will point inside the data contained in the buffer header + * so doesn't need to be freed explicitly. + * + * @param buffer buffer header containing the MMAL_EVENT_FORMAT_CHANGED event. + * @return pointer to a MMAL_EVENT_FORMAT_CHANGED_T structure. + */ +MMAL_EVENT_FORMAT_CHANGED_T *mmal_event_format_changed_get(MMAL_BUFFER_HEADER_T *buffer); + +/* @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* MMAL_EVENTS_H */ diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/mmal_format.h b/external_src/raspicam-0.1.3/dependencies/mmal/mmal_format.h new file mode 100644 index 0000000..78c0844 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/mmal_format.h @@ -0,0 +1,223 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 MMAL_FORMAT_H +#define MMAL_FORMAT_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup MmalFormat Elementary stream format + * Definition of an elementary stream format and its associated API */ +/* @{ */ + +#include "mmal_types.h" +#include "mmal_encodings.h" + +/** Enumeration of the different types of elementary streams. + * This divides elementary streams into 4 big categories, plus an invalid type. */ +typedef enum { + MMAL_ES_TYPE_UNKNOWN, /**< Unknown elementary stream type */ + MMAL_ES_TYPE_CONTROL, /**< Elementary stream of control commands */ + MMAL_ES_TYPE_AUDIO, /**< Audio elementary stream */ + MMAL_ES_TYPE_VIDEO, /**< Video elementary stream */ + MMAL_ES_TYPE_SUBPICTURE /**< Sub-picture elementary stream (e.g. subtitles, overlays) */ +} MMAL_ES_TYPE_T; + +/** Definition of a video format. + * This describes the properties specific to a video stream */ +typedef struct +{ + uint32_t width; /**< Width of frame in pixels */ + uint32_t height; /**< Height of frame in rows of pixels */ + MMAL_RECT_T crop; /**< Visible region of the frame */ + MMAL_RATIONAL_T frame_rate; /**< Frame rate */ + MMAL_RATIONAL_T par; /**< Pixel aspect ratio */ + + MMAL_FOURCC_T color_space; /**< FourCC specifying the color space of the + * video stream. See the \ref MmalColorSpace + * "pre-defined color spaces" for some examples. + */ + +} MMAL_VIDEO_FORMAT_T; + +/** Definition of an audio format. + * This describes the properties specific to an audio stream */ +typedef struct MMAL_AUDIO_FORMAT_T +{ + uint32_t channels; /**< Number of audio channels */ + uint32_t sample_rate; /**< Sample rate */ + + uint32_t bits_per_sample; /**< Bits per sample */ + uint32_t block_align; /**< Size of a block of data */ + + /** \todo add channel mapping, gapless and replay-gain support */ + +} MMAL_AUDIO_FORMAT_T; + +/** Definition of a subpicture format. + * This describes the properties specific to a subpicture stream */ +typedef struct +{ + uint32_t x_offset; /**< Width offset to the start of the subpicture */ + uint32_t y_offset; /**< Height offset to the start of the subpicture */ + + /** \todo surely more things are needed here */ + +} MMAL_SUBPICTURE_FORMAT_T; + +/** Definition of the type specific format. + * This describes the type specific information of the elementary stream. */ +typedef union +{ + MMAL_AUDIO_FORMAT_T audio; /**< Audio specific information */ + MMAL_VIDEO_FORMAT_T video; /**< Video specific information */ + MMAL_SUBPICTURE_FORMAT_T subpicture; /**< Subpicture specific information */ +} MMAL_ES_SPECIFIC_FORMAT_T; + +/** \name Elementary stream flags + * \anchor elementarystreamflags + * The following flags describe properties of an elementary stream */ +/* @{ */ +#define MMAL_ES_FORMAT_FLAG_FRAMED 0x1 /**< The elementary stream will already be framed */ +/* @} */ + +/** \name Undefined encoding value. + * This value indicates an unknown encoding + */ +/* @{ */ +#define MMAL_ENCODING_UNKNOWN 0 +/* @} */ + +/** \name Default encoding variant value. + * This value indicates the default encoding variant is used + */ +/* @{ */ +#define MMAL_ENCODING_VARIANT_DEFAULT 0 +/* @} */ + +/** Definition of an elementary stream format */ +typedef struct MMAL_ES_FORMAT_T +{ + MMAL_ES_TYPE_T type; /**< Type of the elementary stream */ + + MMAL_FOURCC_T encoding; /**< FourCC specifying the encoding of the elementary stream. + * See the \ref MmalEncodings "pre-defined encodings" for some + * examples. + */ + MMAL_FOURCC_T encoding_variant;/**< FourCC specifying the specific encoding variant of + * the elementary stream. See the \ref MmalEncodingVariants + * "pre-defined encoding variants" for some examples. + */ + + MMAL_ES_SPECIFIC_FORMAT_T *es; /**< Type specific information for the elementary stream */ + + uint32_t bitrate; /**< Bitrate in bits per second */ + uint32_t flags; /**< Flags describing properties of the elementary stream. + * See \ref elementarystreamflags "Elementary stream flags". + */ + + uint32_t extradata_size; /**< Size of the codec specific data */ + uint8_t *extradata; /**< Codec specific data */ + +} MMAL_ES_FORMAT_T; + +/** Allocate and initialise a \ref MMAL_ES_FORMAT_T structure. + * + * @return a \ref MMAL_ES_FORMAT_T structure + */ +MMAL_ES_FORMAT_T *mmal_format_alloc(void); + +/** Free a \ref MMAL_ES_FORMAT_T structure allocated by \ref mmal_format_alloc. + * + * @param format the \ref MMAL_ES_FORMAT_T structure to free + */ +void mmal_format_free(MMAL_ES_FORMAT_T *format); + +/** Allocate the extradata buffer in \ref MMAL_ES_FORMAT_T. + * This buffer will be freed automatically when the format is destroyed or + * another allocation is done. + * + * @param format format structure for which the extradata buffer will be allocated + * @param size size of the extradata buffer to allocate + * @return MMAL_SUCCESS on success + */ +MMAL_STATUS_T mmal_format_extradata_alloc(MMAL_ES_FORMAT_T *format, unsigned int size); + +/** 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); + +/** Fully copy a format structure, including the extradata buffer. + * + * @param format_dest destination \ref MMAL_ES_FORMAT_T for the copy + * @param format_src source \ref MMAL_ES_FORMAT_T for the copy + * @return MMAL_SUCCESS on success + */ +MMAL_STATUS_T mmal_format_full_copy(MMAL_ES_FORMAT_T *format_dest, MMAL_ES_FORMAT_T *format_src); + +/** \name Comparison flags + * \anchor comparisonflags + * The following flags describe the differences between 2 format structures */ +/* @{ */ +#define MMAL_ES_FORMAT_COMPARE_FLAG_TYPE 0x01 /**< The type is different */ +#define MMAL_ES_FORMAT_COMPARE_FLAG_ENCODING 0x02 /**< The encoding is different */ +#define MMAL_ES_FORMAT_COMPARE_FLAG_BITRATE 0x04 /**< The bitrate is different */ +#define MMAL_ES_FORMAT_COMPARE_FLAG_FLAGS 0x08 /**< The flags are different */ +#define MMAL_ES_FORMAT_COMPARE_FLAG_EXTRADATA 0x10 /**< The extradata is different */ + +#define MMAL_ES_FORMAT_COMPARE_FLAG_VIDEO_RESOLUTION 0x0100 /**< The video resolution is different */ +#define MMAL_ES_FORMAT_COMPARE_FLAG_VIDEO_CROPPING 0x0200 /**< The video cropping is different */ +#define MMAL_ES_FORMAT_COMPARE_FLAG_VIDEO_FRAME_RATE 0x0400 /**< The video frame rate is different */ +#define MMAL_ES_FORMAT_COMPARE_FLAG_VIDEO_ASPECT_RATIO 0x0800 /**< The video aspect ratio is different */ +#define MMAL_ES_FORMAT_COMPARE_FLAG_VIDEO_COLOR_SPACE 0x1000 /**< The video color space is different */ + +#define MMAL_ES_FORMAT_COMPARE_FLAG_ES_OTHER 0x10000000 /**< Other ES specific parameters are different */ +/* @} */ + +/** Compare 2 format structures and returns a set of flags describing the differences. + * The result will be zero if the structures are the same, or a combination of + * one or more of the \ref comparisonflags "Comparison flags" if different. + * + * @param format_1 first \ref MMAL_ES_FORMAT_T to compare + * @param format_2 second \ref MMAL_ES_FORMAT_T to compare + * @return set of flags describing the differences + */ +uint32_t mmal_format_compare(MMAL_ES_FORMAT_T *format_1, MMAL_ES_FORMAT_T *format_2); + +/* @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* MMAL_FORMAT_H */ diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/mmal_logging.h b/external_src/raspicam-0.1.3/dependencies/mmal/mmal_logging.h new file mode 100644 index 0000000..2307ab3 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/mmal_logging.h @@ -0,0 +1,71 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 MMAL_LOGGING_H +#define MMAL_LOGGING_H + +#include "mmal_common.h" +#include "interface/vcos/vcos_logging.h" + +#ifndef VCOS_LOG_CATEGORY +#define VCOS_LOG_CATEGORY (&mmal_log_category) +extern VCOS_LOG_CAT_T mmal_log_category; +#endif + +#if defined(__GNUC__) && (( __GNUC__ > 2 ) || (( __GNUC__ == 2 ) && ( __GNUC_MINOR__ >= 3 ))) +#define mmal_log_error(s, ...) vcos_log_error("%s: " s, VCOS_FUNCTION, ## __VA_ARGS__) +#define mmal_log_info(s, ...) vcos_log_info("%s: " s, VCOS_FUNCTION, ## __VA_ARGS__) +#define mmal_log_warn(s, ...) vcos_log_warn("%s: " s, VCOS_FUNCTION, ## __VA_ARGS__) +#define mmal_log_debug(s, ...) vcos_log_info("%s: " s, VCOS_FUNCTION, ## __VA_ARGS__) +#define mmal_log_trace(s, ...) vcos_log_trace("%s: " s, VCOS_FUNCTION, ## __VA_ARGS__) +#elif defined(_MSC_VER) +#define mmal_log_error(s, ...) vcos_log_error("%s: " s, VCOS_FUNCTION, __VA_ARGS__) +#define mmal_log_info(s, ...) vcos_log_info("%s: " s, VCOS_FUNCTION, __VA_ARGS__) +#define mmal_log_warn(s, ...) vcos_log_warn("%s: " s, VCOS_FUNCTION, __VA_ARGS__) +#define mmal_log_debug(s, ...) vcos_log_info("%s: " s, VCOS_FUNCTION, __VA_ARGS__) +#define mmal_log_trace(s, ...) vcos_log_trace("%s: " s, VCOS_FUNCTION, __VA_ARGS__) +#else +#define mmal_log_error_fun(s, ...) vcos_log_error("%s: " s, VCOS_FUNCTION, __VA_ARGS__) +#define mmal_log_info_fun(s, ...) vcos_log_info("%s: " s, VCOS_FUNCTION, __VA_ARGS__) +#define mmal_log_warn_fun(s, ...) vcos_log_warn("%s: " s, VCOS_FUNCTION, __VA_ARGS__) +#define mmal_log_debug_fun(s, ...) vcos_log_info("%s: " s, VCOS_FUNCTION, __VA_ARGS__) +#define mmal_log_trace_fun(s, ...) vcos_log_trace("%s: " s, VCOS_FUNCTION, __VA_ARGS__) + +#define mmal_log_error(s...) mmal_log_error_fun(s, 0) +#define mmal_log_info(s...) mmal_log_info_fun(s, 0) +#define mmal_log_warn(s...) mmal_log_warn_fun(s, 0) +#define mmal_log_debug(s...) mmal_log_debug_fun(s, 0) +#define mmal_log_trace(s...) mmal_log_trace_fun(s, 0) +#endif + +#define LOG_ERROR mmal_log_error +#define LOG_INFO mmal_log_info +#define LOG_WARN mmal_log_warn +#define LOG_DEBUG mmal_log_debug +#define LOG_TRACE mmal_log_trace + +#endif /* MMAL_LOGGING_H */ diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/mmal_metadata.h b/external_src/raspicam-0.1.3/dependencies/mmal/mmal_metadata.h new file mode 100644 index 0000000..5d21dd0 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/mmal_metadata.h @@ -0,0 +1,84 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 MMAL_METADATA_H +#define MMAL_METADATA_H + +#include "mmal_common.h" + +/** \defgroup MmalMetadata List of pre-defined metadata types + * This defines a list of standard metadata types. Components can still define proprietary + * metadata types by using their own FourCC and defining their own metadata structures. */ +/* @{ */ + +/** \name Pre-defined metadata FourCCs */ +/* @{ */ +#define MMAL_METADATA_HELLO_WORLD MMAL_FOURCC('H','E','L','O') +/* @} */ + +/** Generic metadata type. All metadata structures need to begin with these fields. */ +typedef struct MMAL_METATDATA_T +{ + uint32_t id; /**< Metadata id. This is a FourCC */ + uint32_t size; /**< Size in bytes of the following metadata (not including id and size) */ +} MMAL_METADATA_T; + +/** Hello World metadata. */ +typedef struct MMAL_METATDATA_HELLO_WORLD_T +{ + uint32_t id; /**< Metadata id. This is a FourCC */ + uint32_t size; /**< Size in bytes of the following metadata (not including id and size) */ + + uint32_t myvalue; /**< Metadata value */ +} MMAL_METADATA_HELLO_WORLD_T; + +/** Get metadata item from buffer header. + * This will search through all the metadata in the buffer header and return a pointer to the + * first instance of the requested metadata id. + * + * @param header buffer header containing the metadata + * @param id requested metadata id + * + * @return Pointer to metadata requested or NULL if not found. + */ +MMAL_METADATA_T *mmal_metadata_get(MMAL_BUFFER_HEADER_T *header, uint32_t id); + +/** Set metadata item in buffer header. + * This will store the metadata item into the buffer header. This operation can fail if not + * enough memory is available in the data section of the buffer header. + * + * @param header buffer header to store the metadata into + * @param metadata metadata item to store in buffer header + * + * @return MMAL_SUCCESS on success or MMAL_ENOMEM if not enough memory is available for storing + * the metadata + */ +MMAL_STATUS_T mmal_metadata_set(MMAL_BUFFER_HEADER_T *header, MMAL_METADATA_T *metadata); + +/* @} */ + +#endif /* MMAL_METADATA_H */ diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/mmal_parameters.h b/external_src/raspicam-0.1.3/dependencies/mmal/mmal_parameters.h new file mode 100644 index 0000000..67ffbda --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/mmal_parameters.h @@ -0,0 +1,194 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 MMAL_PARAMETERS_H +#define MMAL_PARAMETERS_H + +#include "mmal_common.h" +#include "mmal_parameters_camera.h" +#include "mmal_parameters_video.h" +#include "mmal_parameters_audio.h" +#include "mmal_parameters_clock.h" + +/** \defgroup MmalParameters List of pre-defined parameters + * This defines a list of standard parameters. Components can define proprietary + * parameters by creating a new group and defining their own structures. */ +/* @{ */ + +/** Generic unsigned 64-bit integer parameter type. */ +typedef struct MMAL_PARAMETER_UINT64_T +{ + MMAL_PARAMETER_HEADER_T hdr; + + uint64_t value; /**< Parameter value */ +} MMAL_PARAMETER_UINT64_T; + +/** Generic signed 64-bit integer parameter type. */ +typedef struct MMAL_PARAMETER_INT64_T +{ + MMAL_PARAMETER_HEADER_T hdr; + + int64_t value; /**< Parameter value */ +} MMAL_PARAMETER_INT64_T; + +/** Generic unsigned 32-bit integer parameter type. */ +typedef struct MMAL_PARAMETER_UINT32_T +{ + MMAL_PARAMETER_HEADER_T hdr; + + uint32_t value; /**< Parameter value */ +} MMAL_PARAMETER_UINT32_T; + +/** Generic signed 32-bit integer parameter type. */ +typedef struct MMAL_PARAMETER_INT32_T +{ + MMAL_PARAMETER_HEADER_T hdr; + + int32_t value; /**< Parameter value */ +} MMAL_PARAMETER_INT32_T; + +/** Generic rational parameter type. */ +typedef struct MMAL_PARAMETER_RATIONAL_T { + MMAL_PARAMETER_HEADER_T hdr; + + MMAL_RATIONAL_T value; /**< Parameter value */ +} MMAL_PARAMETER_RATIONAL_T; + +/** Generic boolean parameter type. */ +typedef struct MMAL_PARAMETER_BOOLEAN_T +{ + MMAL_PARAMETER_HEADER_T hdr; + + MMAL_BOOL_T enable; /**< Parameter value */ +} MMAL_PARAMETER_BOOLEAN_T; + +/** Generic string parameter type. */ +typedef struct MMAL_PARAMETER_STRING_T +{ + MMAL_PARAMETER_HEADER_T hdr; + + char str[1]; /**< Null-terminated string */ +} MMAL_PARAMETER_STRING_T; + +/** Generic array of bytes parameter type. */ +typedef struct MMAL_PARAMETER_BYTES_T +{ + MMAL_PARAMETER_HEADER_T hdr; + + uint8_t data[1]; /**< Array of bytes */ +} MMAL_PARAMETER_BYTES_T; + +/** The value 1 in 16.16 fixed point form */ +#define MMAL_FIXED_16_16_ONE (1 << 16) + +/** Generic two-dimensional scaling factor type. */ +typedef struct MMAL_PARAMETER_SCALEFACTOR_T +{ + MMAL_PARAMETER_HEADER_T hdr; + + MMAL_FIXED_16_16_T scale_x; /**< Scaling factor in X-axis */ + MMAL_FIXED_16_16_T scale_y; /**< Scaling factor in Y-axis */ +} MMAL_PARAMETER_SCALEFACTOR_T; + +/** Valid mirror modes */ +typedef enum MMAL_PARAM_MIRROR_T +{ + MMAL_PARAM_MIRROR_NONE, + MMAL_PARAM_MIRROR_VERTICAL, + MMAL_PARAM_MIRROR_HORIZONTAL, + MMAL_PARAM_MIRROR_BOTH, +} MMAL_PARAM_MIRROR_T; + +/** Generic mirror parameter type */ +typedef struct MMAL_PARAMETER_MIRROR_T +{ + MMAL_PARAMETER_HEADER_T hdr; + + MMAL_PARAM_MIRROR_T value; /**< Mirror mode */ +} MMAL_PARAMETER_MIRROR_T; + +/** URI parameter type. + * The parameter may hold an arbitrary length, nul-terminated string as long + * as the size is set appropriately. + */ +typedef struct MMAL_PARAMETER_URI_T +{ + MMAL_PARAMETER_HEADER_T hdr; + + char uri[1]; /**< URI string (null-terminated) */ +} MMAL_PARAMETER_URI_T; + +/** Generic encoding parameter type. + * The parameter may hold more than one encoding by overriding the size to + * include a bigger array. + */ +typedef struct MMAL_PARAMETER_ENCODING_T +{ + MMAL_PARAMETER_HEADER_T hdr; + + uint32_t encoding[1]; /**< Array of FourCC encodings, see \ref MmalEncodings */ +} MMAL_PARAMETER_ENCODING_T; + +/** Generic frame-rate parameter type. + * Frame rates are specified as a rational number, using a pair of integers. + * Since there can be many valid pairs for the same ratio, a frame-rate may + * not contain exactly the same pairs of values when read back as it was + * when set. + */ +typedef struct MMAL_PARAMETER_FRAME_RATE_T { + MMAL_PARAMETER_HEADER_T hdr; + + MMAL_RATIONAL_T frame_rate; /**< Frame-rate value */ +} MMAL_PARAMETER_FRAME_RATE_T; + +/** Generic configuration-file setup type. + * Configuration files are transferred in small chunks. The component can + * save all the chunks into a buffer, then process the entire file later. + * This parameter initialises a config file to have the given size. + */ +typedef struct MMAL_PARAMETER_CONFIGFILE_T { + MMAL_PARAMETER_HEADER_T hdr; + + uint32_t file_size; /**< Size of complete file data */ +} MMAL_PARAMETER_CONFIGFILE_T; + +/** Generic configuration-file chunk data type. + * Once a config file has been initialised, this parameter can be used to + * write an arbitrary chunk of the file data (limited by the maximum MMAL + * message size). + */ +typedef struct MMAL_PARAMETER_CONFIGFILE_CHUNK_T { + MMAL_PARAMETER_HEADER_T hdr; + + uint32_t size; /**< Number of bytes being transferred in this chunk */ + uint32_t offset; /**< Offset of this chunk in the file */ + char data[1]; /**< Chunk data */ +} MMAL_PARAMETER_CONFIGFILE_CHUNK_T; + +/* @} */ + +#endif /* MMAL_PARAMETERS_H */ diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/mmal_parameters_audio.h b/external_src/raspicam-0.1.3/dependencies/mmal/mmal_parameters_audio.h new file mode 100644 index 0000000..36625f6 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/mmal_parameters_audio.h @@ -0,0 +1,66 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 MMAL_PARAMETERS_AUDIO_H +#define MMAL_PARAMETERS_AUDIO_H + +#include "mmal_parameters_common.h" + +/************************************************* + * ALWAYS ADD NEW ENUMS AT THE END OF THIS LIST! * + ************************************************/ + +/** Audio-specific MMAL parameter IDs. + * @ingroup MMAL_PARAMETER_IDS + */ +enum +{ + MMAL_PARAMETER_AUDIO_DESTINATION /**< Takes a MMAL_PARAMETER_STRING_T */ + = MMAL_PARAMETER_GROUP_AUDIO, + MMAL_PARAMETER_AUDIO_LATENCY_TARGET, /**< Takes a MMAL_PARAMETER_AUDIO_LATENCY_TARGET_T */ + MMAL_PARAMETER_AUDIO_SOURCE, + MMAL_PARAMETER_AUDIO_PASSTHROUGH, /**< Takes a MMAL_PARAMETER_BOOLEAN_T */ +}; + +/** Audio latency target to maintain. + * These settings are used to adjust the clock speed in order + * to match the measured audio latency to a specified value. */ +typedef struct MMAL_PARAMETER_AUDIO_LATENCY_TARGET_T +{ + MMAL_PARAMETER_HEADER_T hdr; + + MMAL_BOOL_T enable; /**< whether this mode is enabled */ + uint32_t filter; /**< number of latency samples to filter on, good value: 1 */ + uint32_t target; /**< target latency (microseconds) */ + uint32_t shift; /**< shift for storing latency values, good value: 7 */ + int32_t speed_factor; /**< multiplier for speed changes, in 24.8 format, good value: 256-512 */ + int32_t inter_factor; /**< divider for comparing latency versus gradiant, good value: 300 */ + int32_t adj_cap; /**< limit for speed change before nSpeedFactor is applied, good value: 100 */ +} MMAL_PARAMETER_AUDIO_LATENCY_TARGET_T; + +#endif /* MMAL_PARAMETERS_AUDIO_H */ + diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/mmal_parameters_camera.h b/external_src/raspicam-0.1.3/dependencies/mmal/mmal_parameters_camera.h new file mode 100644 index 0000000..7e550a7 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/mmal_parameters_camera.h @@ -0,0 +1,755 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. +*/ + +/*============================================================================= +Copyright (c) 2011 Broadcom Europe Limited. +All rights reserved. +=============================================================================*/ +/** \file + * Multi-Media Abstraction Layer - Definition of some standard parameters. + */ + +#ifndef MMAL_PARAMETERS_CAMERA_H +#define MMAL_PARAMETERS_CAMERA_H + +#include "mmal_parameters_common.h" + +/************************************************* + * ALWAYS ADD NEW ENUMS AT THE END OF THIS LIST! * + ************************************************/ + +/** Camera-specific MMAL parameter IDs. + * @ingroup MMAL_PARAMETER_IDS + */ +enum { + /* 0 */ + MMAL_PARAMETER_THUMBNAIL_CONFIGURATION /**< Takes a @ref MMAL_PARAMETER_THUMBNAIL_CONFIG_T */ + = MMAL_PARAMETER_GROUP_CAMERA, + MMAL_PARAMETER_CAPTURE_QUALITY, /**< Unused? */ + MMAL_PARAMETER_ROTATION, /**< Takes a @ref MMAL_PARAMETER_INT32_T */ + MMAL_PARAMETER_EXIF_DISABLE, /**< Takes a @ref MMAL_PARAMETER_BOOLEAN_T */ + MMAL_PARAMETER_EXIF, /**< Takes a @ref MMAL_PARAMETER_EXIF_T */ + MMAL_PARAMETER_AWB_MODE, /**< Takes a @ref MMAL_PARAM_AWBMODE_T */ + MMAL_PARAMETER_IMAGE_EFFECT, /**< Takes a @ref MMAL_PARAMETER_IMAGEFX_T */ + MMAL_PARAMETER_COLOUR_EFFECT, /**< Takes a @ref MMAL_PARAMETER_COLOURFX_T */ + MMAL_PARAMETER_FLICKER_AVOID, /**< Takes a @ref MMAL_PARAMETER_FLICKERAVOID_T */ + MMAL_PARAMETER_FLASH, /**< Takes a @ref MMAL_PARAMETER_FLASH_T */ + MMAL_PARAMETER_REDEYE, /**< Takes a @ref MMAL_PARAMETER_REDEYE_T */ + MMAL_PARAMETER_FOCUS, /**< Takes a @ref MMAL_PARAMETER_FOCUS_T */ + MMAL_PARAMETER_FOCAL_LENGTHS, /**< Unused? */ + MMAL_PARAMETER_EXPOSURE_COMP, /**< Takes a @ref MMAL_PARAMETER_INT32_T or MMAL_PARAMETER_RATIONAL_T */ + MMAL_PARAMETER_ZOOM, /**< Takes a @ref MMAL_PARAMETER_SCALEFACTOR_T */ + MMAL_PARAMETER_MIRROR, /**< Takes a @ref MMAL_PARAMETER_MIRROR_T */ + + /* 0x10 */ + MMAL_PARAMETER_CAMERA_NUM, /**< Takes a @ref MMAL_PARAMETER_UINT32_T */ + MMAL_PARAMETER_CAPTURE, /**< Takes a @ref MMAL_PARAMETER_BOOLEAN_T */ + MMAL_PARAMETER_EXPOSURE_MODE, /**< Takes a @ref MMAL_PARAMETER_EXPOSUREMODE_T */ + MMAL_PARAMETER_EXP_METERING_MODE, /**< Takes a @ref MMAL_PARAMETER_EXPOSUREMETERINGMODE_T */ + MMAL_PARAMETER_FOCUS_STATUS, /**< Takes a @ref MMAL_PARAMETER_FOCUS_STATUS_T */ + MMAL_PARAMETER_CAMERA_CONFIG, /**< Takes a @ref MMAL_PARAMETER_CAMERA_CONFIG_T */ + MMAL_PARAMETER_CAPTURE_STATUS, /**< Takes a @ref MMAL_PARAMETER_CAPTURE_STATUS_T */ + MMAL_PARAMETER_FACE_TRACK, /**< Takes a @ref MMAL_PARAMETER_FACE_TRACK_T */ + MMAL_PARAMETER_DRAW_BOX_FACES_AND_FOCUS, /**< Takes a @ref MMAL_PARAMETER_BOOLEAN_T */ + MMAL_PARAMETER_JPEG_Q_FACTOR, /**< Takes a @ref MMAL_PARAMETER_UINT32_T */ + MMAL_PARAMETER_FRAME_RATE, /**< Takes a @ref MMAL_PARAMETER_FRAME_RATE_T */ + MMAL_PARAMETER_USE_STC, /**< Takes a @ref MMAL_PARAMETER_CAMERA_STC_MODE_T */ + MMAL_PARAMETER_CAMERA_INFO, /**< Takes a @ref MMAL_PARAMETER_CAMERA_INFO_T */ + MMAL_PARAMETER_VIDEO_STABILISATION, /**< Takes a @ref MMAL_PARAMETER_BOOLEAN_T */ + MMAL_PARAMETER_FACE_TRACK_RESULTS, /**< Takes a @ref MMAL_PARAMETER_FACE_TRACK_RESULTS_T */ + MMAL_PARAMETER_ENABLE_RAW_CAPTURE, /**< Takes a @ref MMAL_PARAMETER_BOOLEAN_T */ + + /* 0x20 */ + MMAL_PARAMETER_DPF_FILE, /**< Takes a @ref MMAL_PARAMETER_URI_T */ + MMAL_PARAMETER_ENABLE_DPF_FILE, /**< Takes a @ref MMAL_PARAMETER_BOOLEAN_T */ + MMAL_PARAMETER_DPF_FAIL_IS_FATAL, /**< Takes a @ref MMAL_PARAMETER_BOOLEAN_T */ + MMAL_PARAMETER_CAPTURE_MODE, /**< Takes a @ref MMAL_PARAMETER_CAPTUREMODE_T */ + MMAL_PARAMETER_FOCUS_REGIONS, /**< Takes a @ref MMAL_PARAMETER_FOCUS_REGIONS_T */ + MMAL_PARAMETER_INPUT_CROP, /**< Takes a @ref MMAL_PARAMETER_INPUT_CROP_T */ + MMAL_PARAMETER_SENSOR_INFORMATION, /**< Takes a @ref MMAL_PARAMETER_SENSOR_INFORMATION_T */ + MMAL_PARAMETER_FLASH_SELECT, /**< Takes a @ref MMAL_PARAMETER_FLASH_SELECT_T */ + MMAL_PARAMETER_FIELD_OF_VIEW, /**< Takes a @ref MMAL_PARAMETER_FIELD_OF_VIEW_T */ + MMAL_PARAMETER_HIGH_DYNAMIC_RANGE, /**< Takes a @ref MMAL_PARAMETER_BOOLEAN_T */ + MMAL_PARAMETER_DYNAMIC_RANGE_COMPRESSION, /**< Takes a @ref MMAL_PARAMETER_DRC_T */ + MMAL_PARAMETER_ALGORITHM_CONTROL, /**< Takes a @ref MMAL_PARAMETER_ALGORITHM_CONTROL_T */ + MMAL_PARAMETER_SHARPNESS, /**< Takes a @ref MMAL_PARAMETER_RATIONAL_T */ + MMAL_PARAMETER_CONTRAST, /**< Takes a @ref MMAL_PARAMETER_RATIONAL_T */ + MMAL_PARAMETER_BRIGHTNESS, /**< Takes a @ref MMAL_PARAMETER_RATIONAL_T */ + MMAL_PARAMETER_SATURATION, /**< Takes a @ref MMAL_PARAMETER_RATIONAL_T */ + + /* 0x30 */ + MMAL_PARAMETER_ISO, /**< Takes a @ref MMAL_PARAMETER_UINT32_T */ + MMAL_PARAMETER_ANTISHAKE, /**< Takes a @ref MMAL_PARAMETER_BOOLEAN_T */ + MMAL_PARAMETER_IMAGE_EFFECT_PARAMETERS, /**< Takes a @ref MMAL_PARAMETER_IMAGEFX_PARAMETERS_T */ + MMAL_PARAMETER_CAMERA_BURST_CAPTURE, /**< Takes a @ref MMAL_PARAMETER_BOOLEAN_T */ + MMAL_PARAMETER_CAMERA_MIN_ISO, /**< Takes a @ref MMAL_PARAMETER_UINT32_T */ + MMAL_PARAMETER_CAMERA_USE_CASE, /**< Takes a @ref MMAL_PARAMETER_CAMERA_USE_CASE_T */ + MMAL_PARAMETER_CAPTURE_STATS_PASS, /**< Takes a @ref MMAL_PARAMETER_BOOLEAN_T */ + MMAL_PARAMETER_CAMERA_CUSTOM_SENSOR_CONFIG, /**< Takes a @ref MMAL_PARAMETER_UINT32_T */ + MMAL_PARAMETER_ENABLE_REGISTER_FILE, /**< Takes a @ref MMAL_PARAMETER_BOOLEAN_T */ + MMAL_PARAMETER_REGISTER_FAIL_IS_FATAL, /**< Takes a @ref MMAL_PARAMETER_BOOLEAN_T */ + MMAL_PARAMETER_CONFIGFILE_REGISTERS, /**< Takes a @ref MMAL_PARAMETER_CONFIGFILE_T */ + MMAL_PARAMETER_CONFIGFILE_CHUNK_REGISTERS,/**< Takes a @ref MMAL_PARAMETER_CONFIGFILE_CHUNK_T */ + MMAL_PARAMETER_JPEG_ATTACH_LOG, /**< Takes a @ref MMAL_PARAMETER_BOOLEAN_T */ + MMAL_PARAMETER_ZERO_SHUTTER_LAG, /**< Takes a @ref MMAL_PARAMETER_ZEROSHUTTERLAG_T */ + MMAL_PARAMETER_FPS_RANGE, /**< Takes a @ref MMAL_PARAMETER_FPS_RANGE_T */ + MMAL_PARAMETER_CAPTURE_EXPOSURE_COMP, /**< Takes a @ref MMAL_PARAMETER_INT32_T */ + + /* 0x40 */ + MMAL_PARAMETER_SW_SHARPEN_DISABLE, /**< Takes a @ref MMAL_PARAMETER_BOOLEAN_T */ + MMAL_PARAMETER_FLASH_REQUIRED, /**< Takes a @ref MMAL_PARAMETER_BOOLEAN_T */ + MMAL_PARAMETER_SW_SATURATION_DISABLE, /**< Takes a @ref MMAL_PARAMETER_BOOLEAN_T */ + MMAL_PARAMETER_SHUTTER_SPEED, /**< Takes a @ref MMAL_PARAMETER_UINT32_T */ + MMAL_PARAMETER_CUSTOM_AWB_GAINS, /**< Takes a @ref MMAL_PARAMETER_AWB_GAINS_T */ + MMAL_PARAMETER_CAMERA_SETTINGS, /**< Takes a @ref MMAL_PARAMETER_CAMERA_SETTINGS_T */ + MMAL_PARAMETER_PRIVACY_INDICATOR, /**< Takes a @ref MMAL_PARAMETER_PRIVACY_INDICATOR_T */ + MMAL_PARAMETER_VIDEO_DENOISE, /**< Takes a @ref MMAL_PARAMETER_BOOLEAN_T */ + MMAL_PARAMETER_STILLS_DENOISE, /**< Takes a @ref MMAL_PARAMETER_BOOLEAN_T */ + MMAL_PARAMETER_ANNOTATE, /**< Takes a @ref MMAL_PARAMETER_CAMERA_ANNOTATE_T */ + MMAL_PARAMETER_STEREOSCOPIC_MODE, /**< Takes a @ref MMAL_PARAMETER_STEREOSCOPIC_MODE_T */ +}; + +/** Thumbnail configuration parameter type */ +typedef struct MMAL_PARAMETER_THUMBNAIL_CONFIG_T +{ + MMAL_PARAMETER_HEADER_T hdr; + + uint32_t enable; /**< Enable generation of thumbnails during still capture */ + uint32_t width; /**< Desired width of the thumbnail */ + uint32_t height; /**< Desired height of the thumbnail */ + uint32_t quality; /**< Desired compression quality of the thumbnail */ +} MMAL_PARAMETER_THUMBNAIL_CONFIG_T; + +/** EXIF parameter type. */ +typedef struct MMAL_PARAMETER_EXIF_T +{ + MMAL_PARAMETER_HEADER_T hdr; + + uint32_t keylen; /**< If 0, assume key is terminated by '=', otherwise length of key and treat data as binary */ + uint32_t value_offset; /**< Offset within data buffer of the start of the value. If 0, look for a "key=value" string */ + uint32_t valuelen; /**< If 0, assume value is null-terminated, otherwise length of value and treat data as binary */ + uint8_t data[1]; /**< EXIF key/value string. Variable length */ +} MMAL_PARAMETER_EXIF_T; + +/** Exposure modes. */ +typedef enum +{ + MMAL_PARAM_EXPOSUREMODE_OFF, + MMAL_PARAM_EXPOSUREMODE_AUTO, + MMAL_PARAM_EXPOSUREMODE_NIGHT, + MMAL_PARAM_EXPOSUREMODE_NIGHTPREVIEW, + MMAL_PARAM_EXPOSUREMODE_BACKLIGHT, + MMAL_PARAM_EXPOSUREMODE_SPOTLIGHT, + MMAL_PARAM_EXPOSUREMODE_SPORTS, + MMAL_PARAM_EXPOSUREMODE_SNOW, + MMAL_PARAM_EXPOSUREMODE_BEACH, + MMAL_PARAM_EXPOSUREMODE_VERYLONG, + MMAL_PARAM_EXPOSUREMODE_FIXEDFPS, + MMAL_PARAM_EXPOSUREMODE_ANTISHAKE, + MMAL_PARAM_EXPOSUREMODE_FIREWORKS, + MMAL_PARAM_EXPOSUREMODE_MAX = 0x7fffffff +} MMAL_PARAM_EXPOSUREMODE_T; + +typedef struct MMAL_PARAMETER_EXPOSUREMODE_T +{ + MMAL_PARAMETER_HEADER_T hdr; + + MMAL_PARAM_EXPOSUREMODE_T value; /**< exposure mode */ +} MMAL_PARAMETER_EXPOSUREMODE_T; + +typedef enum +{ + MMAL_PARAM_EXPOSUREMETERINGMODE_AVERAGE, + MMAL_PARAM_EXPOSUREMETERINGMODE_SPOT, + MMAL_PARAM_EXPOSUREMETERINGMODE_BACKLIT, + MMAL_PARAM_EXPOSUREMETERINGMODE_MATRIX, + MMAL_PARAM_EXPOSUREMETERINGMODE_MAX = 0x7fffffff +} MMAL_PARAM_EXPOSUREMETERINGMODE_T; + +typedef struct MMAL_PARAMETER_EXPOSUREMETERINGMODE_T +{ + MMAL_PARAMETER_HEADER_T hdr; + + MMAL_PARAM_EXPOSUREMETERINGMODE_T value; /**< metering mode */ +} MMAL_PARAMETER_EXPOSUREMETERINGMODE_T; + +/** AWB parameter modes. */ +typedef enum MMAL_PARAM_AWBMODE_T +{ + MMAL_PARAM_AWBMODE_OFF, + MMAL_PARAM_AWBMODE_AUTO, + MMAL_PARAM_AWBMODE_SUNLIGHT, + MMAL_PARAM_AWBMODE_CLOUDY, + MMAL_PARAM_AWBMODE_SHADE, + MMAL_PARAM_AWBMODE_TUNGSTEN, + MMAL_PARAM_AWBMODE_FLUORESCENT, + MMAL_PARAM_AWBMODE_INCANDESCENT, + MMAL_PARAM_AWBMODE_FLASH, + MMAL_PARAM_AWBMODE_HORIZON, + MMAL_PARAM_AWBMODE_MAX = 0x7fffffff +} MMAL_PARAM_AWBMODE_T; + +/** AWB parameter type. */ +typedef struct MMAL_PARAMETER_AWBMODE_T +{ + MMAL_PARAMETER_HEADER_T hdr; + + MMAL_PARAM_AWBMODE_T value; /**< AWB mode */ +} MMAL_PARAMETER_AWBMODE_T; + +/** Image effect */ +typedef enum MMAL_PARAM_IMAGEFX_T +{ + MMAL_PARAM_IMAGEFX_NONE, + MMAL_PARAM_IMAGEFX_NEGATIVE, + MMAL_PARAM_IMAGEFX_SOLARIZE, + MMAL_PARAM_IMAGEFX_POSTERIZE, + MMAL_PARAM_IMAGEFX_WHITEBOARD, + MMAL_PARAM_IMAGEFX_BLACKBOARD, + MMAL_PARAM_IMAGEFX_SKETCH, + MMAL_PARAM_IMAGEFX_DENOISE, + MMAL_PARAM_IMAGEFX_EMBOSS, + MMAL_PARAM_IMAGEFX_OILPAINT, + MMAL_PARAM_IMAGEFX_HATCH, + MMAL_PARAM_IMAGEFX_GPEN, + MMAL_PARAM_IMAGEFX_PASTEL, + MMAL_PARAM_IMAGEFX_WATERCOLOUR, + MMAL_PARAM_IMAGEFX_FILM, + MMAL_PARAM_IMAGEFX_BLUR, + MMAL_PARAM_IMAGEFX_SATURATION, + MMAL_PARAM_IMAGEFX_COLOURSWAP, + MMAL_PARAM_IMAGEFX_WASHEDOUT, + MMAL_PARAM_IMAGEFX_POSTERISE, + MMAL_PARAM_IMAGEFX_COLOURPOINT, + MMAL_PARAM_IMAGEFX_COLOURBALANCE, + MMAL_PARAM_IMAGEFX_CARTOON, + MMAL_PARAM_IMAGEFX_DEINTERLACE_DOUBLE, + MMAL_PARAM_IMAGEFX_DEINTERLACE_ADV, + MMAL_PARAM_IMAGEFX_DEINTERLACE_FAST, + MMAL_PARAM_IMAGEFX_MAX = 0x7fffffff +} MMAL_PARAM_IMAGEFX_T; + +typedef struct MMAL_PARAMETER_IMAGEFX_T +{ + MMAL_PARAMETER_HEADER_T hdr; + + MMAL_PARAM_IMAGEFX_T value; /**< Image effect mode */ +} MMAL_PARAMETER_IMAGEFX_T; + +#define MMAL_MAX_IMAGEFX_PARAMETERS 6 /* Image effects library currently uses a maximum of 5 parameters per effect */ + +typedef struct MMAL_PARAMETER_IMAGEFX_PARAMETERS_T +{ + MMAL_PARAMETER_HEADER_T hdr; + + MMAL_PARAM_IMAGEFX_T effect; /**< Image effect mode */ + uint32_t num_effect_params; /**< Number of used elements in */ + uint32_t effect_parameter[MMAL_MAX_IMAGEFX_PARAMETERS]; /**< Array of parameters */ +} MMAL_PARAMETER_IMAGEFX_PARAMETERS_T; + +/** Colour effect parameter type*/ +typedef struct MMAL_PARAMETER_COLOURFX_T +{ + MMAL_PARAMETER_HEADER_T hdr; + + int32_t enable; + uint32_t u; + uint32_t v; +} MMAL_PARAMETER_COLOURFX_T; + +typedef enum MMAL_CAMERA_STC_MODE_T +{ + MMAL_PARAM_STC_MODE_OFF, /**< Frames do not have STCs, as needed in OpenMAX/IL */ + MMAL_PARAM_STC_MODE_RAW, /**< Use raw clock STC, needed for true pause/resume support */ + MMAL_PARAM_STC_MODE_COOKED, /**< Start the STC from the start of capture, only for quick demo code */ + MMAL_PARAM_STC_MODE_MAX = 0x7fffffff +} MMAL_CAMERA_STC_MODE_T; + +typedef struct MMAL_PARAMETER_CAMERA_STC_MODE_T +{ + MMAL_PARAMETER_HEADER_T hdr; + MMAL_CAMERA_STC_MODE_T value; +} MMAL_PARAMETER_CAMERA_STC_MODE_T; + +typedef enum MMAL_PARAM_FLICKERAVOID_T +{ + MMAL_PARAM_FLICKERAVOID_OFF, + MMAL_PARAM_FLICKERAVOID_AUTO, + MMAL_PARAM_FLICKERAVOID_50HZ, + MMAL_PARAM_FLICKERAVOID_60HZ, + MMAL_PARAM_FLICKERAVOID_MAX = 0x7FFFFFFF +} MMAL_PARAM_FLICKERAVOID_T; + +typedef struct MMAL_PARAMETER_FLICKERAVOID_T +{ + MMAL_PARAMETER_HEADER_T hdr; + + MMAL_PARAM_FLICKERAVOID_T value; /**< Flicker avoidance mode */ +} MMAL_PARAMETER_FLICKERAVOID_T; + +typedef enum MMAL_PARAM_FLASH_T +{ + MMAL_PARAM_FLASH_OFF, + MMAL_PARAM_FLASH_AUTO, + MMAL_PARAM_FLASH_ON, + MMAL_PARAM_FLASH_REDEYE, + MMAL_PARAM_FLASH_FILLIN, + MMAL_PARAM_FLASH_TORCH, + MMAL_PARAM_FLASH_MAX = 0x7FFFFFFF +} MMAL_PARAM_FLASH_T; + +typedef struct MMAL_PARAMETER_FLASH_T +{ + MMAL_PARAMETER_HEADER_T hdr; + + MMAL_PARAM_FLASH_T value; /**< Flash mode */ +} MMAL_PARAMETER_FLASH_T; + +typedef enum MMAL_PARAM_REDEYE_T +{ + MMAL_PARAM_REDEYE_OFF, + MMAL_PARAM_REDEYE_ON, + MMAL_PARAM_REDEYE_SIMPLE, + MMAL_PARAM_REDEYE_MAX = 0x7FFFFFFF +} MMAL_PARAM_REDEYE_T; + +typedef struct MMAL_PARAMETER_REDEYE_T +{ + MMAL_PARAMETER_HEADER_T hdr; + + MMAL_PARAM_REDEYE_T value; /**< Red eye reduction mode */ +} MMAL_PARAMETER_REDEYE_T; + +typedef enum MMAL_PARAM_FOCUS_T +{ + MMAL_PARAM_FOCUS_AUTO, + MMAL_PARAM_FOCUS_AUTO_NEAR, + MMAL_PARAM_FOCUS_AUTO_MACRO, + MMAL_PARAM_FOCUS_CAF, + MMAL_PARAM_FOCUS_CAF_NEAR, + MMAL_PARAM_FOCUS_FIXED_INFINITY, + MMAL_PARAM_FOCUS_FIXED_HYPERFOCAL, + MMAL_PARAM_FOCUS_FIXED_NEAR, + MMAL_PARAM_FOCUS_FIXED_MACRO, + MMAL_PARAM_FOCUS_EDOF, + MMAL_PARAM_FOCUS_CAF_MACRO, + MMAL_PARAM_FOCUS_CAF_FAST, + MMAL_PARAM_FOCUS_CAF_NEAR_FAST, + MMAL_PARAM_FOCUS_CAF_MACRO_FAST, + MMAL_PARAM_FOCUS_FIXED_CURRENT, + MMAL_PARAM_FOCUS_MAX = 0x7FFFFFFF +} MMAL_PARAM_FOCUS_T; + +typedef struct MMAL_PARAMETER_FOCUS_T +{ + MMAL_PARAMETER_HEADER_T hdr; + + MMAL_PARAM_FOCUS_T value; /**< Focus mode */ +} MMAL_PARAMETER_FOCUS_T; + +typedef enum MMAL_PARAM_CAPTURE_STATUS_T +{ + MMAL_PARAM_CAPTURE_STATUS_NOT_CAPTURING, + MMAL_PARAM_CAPTURE_STATUS_CAPTURE_STARTED, + MMAL_PARAM_CAPTURE_STATUS_CAPTURE_ENDED, + + MMAL_PARAM_CAPTURE_STATUS_MAX = 0x7FFFFFFF +} MMAL_PARAM_CAPTURE_STATUS_T; + +typedef struct MMAL_PARAMETER_CAPTURE_STATUS_T +{ + MMAL_PARAMETER_HEADER_T hdr; + + MMAL_PARAM_CAPTURE_STATUS_T status; /**< Capture status */ +} MMAL_PARAMETER_CAPTURE_STATUS_T; + +typedef enum MMAL_PARAM_FOCUS_STATUS_T +{ + MMAL_PARAM_FOCUS_STATUS_OFF, + MMAL_PARAM_FOCUS_STATUS_REQUEST, + MMAL_PARAM_FOCUS_STATUS_REACHED, + MMAL_PARAM_FOCUS_STATUS_UNABLE_TO_REACH, + MMAL_PARAM_FOCUS_STATUS_LOST, + MMAL_PARAM_FOCUS_STATUS_CAF_MOVING, + MMAL_PARAM_FOCUS_STATUS_CAF_SUCCESS, + MMAL_PARAM_FOCUS_STATUS_CAF_FAILED, + MMAL_PARAM_FOCUS_STATUS_MANUAL_MOVING, + MMAL_PARAM_FOCUS_STATUS_MANUAL_REACHED, + MMAL_PARAM_FOCUS_STATUS_CAF_WATCHING, + MMAL_PARAM_FOCUS_STATUS_CAF_SCENE_CHANGED, + + MMAL_PARAM_FOCUS_STATUS_MAX = 0x7FFFFFFF +} MMAL_PARAM_FOCUS_STATUS_T; + +typedef struct MMAL_PARAMETER_FOCUS_STATUS_T +{ + MMAL_PARAMETER_HEADER_T hdr; + + MMAL_PARAM_FOCUS_STATUS_T status; /**< Focus status */ +} MMAL_PARAMETER_FOCUS_STATUS_T; + +typedef enum MMAL_PARAM_FACE_TRACK_MODE_T +{ + MMAL_PARAM_FACE_DETECT_NONE, /**< Disables face detection */ + MMAL_PARAM_FACE_DETECT_ON, /**< Enables face detection */ + MMAL_PARAM_FACE_DETECT_MAX = 0x7FFFFFFF +} MMAL_PARAM_FACE_TRACK_MODE_T; + +typedef struct MMAL_PARAMETER_FACE_TRACK_T /* face tracking control */ +{ + MMAL_PARAMETER_HEADER_T hdr; + MMAL_PARAM_FACE_TRACK_MODE_T mode; + uint32_t maxRegions; + uint32_t frames; + uint32_t quality; +} MMAL_PARAMETER_FACE_TRACK_T; + +typedef struct MMAL_PARAMETER_FACE_TRACK_FACE_T /* face tracking face information */ +{ + int32_t face_id; /**< Face ID. Should remain the same whilst the face is detected to remain in the scene */ + int32_t score; /**< Confidence of the face detection. Range 1-100 (1=unsure, 100=positive). */ + MMAL_RECT_T face_rect; /**< Rectangle around the whole face */ + + MMAL_RECT_T eye_rect[2]; /**< Rectangle around the eyes ([0] = left eye, [1] = right eye) */ + MMAL_RECT_T mouth_rect; /**< Rectangle around the mouth */ +} MMAL_PARAMETER_FACE_TRACK_FACE_T; + +typedef struct MMAL_PARAMETER_FACE_TRACK_RESULTS_T /* face tracking results */ +{ + MMAL_PARAMETER_HEADER_T hdr; + + uint32_t num_faces; /**< Number of faces detected */ + uint32_t frame_width; /**< Width of the frame on which the faces were detected (allows scaling) */ + uint32_t frame_height; /**< Height of the frame on which the faces were detected (allows scaling) */ + + MMAL_PARAMETER_FACE_TRACK_FACE_T faces[1]; /**< Face information (variable length array */ +} MMAL_PARAMETER_FACE_TRACK_RESULTS_T; + +typedef enum MMAL_PARAMETER_CAMERA_CONFIG_TIMESTAMP_MODE_T +{ + MMAL_PARAM_TIMESTAMP_MODE_ZERO, /**< Always timestamp frames as 0 */ + MMAL_PARAM_TIMESTAMP_MODE_RAW_STC, /**< Use the raw STC value for the frame timestamp */ + MMAL_PARAM_TIMESTAMP_MODE_RESET_STC, /**< Use the STC timestamp but subtract the timestamp + * of the first frame sent to give a zero based timestamp. + */ + MMAL_PARAM_TIMESTAMP_MODE_MAX = 0x7FFFFFFF +} MMAL_PARAMETER_CAMERA_CONFIG_TIMESTAMP_MODE_T; + +typedef struct MMAL_PARAMETER_CAMERA_CONFIG_T +{ + MMAL_PARAMETER_HEADER_T hdr; + + /* Parameters for setting up the image pools */ + uint32_t max_stills_w; /**< Max size of stills capture */ + uint32_t max_stills_h; + uint32_t stills_yuv422; /**< Allow YUV422 stills capture */ + uint32_t one_shot_stills; /**< Continuous or one shot stills captures. */ + + uint32_t max_preview_video_w; /**< Max size of the preview or video capture frames */ + uint32_t max_preview_video_h; + uint32_t num_preview_video_frames; + + uint32_t stills_capture_circular_buffer_height; /**< Sets the height of the circular buffer for stills capture. */ + + uint32_t fast_preview_resume; /**< Allows preview/encode to resume as fast as possible after the stills input frame + * has been received, and then processes the still frame in the background + * whilst preview/encode has resumed. + * Actual mode is controlled by MMAL_PARAMETER_CAPTURE_MODE. + */ + + MMAL_PARAMETER_CAMERA_CONFIG_TIMESTAMP_MODE_T use_stc_timestamp; + /**< Selects algorithm for timestamping frames if there is no clock component connected. + */ + + +} MMAL_PARAMETER_CAMERA_CONFIG_T; + +#define MMAL_PARAMETER_CAMERA_INFO_MAX_CAMERAS 4 +#define MMAL_PARAMETER_CAMERA_INFO_MAX_FLASHES 2 + +typedef struct MMAL_PARAMETER_CAMERA_INFO_CAMERA_T +{ + uint32_t port_id; + uint32_t max_width; + uint32_t max_height; + MMAL_BOOL_T lens_present; +} MMAL_PARAMETER_CAMERA_INFO_CAMERA_T; + +typedef enum MMAL_PARAMETER_CAMERA_INFO_FLASH_TYPE_T +{ + MMAL_PARAMETER_CAMERA_INFO_FLASH_TYPE_XENON = 0, /* Make values explicit */ + MMAL_PARAMETER_CAMERA_INFO_FLASH_TYPE_LED = 1, /* to ensure they match */ + MMAL_PARAMETER_CAMERA_INFO_FLASH_TYPE_OTHER = 2, /* values in config ini */ + MMAL_PARAMETER_CAMERA_INFO_FLASH_TYPE_MAX = 0x7FFFFFFF +} MMAL_PARAMETER_CAMERA_INFO_FLASH_TYPE_T; + +typedef struct MMAL_PARAMETER_CAMERA_INFO_FLASH_T +{ + MMAL_PARAMETER_CAMERA_INFO_FLASH_TYPE_T flash_type; +} MMAL_PARAMETER_CAMERA_INFO_FLASH_T; + +typedef struct MMAL_PARAMETER_CAMERA_INFO_T +{ + MMAL_PARAMETER_HEADER_T hdr; + uint32_t num_cameras; + uint32_t num_flashes; + MMAL_PARAMETER_CAMERA_INFO_CAMERA_T cameras[MMAL_PARAMETER_CAMERA_INFO_MAX_CAMERAS]; + MMAL_PARAMETER_CAMERA_INFO_FLASH_T flashes[MMAL_PARAMETER_CAMERA_INFO_MAX_FLASHES]; +} MMAL_PARAMETER_CAMERA_INFO_T; + +typedef enum MMAL_PARAMETER_CAPTUREMODE_MODE_T +{ + MMAL_PARAM_CAPTUREMODE_WAIT_FOR_END, /**< Resumes preview once capture is completed. */ + MMAL_PARAM_CAPTUREMODE_WAIT_FOR_END_AND_HOLD, /**< Resumes preview once capture is completed, and hold the image for subsequent reprocessing. */ + MMAL_PARAM_CAPTUREMODE_RESUME_VF_IMMEDIATELY, /**< Resumes preview as soon as possible once capture frame is received from the sensor. + * Requires fast_preview_resume to be set via MMAL_PARAMETER_CAMERA_CONFIG. + */ +} MMAL_PARAMETER_CAPTUREMODE_MODE_T; + +/** Stills capture mode control. */ +typedef struct MMAL_PARAMETER_CAPTUREMODE_T +{ + MMAL_PARAMETER_HEADER_T hdr; + MMAL_PARAMETER_CAPTUREMODE_MODE_T mode; +} MMAL_PARAMETER_CAPTUREMODE_T; + +typedef enum MMAL_PARAMETER_FOCUS_REGION_TYPE_T +{ + MMAL_PARAMETER_FOCUS_REGION_TYPE_NORMAL, /**< Region defines a generic region */ + MMAL_PARAMETER_FOCUS_REGION_TYPE_FACE, /**< Region defines a face */ + MMAL_PARAMETER_FOCUS_REGION_TYPE_MAX +} MMAL_PARAMETER_FOCUS_REGION_TYPE_T; + +typedef struct MMAL_PARAMETER_FOCUS_REGION_T +{ + MMAL_RECT_T rect; /**< Focus rectangle as 0P16 fixed point values. */ + uint32_t weight; /**< Region weighting. */ + uint32_t mask; /**< Mask for multi-stage regions */ + MMAL_PARAMETER_FOCUS_REGION_TYPE_T type; /**< Region type */ +} MMAL_PARAMETER_FOCUS_REGION_T; + +typedef struct MMAL_PARAMETER_FOCUS_REGIONS_T +{ + MMAL_PARAMETER_HEADER_T hdr; + uint32_t num_regions; /**< Number of regions defined */ + MMAL_BOOL_T lock_to_faces; /**< If region is within tolerance of a face, adopt face rect instead of defined region */ + MMAL_PARAMETER_FOCUS_REGION_T regions[1]; /**< Variable number of regions */ +} MMAL_PARAMETER_FOCUS_REGIONS_T; + +typedef struct MMAL_PARAMETER_INPUT_CROP_T +{ + MMAL_PARAMETER_HEADER_T hdr; + MMAL_RECT_T rect; /**< Crop rectangle as 16P16 fixed point values */ +} MMAL_PARAMETER_INPUT_CROP_T; + +typedef struct MMAL_PARAMETER_SENSOR_INFORMATION_T +{ + MMAL_PARAMETER_HEADER_T hdr; + MMAL_RATIONAL_T f_number; /**< Lens f-number */ + MMAL_RATIONAL_T focal_length; /**< Lens focal length */ + uint32_t model_id; /**< Sensor reported model id */ + uint32_t manufacturer_id; /**< Sensor reported manufacturer id */ + uint32_t revision; /**< Sensor reported revision */ +} MMAL_PARAMETER_SENSOR_INFORMATION_T; + +typedef struct MMAL_PARAMETER_FLASH_SELECT_T +{ + MMAL_PARAMETER_HEADER_T hdr; + MMAL_PARAMETER_CAMERA_INFO_FLASH_TYPE_T flash_type; /**< Flash type to use */ +} MMAL_PARAMETER_FLASH_SELECT_T; + +typedef struct MMAL_PARAMETER_FIELD_OF_VIEW_T +{ + MMAL_PARAMETER_HEADER_T hdr; + MMAL_RATIONAL_T fov_h; /**< Horizontal field of view */ + MMAL_RATIONAL_T fov_v; /**< Vertical field of view */ +} MMAL_PARAMETER_FIELD_OF_VIEW_T; + +typedef enum MMAL_PARAMETER_DRC_STRENGTH_T +{ + MMAL_PARAMETER_DRC_STRENGTH_OFF, + MMAL_PARAMETER_DRC_STRENGTH_LOW, + MMAL_PARAMETER_DRC_STRENGTH_MEDIUM, + MMAL_PARAMETER_DRC_STRENGTH_HIGH, + MMAL_PARAMETER_DRC_STRENGTH_MAX = 0x7fffffff +} MMAL_PARAMETER_DRC_STRENGTH_T; + +typedef struct MMAL_PARAMETER_DRC_T +{ + MMAL_PARAMETER_HEADER_T hdr; + MMAL_PARAMETER_DRC_STRENGTH_T strength; /**< DRC strength */ +} MMAL_PARAMETER_DRC_T; + +typedef enum MMAL_PARAMETER_ALGORITHM_CONTROL_ALGORITHMS_T +{ + MMAL_PARAMETER_ALGORITHM_CONTROL_ALGORITHMS_FACETRACKING, + MMAL_PARAMETER_ALGORITHM_CONTROL_ALGORITHMS_REDEYE_REDUCTION, + MMAL_PARAMETER_ALGORITHM_CONTROL_ALGORITHMS_VIDEO_STABILISATION, + MMAL_PARAMETER_ALGORITHM_CONTROL_ALGORITHMS_WRITE_RAW, + MMAL_PARAMETER_ALGORITHM_CONTROL_ALGORITHMS_VIDEO_DENOISE, + MMAL_PARAMETER_ALGORITHM_CONTROL_ALGORITHMS_STILLS_DENOISE, + MMAL_PARAMETER_ALGORITHM_CONTROL_ALGORITHMS_TEMPORAL_DENOISE, + MMAL_PARAMETER_ALGORITHM_CONTROL_ALGORITHMS_ANTISHAKE, + MMAL_PARAMETER_ALGORITHM_CONTROL_ALGORITHMS_IMAGE_EFFECTS, + MMAL_PARAMETER_ALGORITHM_CONTROL_ALGORITHMS_DYNAMIC_RANGE_COMPRESSION, + MMAL_PARAMETER_ALGORITHM_CONTROL_ALGORITHMS_FACE_RECOGNITION, + MMAL_PARAMETER_ALGORITHM_CONTROL_ALGORITHMS_FACE_BEAUTIFICATION, + MMAL_PARAMETER_ALGORITHM_CONTROL_ALGORITHMS_SCENE_DETECTION, + MMAL_PARAMETER_ALGORITHM_CONTROL_ALGORITHMS_HIGH_DYNAMIC_RANGE, + MMAL_PARAMETER_ALGORITHM_CONTROL_ALGORITHMS_MAX = 0x7fffffff +} MMAL_PARAMETER_ALGORITHM_CONTROL_ALGORITHMS_T; + +typedef struct MMAL_PARAMETER_ALGORITHM_CONTROL_T +{ + MMAL_PARAMETER_HEADER_T hdr; + MMAL_PARAMETER_ALGORITHM_CONTROL_ALGORITHMS_T algorithm; + MMAL_BOOL_T enabled; +} MMAL_PARAMETER_ALGORITHM_CONTROL_T; + + +typedef enum MMAL_PARAM_CAMERA_USE_CASE_T +{ + MMAL_PARAM_CAMERA_USE_CASE_UNKNOWN, /**< Compromise on behaviour as use case totally unknown */ + MMAL_PARAM_CAMERA_USE_CASE_STILLS_CAPTURE, /**< Stills capture use case */ + MMAL_PARAM_CAMERA_USE_CASE_VIDEO_CAPTURE, /**< Video encode (camcorder) use case */ + + MMAL_PARAM_CAMERA_USE_CASE_MAX = 0x7fffffff +} MMAL_PARAM_CAMERA_USE_CASE_T; + +typedef struct MMAL_PARAMETER_CAMERA_USE_CASE_T +{ + MMAL_PARAMETER_HEADER_T hdr; + + MMAL_PARAM_CAMERA_USE_CASE_T use_case; /**< Use case */ +} MMAL_PARAMETER_CAMERA_USE_CASE_T; + +typedef struct MMAL_PARAMETER_FPS_RANGE_T +{ + MMAL_PARAMETER_HEADER_T hdr; + + MMAL_RATIONAL_T fps_low; /**< Low end of the permitted framerate range */ + MMAL_RATIONAL_T fps_high; /**< High end of the permitted framerate range */ +} MMAL_PARAMETER_FPS_RANGE_T; + +typedef struct MMAL_PARAMETER_ZEROSHUTTERLAG_T +{ + MMAL_PARAMETER_HEADER_T hdr; + + MMAL_BOOL_T zero_shutter_lag_mode; /**< Select zero shutter lag mode from sensor */ + MMAL_BOOL_T concurrent_capture; /**< Activate full zero shutter lag mode and + * use the last preview raw image for the stills capture + */ +} MMAL_PARAMETER_ZEROSHUTTERLAG_T; + +typedef struct MMAL_PARAMETER_AWB_GAINS_T +{ + MMAL_PARAMETER_HEADER_T hdr; + + MMAL_RATIONAL_T r_gain; /**< Red gain */ + MMAL_RATIONAL_T b_gain; /**< Blue gain */ +} MMAL_PARAMETER_AWB_GAINS_T; + +typedef struct MMAL_PARAMETER_CAMERA_SETTINGS_T +{ + MMAL_PARAMETER_HEADER_T hdr; + + uint32_t exposure; + MMAL_RATIONAL_T analog_gain; + MMAL_RATIONAL_T digital_gain; + MMAL_RATIONAL_T awb_red_gain; + MMAL_RATIONAL_T awb_blue_gain; + uint32_t focus_position; +} MMAL_PARAMETER_CAMERA_SETTINGS_T; + +typedef enum MMAL_PARAM_PRIVACY_INDICATOR_T +{ + MMAL_PARAMETER_PRIVACY_INDICATOR_OFF, /**< Indicator will be off. */ + MMAL_PARAMETER_PRIVACY_INDICATOR_ON, /**< Indicator will come on just after a stills capture and + * and remain on for 2seconds, or will be on whilst output[1] + * is actively producing images. + */ + MMAL_PARAMETER_PRIVACY_INDICATOR_FORCE_ON, /**< Turns indicator of for 2s independent of capture status. + * Set this mode repeatedly to keep the indicator on for a + * longer period. + */ + MMAL_PARAMETER_PRIVACY_INDICATOR_MAX = 0x7fffffff +} MMAL_PARAM_PRIVACY_INDICATOR_T; + +typedef struct MMAL_PARAMETER_PRIVACY_INDICATOR_T +{ + MMAL_PARAMETER_HEADER_T hdr; + + MMAL_PARAM_PRIVACY_INDICATOR_T mode; +} MMAL_PARAMETER_PRIVACY_INDICATOR_T; + +#define MMAL_CAMERA_ANNOTATE_MAX_TEXT_LEN 32 +typedef struct MMAL_PARAMETER_CAMERA_ANNOTATE_T +{ + MMAL_PARAMETER_HEADER_T hdr; + + MMAL_BOOL_T enable; + char text[MMAL_CAMERA_ANNOTATE_MAX_TEXT_LEN]; + MMAL_BOOL_T show_shutter; + MMAL_BOOL_T show_analog_gain; + MMAL_BOOL_T show_lens; + MMAL_BOOL_T show_caf; + MMAL_BOOL_T show_motion; +} MMAL_PARAMETER_CAMERA_ANNOTATE_T; + +#define MMAL_CAMERA_ANNOTATE_MAX_TEXT_LEN_V2 256 +typedef struct MMAL_PARAMETER_CAMERA_ANNOTATE_V2_T +{ + MMAL_PARAMETER_HEADER_T hdr; + + MMAL_BOOL_T enable; + MMAL_BOOL_T show_shutter; + MMAL_BOOL_T show_analog_gain; + MMAL_BOOL_T show_lens; + MMAL_BOOL_T show_caf; + MMAL_BOOL_T show_motion; + MMAL_BOOL_T show_frame_num; + MMAL_BOOL_T black_text_background; + char text[MMAL_CAMERA_ANNOTATE_MAX_TEXT_LEN_V2]; +} MMAL_PARAMETER_CAMERA_ANNOTATE_V2_T; + +typedef enum MMAL_STEREOSCOPIC_MODE_T { + MMAL_STEREOSCOPIC_MODE_NONE = 0, + MMAL_STEREOSCOPIC_MODE_SIDE_BY_SIDE = 1, + MMAL_STEREOSCOPIC_MODE_TOP_BOTTOM = 2, + MMAL_STEREOSCOPIC_MODE_MAX = 0x7FFFFFFF, +} MMAL_STEREOSCOPIC_MODE_T; + +typedef struct MMAL_PARAMETER_STEREOSCOPIC_MODE_T +{ + MMAL_PARAMETER_HEADER_T hdr; + + MMAL_STEREOSCOPIC_MODE_T mode; + MMAL_BOOL_T decimate; + MMAL_BOOL_T swap_eyes; +} MMAL_PARAMETER_STEREOSCOPIC_MODE_T; + +#endif /* MMAL_PARAMETERS_CAMERA_H */ diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/mmal_parameters_clock.h b/external_src/raspicam-0.1.3/dependencies/mmal/mmal_parameters_clock.h new file mode 100644 index 0000000..9f798a1 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/mmal_parameters_clock.h @@ -0,0 +1,88 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 MMAL_PARAMETERS_CLOCK_H +#define MMAL_PARAMETERS_CLOCK_H + +#include "mmal_clock.h" +#include "mmal_parameters_common.h" + +/************************************************* + * ALWAYS ADD NEW ENUMS AT THE END OF THIS LIST! * + ************************************************/ + +/** Clock-specific MMAL parameter IDs. + * @ingroup MMAL_PARAMETER_IDS + */ +enum +{ + MMAL_PARAMETER_CLOCK_REFERENCE /**< Takes a MMAL_PARAMETER_BOOLEAN_T */ + = MMAL_PARAMETER_GROUP_CLOCK, + MMAL_PARAMETER_CLOCK_ACTIVE, /**< Takes a MMAL_PARAMETER_BOOLEAN_T */ + MMAL_PARAMETER_CLOCK_SCALE, /**< Takes a MMAL_PARAMETER_RATIONAL_T */ + MMAL_PARAMETER_CLOCK_TIME, /**< Takes a MMAL_PARAMETER_INT64_T */ + MMAL_PARAMETER_CLOCK_UPDATE_THRESHOLD, /**< Takes a MMAL_PARAMETER_CLOCK_UPDATE_THRESHOLD_T */ + MMAL_PARAMETER_CLOCK_DISCONT_THRESHOLD, /**< Takes a MMAL_PARAMETER_CLOCK_DISCONT_THRESHOLD_T */ + MMAL_PARAMETER_CLOCK_REQUEST_THRESHOLD, /**< Takes a MMAL_PARAMETER_CLOCK_REQUEST_THRESHOLD_T */ + MMAL_PARAMETER_CLOCK_ENABLE_BUFFER_INFO, /**< Takes a MMAL_PARAMETER_BOOLEAN_T */ + MMAL_PARAMETER_CLOCK_FRAME_RATE, /**< Takes a MMAL_PARAMETER_RATIONAL_T */ + MMAL_PARAMETER_CLOCK_LATENCY, /**< Takes a MMAL_PARAMETER_CLOCK_LATENCY_T */ +}; + +/** Media-time update thresholds */ +typedef struct MMAL_PARAMETER_CLOCK_UPDATE_THRESHOLD_T +{ + MMAL_PARAMETER_HEADER_T hdr; + + MMAL_CLOCK_UPDATE_THRESHOLD_T value; +} MMAL_PARAMETER_CLOCK_UPDATE_THRESHOLD_T; + +/** Media-time discontinuity settings */ +typedef struct MMAL_PARAMETER_CLOCK_DISCONT_THRESHOLD_T +{ + MMAL_PARAMETER_HEADER_T hdr; + + MMAL_CLOCK_DISCONT_THRESHOLD_T value; +} MMAL_PARAMETER_CLOCK_DISCONT_THRESHOLD_T; + +/** Media-time future frame drop settings */ +typedef struct MMAL_PARAMETER_CLOCK_REQUEST_THRESHOLD_T +{ + MMAL_PARAMETER_HEADER_T hdr; + + MMAL_CLOCK_REQUEST_THRESHOLD_T value; +} MMAL_PARAMETER_CLOCK_REQUEST_THRESHOLD_T; + +/** Clock latency parameter */ +typedef struct MMAL_PARAMETER_CLOCK_LATENCY_T +{ + MMAL_PARAMETER_HEADER_T hdr; + + MMAL_CLOCK_LATENCY_T value; +} MMAL_PARAMETER_CLOCK_LATENCY_T; + +#endif /* MMAL_PARAMETERS_CLOCK_H */ diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/mmal_parameters_common.h b/external_src/raspicam-0.1.3/dependencies/mmal/mmal_parameters_common.h new file mode 100644 index 0000000..28c3118 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/mmal_parameters_common.h @@ -0,0 +1,191 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 MMAL_PARAMETERS_COMMON_H +#define MMAL_PARAMETERS_COMMON_H + +/** @defgroup MMAL_PARAMETER_IDS Pre-defined MMAL parameter IDs + * @ingroup MmalParameters + * @{ + */ + +/** @name Parameter groups + * Parameters are divided into groups, and then allocated sequentially within + * a group using an enum. + * @{ + */ + +/** Common parameter ID group, used with many types of component. */ +#define MMAL_PARAMETER_GROUP_COMMON (0<<16) +/** Camera-specific parameter ID group. */ +#define MMAL_PARAMETER_GROUP_CAMERA (1<<16) +/** Video-specific parameter ID group. */ +#define MMAL_PARAMETER_GROUP_VIDEO (2<<16) +/** Audio-specific parameter ID group. */ +#define MMAL_PARAMETER_GROUP_AUDIO (3<<16) +/** Clock-specific parameter ID group. */ +#define MMAL_PARAMETER_GROUP_CLOCK (4<<16) +/** Miracast-specific parameter ID group. */ +#define MMAL_PARAMETER_GROUP_MIRACAST (5<<16) + + +/**@}*/ + +/** Common MMAL parameter IDs. + */ +enum { + MMAL_PARAMETER_UNUSED /**< Never a valid parameter ID */ + = MMAL_PARAMETER_GROUP_COMMON, + MMAL_PARAMETER_SUPPORTED_ENCODINGS, /**< Takes a MMAL_PARAMETER_ENCODING_T */ + MMAL_PARAMETER_URI, /**< Takes a MMAL_PARAMETER_URI_T */ + MMAL_PARAMETER_CHANGE_EVENT_REQUEST, /**< Takes a MMAL_PARAMETER_CHANGE_EVENT_REQUEST_T */ + MMAL_PARAMETER_ZERO_COPY, /**< Takes a MMAL_PARAMETER_BOOLEAN_T */ + MMAL_PARAMETER_BUFFER_REQUIREMENTS, /**< Takes a MMAL_PARAMETER_BUFFER_REQUIREMENTS_T */ + MMAL_PARAMETER_STATISTICS, /**< Takes a MMAL_PARAMETER_STATISTICS_T */ + MMAL_PARAMETER_CORE_STATISTICS, /**< Takes a MMAL_PARAMETER_CORE_STATISTICS_T */ + MMAL_PARAMETER_MEM_USAGE, /**< Takes a MMAL_PARAMETER_MEM_USAGE_T */ + MMAL_PARAMETER_BUFFER_FLAG_FILTER, /**< Takes a MMAL_PARAMETER_UINT32_T */ + MMAL_PARAMETER_SEEK, /**< Takes a MMAL_PARAMETER_SEEK_T */ + MMAL_PARAMETER_POWERMON_ENABLE, /**< Takes a MMAL_PARAMETER_BOOLEAN_T */ + MMAL_PARAMETER_LOGGING, /**< Takes a MMAL_PARAMETER_LOGGING_T */ + MMAL_PARAMETER_SYSTEM_TIME, /**< Takes a MMAL_PARAMETER_UINT64_T */ + MMAL_PARAMETER_NO_IMAGE_PADDING, /**< Takes a MMAL_PARAMETER_BOOLEAN_T */ + MMAL_PARAMETER_LOCKSTEP_ENABLE /**< Takes a MMAL_PARAMETER_BOOLEAN_T */ +}; + +/**@}*/ + +/** Parameter header type. All parameter structures need to begin with this type. + * The \ref id field must be set to a parameter ID, such as one of those listed on + * the \ref MMAL_PARAMETER_IDS "Pre-defined MMAL parameter IDs" page. + */ +typedef struct MMAL_PARAMETER_HEADER_T +{ + uint32_t id; /**< Parameter ID. */ + uint32_t size; /**< Size in bytes of the parameter (including the header) */ +} MMAL_PARAMETER_HEADER_T; + +/** Change event request parameter type. + * This is used to control whether a \ref MMAL_EVENT_PARAMETER_CHANGED_T event + * is issued should a given parameter change. + */ +typedef struct MMAL_PARAMETER_CHANGE_EVENT_REQUEST_T +{ + MMAL_PARAMETER_HEADER_T hdr; + + uint32_t change_id; /**< ID of parameter that may change, see \ref MMAL_PARAMETER_IDS */ + MMAL_BOOL_T enable; /**< True if the event is enabled, false if disabled */ +} MMAL_PARAMETER_CHANGE_EVENT_REQUEST_T; + +/** Buffer requirements parameter. + * This is mainly used to increase the requirements of a component. */ +typedef struct MMAL_PARAMETER_BUFFER_REQUIREMENTS_T +{ + MMAL_PARAMETER_HEADER_T hdr; + + uint32_t buffer_num_min; /**< Minimum number of buffers the port requires */ + uint32_t buffer_size_min; /**< Minimum size of buffers the port requires */ + uint32_t buffer_alignment_min; /**< Minimum alignment requirement for the buffers. + A value of zero means no special alignment requirements. */ + uint32_t buffer_num_recommended; /**< Number of buffers the port recommends for optimal performance. + A value of zero means no special recommendation. */ + uint32_t buffer_size_recommended; /**< Size of buffers the port recommends for optimal performance. + A value of zero means no special recommendation. */ +} MMAL_PARAMETER_BUFFER_REQUIREMENTS_T; + +/** Seek request parameter type. + * This is used to issue a seek request to a source component. + */ +typedef struct MMAL_PARAMETER_SEEK_T +{ + MMAL_PARAMETER_HEADER_T hdr; + + int64_t offset; /**< Offset (in microseconds) to seek to */ + uint32_t flags; /**< Seeking flags */ + +#define MMAL_PARAM_SEEK_FLAG_PRECISE 0x1 /**< Choose precise seeking even if slower */ +#define MMAL_PARAM_SEEK_FLAG_FORWARD 0x2 /**< Seek to the next keyframe following the specified offset */ + +} MMAL_PARAMETER_SEEK_T; + +/** Port statistics for debugging/test purposes. + * Ports may support query of this parameter to return statistics for debugging or + * test purposes. Not all values may be relevant for a given port. + */ +typedef struct MMAL_PARAMETER_STATISTICS_T +{ + MMAL_PARAMETER_HEADER_T hdr; + + uint32_t buffer_count; /**< Total number of buffers processed */ + uint32_t frame_count; /**< Total number of frames processed */ + uint32_t frames_skipped; /**< Number of frames without expected PTS based on frame rate */ + uint32_t frames_discarded; /**< Number of frames discarded */ + uint32_t eos_seen; /**< Set if the end of stream has been reached */ + uint32_t maximum_frame_bytes; /**< Maximum frame size in bytes */ + int64_t total_bytes; /**< Total number of bytes processed */ + uint32_t corrupt_macroblocks; /**< Number of corrupt macroblocks in the stream */ +} MMAL_PARAMETER_STATISTICS_T; + +typedef enum +{ + MMAL_CORE_STATS_RX, + MMAL_CORE_STATS_TX, + MMAL_CORE_STATS_MAX = 0x7fffffff /* Force 32 bit size for this enum */ +} MMAL_CORE_STATS_DIR; + +/** MMAL core statistics. These are collected by the core itself. + */ +typedef struct MMAL_PARAMETER_CORE_STATISTICS_T +{ + MMAL_PARAMETER_HEADER_T hdr; + MMAL_CORE_STATS_DIR dir; + MMAL_BOOL_T reset; /**< Reset to zero after reading */ + MMAL_CORE_STATISTICS_T stats; /**< The statistics */ +} MMAL_PARAMETER_CORE_STATISTICS_T; + +/** + * Component memory usage statistics. + */ +typedef struct MMAL_PARAMETER_MEM_USAGE_T +{ + MMAL_PARAMETER_HEADER_T hdr; + /**< The amount of memory allocated in image pools by the component */ + uint32_t pool_mem_alloc_size; +} MMAL_PARAMETER_MEM_USAGE_T; + +/** + * Logging control. + */ +typedef struct MMAL_PARAMETER_LOGGING_T +{ + MMAL_PARAMETER_HEADER_T hdr; + uint32_t set; /**< Logging bits to set */ + uint32_t clear; /**< Logging bits to clear */ +} MMAL_PARAMETER_LOGGING_T; + +#endif /* MMAL_PARAMETERS_COMMON_H */ + diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/mmal_parameters_video.h b/external_src/raspicam-0.1.3/dependencies/mmal/mmal_parameters_video.h new file mode 100644 index 0000000..16d8fa2 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/mmal_parameters_video.h @@ -0,0 +1,486 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 MMAL_PARAMETERS_VIDEO_H +#define MMAL_PARAMETERS_VIDEO_H + +#include "mmal_parameters_common.h" + +/************************************************* + * ALWAYS ADD NEW ENUMS AT THE END OF THIS LIST! * + ************************************************/ + +/** Video-specific MMAL parameter IDs. + * @ingroup MMAL_PARAMETER_IDS + */ +enum { + MMAL_PARAMETER_DISPLAYREGION /**< Takes a @ref MMAL_DISPLAYREGION_T */ + = MMAL_PARAMETER_GROUP_VIDEO, + MMAL_PARAMETER_SUPPORTED_PROFILES, /**< Takes a @ref MMAL_PARAMETER_VIDEO_PROFILE_T */ + MMAL_PARAMETER_PROFILE, /**< Takes a @ref MMAL_PARAMETER_VIDEO_PROFILE_T */ + MMAL_PARAMETER_INTRAPERIOD, /**< Takes a @ref MMAL_PARAMETER_UINT32_T */ + MMAL_PARAMETER_RATECONTROL, /**< Takes a @ref MMAL_PARAMETER_VIDEO_RATECONTROL_T */ + MMAL_PARAMETER_NALUNITFORMAT, /**< Takes a @ref MMAL_PARAMETER_VIDEO_NALUNITFORMAT_T */ + MMAL_PARAMETER_MINIMISE_FRAGMENTATION, /**< Takes a @ref MMAL_PARAMETER_BOOLEAN_T */ + MMAL_PARAMETER_MB_ROWS_PER_SLICE, /**< Takes a @ref MMAL_PARAMETER_UINT32_T. + * Setting the value to zero resets to the default (one slice per frame). */ + MMAL_PARAMETER_VIDEO_LEVEL_EXTENSION, /**< Takes a @ref MMAL_PARAMETER_VIDEO_LEVEL_EXTENSION_T */ + MMAL_PARAMETER_VIDEO_EEDE_ENABLE, /**< Takes a @ref MMAL_PARAMETER_VIDEO_EEDE_ENABLE_T */ + MMAL_PARAMETER_VIDEO_EEDE_LOSSRATE, /**< Takes a @ref MMAL_PARAMETER_VIDEO_EEDE_LOSSRATE_T */ + MMAL_PARAMETER_VIDEO_REQUEST_I_FRAME, /**< Takes a @ref MMAL_PARAMETER_BOOLEAN_T. + * Request an I-frame. */ + MMAL_PARAMETER_VIDEO_INTRA_REFRESH, /**< Takes a @ref MMAL_PARAMETER_VIDEO_INTRA_REFRESH_T */ + MMAL_PARAMETER_VIDEO_IMMUTABLE_INPUT, /**< Takes a @ref MMAL_PARAMETER_BOOLEAN_T. */ + MMAL_PARAMETER_VIDEO_BIT_RATE, /**< Takes a @ref MMAL_PARAMETER_UINT32_T. + * Run-time bit rate control */ + MMAL_PARAMETER_VIDEO_FRAME_RATE, /**< Takes a @ref MMAL_PARAMETER_FRAME_RATE_T */ + MMAL_PARAMETER_VIDEO_ENCODE_MIN_QUANT, /**< Takes a @ref MMAL_PARAMETER_UINT32_T. */ + MMAL_PARAMETER_VIDEO_ENCODE_MAX_QUANT, /**< Takes a @ref MMAL_PARAMETER_UINT32_T. */ + MMAL_PARAMETER_VIDEO_ENCODE_RC_MODEL, /**< Takes a @ref MMAL_PARAMETER_VIDEO_ENCODE_RC_MODEL_T. */ + MMAL_PARAMETER_EXTRA_BUFFERS, /**< Takes a @ref MMAL_PARAMETER_UINT32_T. */ + MMAL_PARAMETER_VIDEO_ALIGN_HORIZ, /**< Takes a @ref MMAL_PARAMETER_UINT32_T. + Changing this paramater from the default can reduce frame rate + because image buffers need to be re-pitched.*/ + MMAL_PARAMETER_VIDEO_ALIGN_VERT, /**< Takes a @ref MMAL_PARAMETER_UINT32_T. + Changing this paramater from the default can reduce frame rate + because image buffers need to be re-pitched.*/ + MMAL_PARAMETER_VIDEO_DROPPABLE_PFRAMES, /**< Take a @ref MMAL_PARAMETER_BOOLEAN_T. */ + MMAL_PARAMETER_VIDEO_ENCODE_INITIAL_QUANT, /**< Takes a @ref MMAL_PARAMETER_UINT32_T. */ + MMAL_PARAMETER_VIDEO_ENCODE_QP_P, /**< Takes a @ref MMAL_PARAMETER_UINT32_T. */ + MMAL_PARAMETER_VIDEO_ENCODE_RC_SLICE_DQUANT, /**< Takes a @ref MMAL_PARAMETER_UINT32_T. */ + MMAL_PARAMETER_VIDEO_ENCODE_FRAME_LIMIT_BITS, /**< Takes a @ref MMAL_PARAMETER_UINT32_T */ + MMAL_PARAMETER_VIDEO_ENCODE_PEAK_RATE, /**< Takes a @ref MMAL_PARAMETER_UINT32_T. */ + + /*H264 specific parameters*/ + MMAL_PARAMETER_VIDEO_ENCODE_H264_DISABLE_CABAC, /**< Take a @ref MMAL_PARAMETER_BOOLEAN_T. */ + MMAL_PARAMETER_VIDEO_ENCODE_H264_LOW_LATENCY, /**< Take a @ref MMAL_PARAMETER_BOOLEAN_T. */ + MMAL_PARAMETER_VIDEO_ENCODE_H264_AU_DELIMITERS, /**< Take a @ref MMAL_PARAMETER_BOOLEAN_T. */ + MMAL_PARAMETER_VIDEO_ENCODE_H264_DEBLOCK_IDC, /**< Takes a @ref MMAL_PARAMETER_UINT32_T. */ + MMAL_PARAMETER_VIDEO_ENCODE_H264_MB_INTRA_MODE, /**< Takes a @ref MMAL_PARAMETER_VIDEO_ENCODER_H264_MB_INTRA_MODES_T. */ + + MMAL_PARAMETER_VIDEO_ENCODE_HEADER_ON_OPEN, /**< Takes a @ref MMAL_PARAMETER_BOOLEAN_T */ + MMAL_PARAMETER_VIDEO_ENCODE_PRECODE_FOR_QP, /**< Takes a @ref MMAL_PARAMETER_BOOLEAN_T */ + + MMAL_PARAMETER_VIDEO_DRM_INIT_INFO, /**< Takes a @ref MMAL_PARAMETER_VIDEO_DRM_INIT_INFO_T. */ + MMAL_PARAMETER_VIDEO_TIMESTAMP_FIFO, /**< Takes a @ref MMAL_PARAMETER_BOOLEAN_T */ + MMAL_PARAMETER_VIDEO_DECODE_ERROR_CONCEALMENT, /**< Takes a @ref MMAL_PARAMETER_BOOLEAN_T */ + MMAL_PARAMETER_VIDEO_DRM_PROTECT_BUFFER, /**< Takes a @ref MMAL_PARAMETER_VIDEO_DRM_PROTECT_BUFFER_T. */ + + MMAL_PARAMETER_VIDEO_DECODE_CONFIG_VD3, /**< Takes a @ref MMAL_PARAMETER_BYTES_T */ + MMAL_PARAMETER_VIDEO_ENCODE_H264_VCL_HRD_PARAMETERS, /**< Take a @ref MMAL_PARAMETER_BOOLEAN_T. */ + MMAL_PARAMETER_VIDEO_ENCODE_H264_LOW_DELAY_HRD_FLAG, /**< Take a @ref MMAL_PARAMETER_BOOLEAN_T. */ + MMAL_PARAMETER_VIDEO_ENCODE_INLINE_HEADER, /**< Take a @ref MMAL_PARAMETER_BOOLEAN_T. */ + MMAL_PARAMETER_VIDEO_ENCODE_SEI_ENABLE, /**< Take a @ref MMAL_PARAMETER_BOOLEAN_T. */ + MMAL_PARAMETER_VIDEO_ENCODE_INLINE_VECTORS, /**< Take a @ref MMAL_PARAMETER_BOOLEAN_T. */ + MMAL_PARAMETER_VIDEO_RENDER_STATS, /**< Take a @ref MMAL_PARAMETER_VIDEO_RENDER_STATS_T. */ + MMAL_PARAMETER_VIDEO_INTERLACE_TYPE, /**< Take a @ref MMAL_PARAMETER_VIDEO_INTERLACE_TYPE_T. */ +}; + +/** Display transformations. + * Although an enumeration, the values correspond to combinations of: + * \li 1 Reflect in a vertical axis + * \li 2 180 degree rotation + * \li 4 Reflect in the leading diagonal + */ +typedef enum MMAL_DISPLAYTRANSFORM_T { + MMAL_DISPLAY_ROT0 = 0, + MMAL_DISPLAY_MIRROR_ROT0 = 1, + MMAL_DISPLAY_MIRROR_ROT180 = 2, + MMAL_DISPLAY_ROT180 = 3, + MMAL_DISPLAY_MIRROR_ROT90 = 4, + MMAL_DISPLAY_ROT270 = 5, + MMAL_DISPLAY_ROT90 = 6, + MMAL_DISPLAY_MIRROR_ROT270 = 7, + MMAL_DISPLAY_DUMMY = 0x7FFFFFFF +} MMAL_DISPLAYTRANSFORM_T; + +/** Display modes. */ +typedef enum MMAL_DISPLAYMODE_T { + MMAL_DISPLAY_MODE_FILL = 0, + MMAL_DISPLAY_MODE_LETTERBOX = 1, + // these allow a left eye source->dest to be specified and the right eye mapping will be inferred by symmetry + MMAL_DISPLAY_MODE_STEREO_LEFT_TO_LEFT = 2, + MMAL_DISPLAY_MODE_STEREO_TOP_TO_TOP = 3, + MMAL_DISPLAY_MODE_STEREO_LEFT_TO_TOP = 4, + MMAL_DISPLAY_MODE_STEREO_TOP_TO_LEFT = 5, + MMAL_DISPLAY_MODE_DUMMY = 0x7FFFFFFF +} MMAL_DISPLAYMODE_T; + +/** Values used to indicate which fields are used when setting the + * display configuration */ +typedef enum MMAL_DISPLAYSET_T { + MMAL_DISPLAY_SET_NONE = 0, + MMAL_DISPLAY_SET_NUM = 1, + MMAL_DISPLAY_SET_FULLSCREEN = 2, + MMAL_DISPLAY_SET_TRANSFORM = 4, + MMAL_DISPLAY_SET_DEST_RECT = 8, + MMAL_DISPLAY_SET_SRC_RECT = 0x10, + MMAL_DISPLAY_SET_MODE = 0x20, + MMAL_DISPLAY_SET_PIXEL = 0x40, + MMAL_DISPLAY_SET_NOASPECT = 0x80, + MMAL_DISPLAY_SET_LAYER = 0x100, + MMAL_DISPLAY_SET_COPYPROTECT = 0x200, + MMAL_DISPLAY_SET_ALPHA = 0x400, + MMAL_DISPLAY_SET_DUMMY = 0x7FFFFFFF +} MMAL_DISPLAYSET_T; + +/** +This config sets the output display device, as well as the region used +on the output display, any display transformation, and some flags to +indicate how to scale the image. +*/ + +typedef struct MMAL_DISPLAYREGION_T { + MMAL_PARAMETER_HEADER_T hdr; + /** Bitfield that indicates which fields are set and should be used. All + * other fields will maintain their current value. + * \ref MMAL_DISPLAYSET_T defines the bits that can be combined. + */ + uint32_t set; + /** Describes the display output device, with 0 typically being a directly + * connected LCD display. The actual values will depend on the hardware. + * Code using hard-wired numbers (e.g. 2) is certain to fail. + */ + uint32_t display_num; + /** Indicates that we are using the full device screen area, rather than + * a window of the display. If zero, then dest_rect is used to specify a + * region of the display to use. + */ + MMAL_BOOL_T fullscreen; + /** Indicates any rotation or flipping used to map frames onto the natural + * display orientation. + */ + MMAL_DISPLAYTRANSFORM_T transform; + /** Where to display the frame within the screen, if fullscreen is zero. + */ + MMAL_RECT_T dest_rect; + /** Indicates which area of the frame to display. If all values are zero, + * the whole frame will be used. + */ + MMAL_RECT_T src_rect; + /** If set to non-zero, indicates that any display scaling should disregard + * the aspect ratio of the frame region being displayed. + */ + MMAL_BOOL_T noaspect; + /** Indicates how the image should be scaled to fit the display. \code + * MMAL_DISPLAY_MODE_FILL \endcode indicates that the image should fill the + * screen by potentially cropping the frames. Setting \code mode \endcode + * to \code MMAL_DISPLAY_MODE_LETTERBOX \endcode indicates that all the source + * region should be displayed and black bars added if necessary. + */ + MMAL_DISPLAYMODE_T mode; + /** If non-zero, defines the width of a source pixel relative to \code pixel_y + * \endcode. If zero, then pixels default to being square. + */ + uint32_t pixel_x; + /** If non-zero, defines the height of a source pixel relative to \code pixel_x + * \endcode. If zero, then pixels default to being square. + */ + uint32_t pixel_y; + /** Sets the relative depth of the images, with greater values being in front + * of smaller values. + */ + int32_t layer; + /** Set to non-zero to ensure copy protection is used on output. + */ + MMAL_BOOL_T copyprotect_required; + /** Level of opacity of the layer, where zero is fully transparent and + * 255 is fully opaque. + */ + uint32_t alpha; +} MMAL_DISPLAYREGION_T; + +/** Video profiles. + * Only certain combinations of profile and level will be valid. + * @ref MMAL_VIDEO_LEVEL_T + */ +typedef enum MMAL_VIDEO_PROFILE_T { + MMAL_VIDEO_PROFILE_H263_BASELINE, + MMAL_VIDEO_PROFILE_H263_H320CODING, + MMAL_VIDEO_PROFILE_H263_BACKWARDCOMPATIBLE, + MMAL_VIDEO_PROFILE_H263_ISWV2, + MMAL_VIDEO_PROFILE_H263_ISWV3, + MMAL_VIDEO_PROFILE_H263_HIGHCOMPRESSION, + MMAL_VIDEO_PROFILE_H263_INTERNET, + MMAL_VIDEO_PROFILE_H263_INTERLACE, + MMAL_VIDEO_PROFILE_H263_HIGHLATENCY, + MMAL_VIDEO_PROFILE_MP4V_SIMPLE, + MMAL_VIDEO_PROFILE_MP4V_SIMPLESCALABLE, + MMAL_VIDEO_PROFILE_MP4V_CORE, + MMAL_VIDEO_PROFILE_MP4V_MAIN, + MMAL_VIDEO_PROFILE_MP4V_NBIT, + MMAL_VIDEO_PROFILE_MP4V_SCALABLETEXTURE, + MMAL_VIDEO_PROFILE_MP4V_SIMPLEFACE, + MMAL_VIDEO_PROFILE_MP4V_SIMPLEFBA, + MMAL_VIDEO_PROFILE_MP4V_BASICANIMATED, + MMAL_VIDEO_PROFILE_MP4V_HYBRID, + MMAL_VIDEO_PROFILE_MP4V_ADVANCEDREALTIME, + MMAL_VIDEO_PROFILE_MP4V_CORESCALABLE, + MMAL_VIDEO_PROFILE_MP4V_ADVANCEDCODING, + MMAL_VIDEO_PROFILE_MP4V_ADVANCEDCORE, + MMAL_VIDEO_PROFILE_MP4V_ADVANCEDSCALABLE, + MMAL_VIDEO_PROFILE_MP4V_ADVANCEDSIMPLE, + MMAL_VIDEO_PROFILE_H264_BASELINE, + MMAL_VIDEO_PROFILE_H264_MAIN, + MMAL_VIDEO_PROFILE_H264_EXTENDED, + MMAL_VIDEO_PROFILE_H264_HIGH, + MMAL_VIDEO_PROFILE_H264_HIGH10, + MMAL_VIDEO_PROFILE_H264_HIGH422, + MMAL_VIDEO_PROFILE_H264_HIGH444, + MMAL_VIDEO_PROFILE_H264_CONSTRAINED_BASELINE, + MMAL_VIDEO_PROFILE_DUMMY = 0x7FFFFFFF +} MMAL_VIDEO_PROFILE_T; + +/** Video levels. + * Only certain combinations of profile and level will be valid. + * @ref MMAL_VIDEO_PROFILE_T + */ +typedef enum MMAL_VIDEO_LEVEL_T { + MMAL_VIDEO_LEVEL_H263_10, + MMAL_VIDEO_LEVEL_H263_20, + MMAL_VIDEO_LEVEL_H263_30, + MMAL_VIDEO_LEVEL_H263_40, + MMAL_VIDEO_LEVEL_H263_45, + MMAL_VIDEO_LEVEL_H263_50, + MMAL_VIDEO_LEVEL_H263_60, + MMAL_VIDEO_LEVEL_H263_70, + MMAL_VIDEO_LEVEL_MP4V_0, + MMAL_VIDEO_LEVEL_MP4V_0b, + MMAL_VIDEO_LEVEL_MP4V_1, + MMAL_VIDEO_LEVEL_MP4V_2, + MMAL_VIDEO_LEVEL_MP4V_3, + MMAL_VIDEO_LEVEL_MP4V_4, + MMAL_VIDEO_LEVEL_MP4V_4a, + MMAL_VIDEO_LEVEL_MP4V_5, + MMAL_VIDEO_LEVEL_MP4V_6, + MMAL_VIDEO_LEVEL_H264_1, + MMAL_VIDEO_LEVEL_H264_1b, + MMAL_VIDEO_LEVEL_H264_11, + MMAL_VIDEO_LEVEL_H264_12, + MMAL_VIDEO_LEVEL_H264_13, + MMAL_VIDEO_LEVEL_H264_2, + MMAL_VIDEO_LEVEL_H264_21, + MMAL_VIDEO_LEVEL_H264_22, + MMAL_VIDEO_LEVEL_H264_3, + MMAL_VIDEO_LEVEL_H264_31, + MMAL_VIDEO_LEVEL_H264_32, + MMAL_VIDEO_LEVEL_H264_4, + MMAL_VIDEO_LEVEL_H264_41, + MMAL_VIDEO_LEVEL_H264_42, + MMAL_VIDEO_LEVEL_H264_5, + MMAL_VIDEO_LEVEL_H264_51, + MMAL_VIDEO_LEVEL_DUMMY = 0x7FFFFFFF +} MMAL_VIDEO_LEVEL_T; + +/** Video profile and level setting. + * This is a variable length structure when querying the supported profiles and + * levels. To get more than one, pass a structure with more profile/level pairs. + */ +typedef struct MMAL_PARAMETER_VIDEO_PROFILE_T +{ + MMAL_PARAMETER_HEADER_T hdr; + + struct + { + MMAL_VIDEO_PROFILE_T profile; + MMAL_VIDEO_LEVEL_T level; + } profile[1]; +} MMAL_PARAMETER_VIDEO_PROFILE_T; + +/** Manner of video rate control */ +typedef enum MMAL_VIDEO_RATECONTROL_T { + MMAL_VIDEO_RATECONTROL_DEFAULT, + MMAL_VIDEO_RATECONTROL_VARIABLE, + MMAL_VIDEO_RATECONTROL_CONSTANT, + MMAL_VIDEO_RATECONTROL_VARIABLE_SKIP_FRAMES, + MMAL_VIDEO_RATECONTROL_CONSTANT_SKIP_FRAMES, + MMAL_VIDEO_RATECONTROL_DUMMY = 0x7fffffff +} MMAL_VIDEO_RATECONTROL_T; + +/** Intra refresh modes */ +typedef enum MMAL_VIDEO_INTRA_REFRESH_T { + MMAL_VIDEO_INTRA_REFRESH_CYCLIC, + MMAL_VIDEO_INTRA_REFRESH_ADAPTIVE, + MMAL_VIDEO_INTRA_REFRESH_BOTH, + MMAL_VIDEO_INTRA_REFRESH_KHRONOSEXTENSIONS = 0x6F000000, + MMAL_VIDEO_INTRA_REFRESH_VENDORSTARTUNUSED = 0x7F000000, + MMAL_VIDEO_INTRA_REFRESH_CYCLIC_MROWS, + MMAL_VIDEO_INTRA_REFRESH_PSEUDO_RAND, + MMAL_VIDEO_INTRA_REFRESH_MAX, + MMAL_VIDEO_INTRA_REFRESH_DUMMY = 0x7FFFFFFF +} MMAL_VIDEO_INTRA_REFRESH_T; + +/*Encode RC Models Supported*/ +typedef enum MMAL_VIDEO_ENCODE_RC_MODEL_T { + MMAL_VIDEO_ENCODER_RC_MODEL_DEFAULT = 0, + MMAL_VIDEO_ENCODER_RC_MODEL_JVT = MMAL_VIDEO_ENCODER_RC_MODEL_DEFAULT, + MMAL_VIDEO_ENCODER_RC_MODEL_VOWIFI, + MMAL_VIDEO_ENCODER_RC_MODEL_CBR, + MMAL_VIDEO_ENCODER_RC_MODEL_LAST, + MMAL_VIDEO_ENCODER_RC_MODEL_DUMMY = 0x7FFFFFFF +} MMAL_VIDEO_ENCODE_RC_MODEL_T; + +typedef struct MMAL_PARAMETER_VIDEO_ENCODE_RC_MODEL_T { + MMAL_PARAMETER_HEADER_T hdr; + MMAL_VIDEO_ENCODE_RC_MODEL_T rc_model; +}MMAL_PARAMETER_VIDEO_ENCODE_RC_MODEL_T; + +/** Video rate control setting */ +typedef struct MMAL_PARAMETER_VIDEO_RATECONTROL_T { + MMAL_PARAMETER_HEADER_T hdr; + + MMAL_VIDEO_RATECONTROL_T control; +} MMAL_PARAMETER_VIDEO_RATECONTROL_T; + +/*H264 INTRA MB MODES*/ +typedef enum MMAL_VIDEO_ENCODE_H264_MB_INTRA_MODES_T { + MMAL_VIDEO_ENCODER_H264_MB_4x4_INTRA = 1, + MMAL_VIDEO_ENCODER_H264_MB_8x8_INTRA = 2, + MMAL_VIDEO_ENCODER_H264_MB_16x16_INTRA = 4, + MMAL_VIDEO_ENCODER_H264_MB_INTRA_DUMMY = 0x7fffffff +} MMAL_VIDEO_ENCODE_H264_MB_INTRA_MODES_T; + +typedef struct MMAL_PARAMETER_VIDEO_ENCODER_H264_MB_INTRA_MODES_T { + MMAL_PARAMETER_HEADER_T hdr; + MMAL_VIDEO_ENCODE_H264_MB_INTRA_MODES_T mb_mode; +}MMAL_PARAMETER_VIDEO_ENCODER_H264_MB_INTRA_MODES_T; + +/** NAL unit formats */ +typedef enum MMAL_VIDEO_NALUNITFORMAT_T { + MMAL_VIDEO_NALUNITFORMAT_STARTCODES = 1, + MMAL_VIDEO_NALUNITFORMAT_NALUNITPERBUFFER = 2, + MMAL_VIDEO_NALUNITFORMAT_ONEBYTEINTERLEAVELENGTH = 4, + MMAL_VIDEO_NALUNITFORMAT_TWOBYTEINTERLEAVELENGTH = 8, + MMAL_VIDEO_NALUNITFORMAT_FOURBYTEINTERLEAVELENGTH = 16, + MMAL_VIDEO_NALUNITFORMAT_DUMMY = 0x7fffffff +} MMAL_VIDEO_NALUNITFORMAT_T; + +/** NAL unit format setting */ +typedef struct MMAL_PARAMETER_VIDEO_NALUNITFORMAT_T { + MMAL_PARAMETER_HEADER_T hdr; + + MMAL_VIDEO_NALUNITFORMAT_T format; +} MMAL_PARAMETER_VIDEO_NALUNITFORMAT_T; + +/** H264 Only: Overrides for max macro-blocks per second, max framesize, + * and max bitrates. This overrides the default maximums for the configured level. + */ +typedef struct MMAL_PARAMETER_VIDEO_LEVEL_EXTENSION_T { + MMAL_PARAMETER_HEADER_T hdr; + + uint32_t custom_max_mbps; + uint32_t custom_max_fs; + uint32_t custom_max_br_and_cpb; +} MMAL_PARAMETER_VIDEO_LEVEL_EXTENSION_T; + +/** H264 Only: Overrides for max macro-blocks per second, max framesize, + * and max bitrates. This overrides the default maximums for the configured level. + */ +typedef struct MMAL_PARAMETER_VIDEO_INTRA_REFRESH_T { + MMAL_PARAMETER_HEADER_T hdr; + + MMAL_VIDEO_INTRA_REFRESH_T refresh_mode; + uint32_t air_mbs; + uint32_t air_ref; + uint32_t cir_mbs; + uint32_t pir_mbs; +} MMAL_PARAMETER_VIDEO_INTRA_REFRESH_T; + +/** Structure for enabling EEDE, we keep it like this for now, there could be extra fields in the future */ +typedef struct MMAL_PARAMETER_VIDEO_EEDE_ENABLE_T { + MMAL_PARAMETER_HEADER_T hdr; + + uint32_t enable; +} MMAL_PARAMETER_VIDEO_EEDE_ENABLE_T; + +/** Structure for setting lossrate for EEDE, we keep it like this for now, there could be extra fields in the future */ +typedef struct MMAL_PARAMETER_VIDEO_EEDE_LOSSRATE_T { + MMAL_PARAMETER_HEADER_T hdr; + + uint32_t loss_rate; +} MMAL_PARAMETER_VIDEO_EEDE_LOSSRATE_T; + +/** Structure for setting inital DRM parameters */ +typedef struct MMAL_PARAMETER_VIDEO_DRM_INIT_INFO_T { + MMAL_PARAMETER_HEADER_T hdr; + + uint32_t current_time; + uint32_t ticks_per_sec; + uint8_t lhs[32]; +} MMAL_PARAMETER_VIDEO_DRM_INIT_INFO_T; + +/** Structure for requesting a hardware-protected memory buffer **/ +typedef struct MMAL_PARAMETER_VIDEO_DRM_PROTECT_BUFFER_T { + MMAL_PARAMETER_HEADER_T hdr; + + uint32_t size_wanted; /**< Input. Zero size means internal video decoder buffer, + mem_handle and phys_addr not returned in this case */ + uint32_t protect; /**< Input. 1 = protect, 0 = unprotect */ + + uint32_t mem_handle; /**< Output. Handle for protected buffer */ + void * phys_addr; /**< Output. Physical memory address of protected buffer */ + +} MMAL_PARAMETER_VIDEO_DRM_PROTECT_BUFFER_T; + +typedef struct MMAL_PARAMETER_VIDEO_RENDER_STATS_T { + MMAL_PARAMETER_HEADER_T hdr; + + MMAL_BOOL_T valid; + uint32_t match; + uint32_t period; + uint32_t phase; + uint32_t pixel_clock_nominal; + uint32_t pixel_clock; + uint32_t hvs_status; + uint32_t dummy[2]; +} MMAL_PARAMETER_VIDEO_RENDER_STATS_T; + +typedef enum MMAL_INTERLACETYPE_T { + MMAL_InterlaceProgressive, /**< The data is not interlaced, it is progressive scan */ + MMAL_InterlaceFieldSingleUpperFirst, /**< The data is interlaced, fields sent + separately in temporal order, with upper field first */ + MMAL_InterlaceFieldSingleLowerFirst, /**< The data is interlaced, fields sent + separately in temporal order, with lower field first */ + MMAL_InterlaceFieldsInterleavedUpperFirst, /**< The data is interlaced, two fields sent together line + interleaved, with the upper field temporally earlier */ + MMAL_InterlaceFieldsInterleavedLowerFirst, /**< The data is interlaced, two fields sent together line + interleaved, with the lower field temporally earlier */ + MMAL_InterlaceMixed, /**< The stream may contain a mixture of progressive + and interlaced frames */ + MMAL_InterlaceKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + MMAL_InterlaceVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + MMAL_InterlaceMax = 0x7FFFFFFF +} MMAL_INTERLACETYPE_T; + +typedef struct MMAL_PARAMETER_VIDEO_INTERLACE_TYPE_T { + MMAL_PARAMETER_HEADER_T hdr; + + MMAL_INTERLACETYPE_T eMode; /**< The interlace type of the content */ + MMAL_BOOL_T bRepeatFirstField; /**< Whether to repeat the first field */ +} MMAL_PARAMETER_VIDEO_INTERLACE_TYPE_T; + +#endif diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/mmal_pool.h b/external_src/raspicam-0.1.3/dependencies/mmal/mmal_pool.h new file mode 100644 index 0000000..4df5853 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/mmal_pool.h @@ -0,0 +1,167 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 MMAL_POOL_H +#define MMAL_POOL_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup MmalPool Pools of buffer headers + * A pool of buffer headers is composed of a queue (\ref MMAL_QUEUE_T) and a user + * specified number of buffer headers (\ref MMAL_BUFFER_HEADER_T). */ +/* @{ */ + +#include "mmal_queue.h" + +/** Definition of a pool */ +typedef struct MMAL_POOL_T +{ + MMAL_QUEUE_T *queue; /**< Queue used by the pool */ + uint32_t headers_num; /**< Number of buffer headers in the pool */ + MMAL_BUFFER_HEADER_T **header; /**< Array of buffer headers belonging to the pool */ +} MMAL_POOL_T; + +/** Allocator alloc prototype + * + * @param context The context pointer passed in on pool creation. + * @param size The size of the allocation required, in bytes. + * @return The pointer to the newly allocated memory, or NULL on failure. + */ +typedef void *(*mmal_pool_allocator_alloc_t)(void *context, uint32_t size); +/** Allocator free prototype + * + * @param context The context pointer passed in on pool creation. + * @param mem The pointer to the memory to be released. + */ +typedef void (*mmal_pool_allocator_free_t)(void *context, void *mem); + +/** Create a pool of MMAL_BUFFER_HEADER_T. + * 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. + * + * The payload buffers may also be allocated independently by the client, and assigned + * to the buffer headers, but it will be the responsibility of the client to deal with + * resizing and releasing the memory. It is recommended that mmal_pool_create_with_allocator() + * is used in this case, supplying allocator function pointers that will be used as + * necessary by MMAL. + * + * @param headers Number of buffer headers to be allocated with the pool. + * @param payload_size Size of the payload buffer that will be allocated in + * each of the buffer headers. + * @return Pointer to the newly created pool or NULL on failure. + */ +MMAL_POOL_T *mmal_pool_create(unsigned int headers, uint32_t payload_size); + +/** Create a pool of MMAL_BUFFER_HEADER_T. + * 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. The allocators + * passed during creation shall be used when resizing the payload buffers. + * + * @param headers Number of buffer headers to be allocated with the pool. + * @param payload_size Size of the payload buffer that will be allocated in + * each of the buffer headers. + * @param allocator_context Pointer to the context of the allocator. + * @param allocator_alloc Function pointer for the alloc call of the allocator. + * @param allocator_free Function pointer for the free call of the allocator. + * + * @return Pointer to the newly created pool or NULL on failure. + */ +MMAL_POOL_T *mmal_pool_create_with_allocator(unsigned int headers, uint32_t payload_size, + void *allocator_context, mmal_pool_allocator_alloc_t allocator_alloc, + mmal_pool_allocator_free_t allocator_free); + +/** Destroy a pool of MMAL_BUFFER_HEADER_T. + * This will also deallocate all of the memory which was allocated when creating or + * resizing the pool. + * + * If payload buffers have been allocated independently by the client, they should be + * released prior to calling this function. If the client provided allocator functions, + * the allocator_free function shall be called for each payload buffer. + * + * @param pool Pointer to a pool + */ +void mmal_pool_destroy(MMAL_POOL_T *pool); + +/** Resize a pool of MMAL_BUFFER_HEADER_T. + * This allows modifying either the number of allocated buffers, the payload size or both at the + * same time. + * + * @param pool Pointer to the pool + * @param headers New number of buffer headers to be allocated in the pool. + * It is not valid to pass zero for the number of buffers. + * @param payload_size Size of the payload buffer that will be allocated in + * each of the buffer headers. + * If this is set to 0, all payload buffers shall be released. + * @return MMAL_SUCCESS or an error on failure. + */ +MMAL_STATUS_T mmal_pool_resize(MMAL_POOL_T *pool, unsigned int headers, uint32_t payload_size); + +/** Definition of the callback used by a pool to signal back to the user that a buffer header + * has been released back to the pool. + * + * @param pool Pointer to the pool + * @param buffer Buffer header just released + * @param userdata User specific data passed in when setting the callback + * @return True to have the buffer header put back in the pool's queue, false if the buffer + * header has been taken within the callback. + */ +typedef MMAL_BOOL_T (*MMAL_POOL_BH_CB_T)(MMAL_POOL_T *pool, MMAL_BUFFER_HEADER_T *buffer, void *userdata); + +/** Set a buffer header release callback to the pool. + * Each time a buffer header is released to the pool, the callback will be triggered. + * + * @param pool Pointer to a pool + * @param cb Callback function + * @param userdata User specific data which will be passed with each callback + */ +void mmal_pool_callback_set(MMAL_POOL_T *pool, MMAL_POOL_BH_CB_T cb, void *userdata); + +/** Set a pre-release callback for all buffer headers in the pool. + * Each time a buffer header is about to be released to the pool, the callback + * will be triggered. + * + * @param pool Pointer to the pool + * @param cb Pre-release callback function + * @param userdata User-specific data passed back with each callback + */ +void mmal_pool_pre_release_callback_set(MMAL_POOL_T *pool, MMAL_BH_PRE_RELEASE_CB_T cb, void *userdata); + +/* @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* MMAL_POOL_H */ diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/mmal_port.h b/external_src/raspicam-0.1.3/dependencies/mmal/mmal_port.h new file mode 100644 index 0000000..982c45f --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/mmal_port.h @@ -0,0 +1,286 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 MMAL_PORT_H +#define MMAL_PORT_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup MmalPort Ports + * Definition of a MMAL port and its associated API */ +/* @{ */ + +#include "mmal_types.h" +#include "mmal_format.h" +#include "mmal_buffer.h" +#include "mmal_parameters.h" + +/** List of port types */ +typedef enum +{ + MMAL_PORT_TYPE_UNKNOWN = 0, /**< Unknown port type */ + MMAL_PORT_TYPE_CONTROL, /**< Control port */ + MMAL_PORT_TYPE_INPUT, /**< Input port */ + MMAL_PORT_TYPE_OUTPUT, /**< Output port */ + MMAL_PORT_TYPE_CLOCK, /**< Clock port */ + MMAL_PORT_TYPE_INVALID = 0xffffffff /**< Dummy value to force 32bit enum */ + +} MMAL_PORT_TYPE_T; + +/** \name Port capabilities + * \anchor portcapabilities + * The following flags describe the capabilities advertised by a port */ +/* @{ */ +/** The port is pass-through and doesn't need buffer headers allocated */ +#define MMAL_PORT_CAPABILITY_PASSTHROUGH 0x01 +/** The port wants to allocate the buffer payloads. This signals a preference that + * payload allocation should be done on this port for efficiency reasons. */ +#define MMAL_PORT_CAPABILITY_ALLOCATION 0x02 +/** The port supports format change events. This applies to input ports and is used + * to let the client know whether the port supports being reconfigured via a format + * change event (i.e. without having to disable the port). */ +#define MMAL_PORT_CAPABILITY_SUPPORTS_EVENT_FORMAT_CHANGE 0x04 +/* @} */ + +/** Definition of a port. + * A port is the entity that is exposed by components to receive or transmit + * buffer headers (\ref MMAL_BUFFER_HEADER_T). A port is defined by its + * \ref MMAL_ES_FORMAT_T. + * + * It may be possible to override the buffer requirements of a port by using + * the MMAL_PARAMETER_BUFFER_REQUIREMENTS parameter. + */ +typedef struct MMAL_PORT_T +{ + struct MMAL_PORT_PRIVATE_T *priv; /**< Private member used by the framework */ + const char *name; /**< Port name. Used for debugging purposes (Read Only) */ + + MMAL_PORT_TYPE_T type; /**< Type of the port (Read Only) */ + uint16_t index; /**< Index of the port in its type list (Read Only) */ + uint16_t index_all; /**< Index of the port in the list of all ports (Read Only) */ + + uint32_t is_enabled; /**< Indicates whether the port is enabled or not (Read Only) */ + MMAL_ES_FORMAT_T *format; /**< Format of the elementary stream */ + + uint32_t buffer_num_min; /**< Minimum number of buffers the port requires (Read Only). + This is set by the component. */ + uint32_t buffer_size_min; /**< Minimum size of buffers the port requires (Read Only). + This is set by the component. */ + uint32_t buffer_alignment_min; /**< Minimum alignment requirement for the buffers (Read Only). + A value of zero means no special alignment requirements. + This is set by the component. */ + uint32_t buffer_num_recommended; /**< Number of buffers the port recommends for optimal performance (Read Only). + A value of zero means no special recommendation. + This is set by the component. */ + uint32_t buffer_size_recommended; /**< Size of buffers the port recommends for optimal performance (Read Only). + A value of zero means no special recommendation. + This is set by the component. */ + uint32_t buffer_num; /**< Actual number of buffers the port will use. + This is set by the client. */ + uint32_t buffer_size; /**< Actual maximum size of the buffers that will be sent + to the port. This is set by the client. */ + + struct MMAL_COMPONENT_T *component; /**< Component this port belongs to (Read Only) */ + struct MMAL_PORT_USERDATA_T *userdata; /**< Field reserved for use by the client */ + + uint32_t capabilities; /**< Flags describing the capabilities of a port (Read Only). + * Bitwise combination of \ref portcapabilities "Port capabilities" + * values. + */ + +} MMAL_PORT_T; + +/** 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); + +/** Definition of the callback used by a port to send a \ref MMAL_BUFFER_HEADER_T + * back to the user. + * + * @param port The port sending the buffer header. + * @param buffer The buffer header being sent. + */ +typedef void (*MMAL_PORT_BH_CB_T)(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer); + +/** 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: + *
    + *
  • The port shall be populated with a pool of buffers, allocated as required, according + * to the buffer_num and buffer_size values. + *
  • 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. + *
+ * + * @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); + +/** 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); + +/** 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); + +/** 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); + +/** 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); + +/** 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); + +/** 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); + +/** 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); + +/** 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); + +/** 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); + +/** 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); + +/* @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* MMAL_PORT_H */ diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/mmal_queue.h b/external_src/raspicam-0.1.3/dependencies/mmal/mmal_queue.h new file mode 100644 index 0000000..ce53a26 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/mmal_queue.h @@ -0,0 +1,116 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 MMAL_QUEUE_H +#define MMAL_QUEUE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup MmalQueue Queues of buffer headers + * This provides a thread-safe implementation of a queue of buffer headers + * (\ref MMAL_BUFFER_HEADER_T). The queue works in a first-in, first-out basis + * so the buffer headers will be dequeued in the order they have been queued. */ +/* @{ */ + +#include "mmal_buffer.h" + +typedef struct MMAL_QUEUE_T MMAL_QUEUE_T; + +/** Create a queue of MMAL_BUFFER_HEADER_T + * + * @return Pointer to the newly created queue or NULL on failure. + */ +MMAL_QUEUE_T *mmal_queue_create(void); + +/** Put a MMAL_BUFFER_HEADER_T into a queue + * + * @param queue Pointer to a queue + * @param buffer Pointer to the MMAL_BUFFER_HEADER_T to add to the queue + */ +void mmal_queue_put(MMAL_QUEUE_T *queue, MMAL_BUFFER_HEADER_T *buffer); + +/** Put a MMAL_BUFFER_HEADER_T back at the start of a queue. + * This is used when a buffer header was removed from the queue but not + * fully processed and needs to be put back where it was originally taken. + * + * @param queue Pointer to a queue + * @param buffer Pointer to the MMAL_BUFFER_HEADER_T to add to the queue + */ +void mmal_queue_put_back(MMAL_QUEUE_T *queue, MMAL_BUFFER_HEADER_T *buffer); + +/** Get a MMAL_BUFFER_HEADER_T from a queue + * + * @param queue Pointer to a queue + * + * @return pointer to the next MMAL_BUFFER_HEADER_T or NULL if the queue is empty. + */ +MMAL_BUFFER_HEADER_T *mmal_queue_get(MMAL_QUEUE_T *queue); + +/** Wait for a MMAL_BUFFER_HEADER_T from a queue. + * This is the same as a get except that this will block until a buffer header is + * available. + * + * @param queue Pointer to a queue + * + * @return pointer to the next MMAL_BUFFER_HEADER_T. + */ +MMAL_BUFFER_HEADER_T *mmal_queue_wait(MMAL_QUEUE_T *queue); + +/** Wait for a MMAL_BUFFER_HEADER_T from a queue, up to a given timeout. + * This is the same as a wait, except that it will abort in case of timeout. + * + * @param queue Pointer to a queue + * @param timeout Number of milliseconds to wait before + * returning if the semaphore can't be acquired. + * + * @return pointer to the next MMAL_BUFFER_HEADER_T. + */ +MMAL_BUFFER_HEADER_T *mmal_queue_timedwait(MMAL_QUEUE_T *queue, VCOS_UNSIGNED timeout); + +/** 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); + +/** Destroy a queue of MMAL_BUFFER_HEADER_T. + * + * @param queue Pointer to a queue + */ +void mmal_queue_destroy(MMAL_QUEUE_T *queue); + +/* @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* MMAL_QUEUE_H */ diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/mmal_types.h b/external_src/raspicam-0.1.3/dependencies/mmal/mmal_types.h new file mode 100644 index 0000000..741f742 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/mmal_types.h @@ -0,0 +1,100 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 MMAL_TYPES_H +#define MMAL_TYPES_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup MmalTypes Common types + * Definition for common types */ +/* @{ */ + +#include "mmal_common.h" + +/** Status return codes from the API. + * + * \internal Please try to keep this similar to the standard POSIX codes + * rather than making up new ones! + */ +typedef enum +{ + MMAL_SUCCESS = 0, /**< Success */ + MMAL_ENOMEM, /**< Out of memory */ + MMAL_ENOSPC, /**< Out of resources (other than memory) */ + MMAL_EINVAL, /**< Argument is invalid */ + MMAL_ENOSYS, /**< Function not implemented */ + MMAL_ENOENT, /**< No such file or directory */ + MMAL_ENXIO, /**< No such device or address */ + MMAL_EIO, /**< I/O error */ + MMAL_ESPIPE, /**< Illegal seek */ + MMAL_ECORRUPT, /**< Data is corrupt \attention FIXME: not POSIX */ + MMAL_ENOTREADY, /**< Component is not ready \attention FIXME: not POSIX */ + MMAL_ECONFIG, /**< Component is not configured \attention FIXME: not POSIX */ + MMAL_EISCONN, /**< Port is already connected */ + MMAL_ENOTCONN, /**< Port is disconnected */ + MMAL_EAGAIN, /**< Resource temporarily unavailable. Try again later*/ + MMAL_EFAULT, /**< Bad address */ + /* Do not add new codes here unless they match something from POSIX */ + MMAL_STATUS_MAX = 0x7FFFFFFF /**< Force to 32 bit */ +} MMAL_STATUS_T; + +/** Describes a rectangle */ +typedef struct +{ + int32_t x; /**< x coordinate (from left) */ + int32_t y; /**< y coordinate (from top) */ + int32_t width; /**< width */ + int32_t height; /**< height */ +} MMAL_RECT_T; + +/** Describes a rational number */ +typedef struct +{ + int32_t num; /**< Numerator */ + int32_t den; /**< Denominator */ +} MMAL_RATIONAL_T; + +/** \name Special Unknown Time Value + * Timestamps in MMAL are defined as signed 64 bits integer values representing microseconds. + * However a pre-defined special value is used to signal that a timestamp is not known. */ +/* @{ */ +#define MMAL_TIME_UNKNOWN (INT64_C(1)<<63) /**< Special value signalling that time is not known */ +/* @} */ + +/** Four Character Code type */ +typedef uint32_t MMAL_FOURCC_T; + +/* @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* MMAL_TYPES_H */ diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/openmaxil/CMakeLists.txt b/external_src/raspicam-0.1.3/dependencies/mmal/openmaxil/CMakeLists.txt new file mode 100644 index 0000000..68d9832 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/openmaxil/CMakeLists.txt @@ -0,0 +1,20 @@ +add_library (mmal_omx ${LIBRARY_TYPE} + mmalomx_core.c + mmalomx_logging.c + mmalomx_commands.c + mmalomx_buffer.c + mmalomx_marks.c + mmalomx_roles.c + mmalomx_parameters.c + mmalomx_registry.c +) + +add_library (mmal_omxutil ${LIBRARY_TYPE} + mmalomx_util_params.c + mmalomx_util_params_audio.c + mmalomx_util_params_video.c + mmalomx_util_params_camera.c + mmalomx_util_params_misc.c +) + +target_link_libraries (mmal_omx mmal_omxutil mmal_core mmal_util vcos) diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/openmaxil/mmalomx.h b/external_src/raspicam-0.1.3/dependencies/mmal/openmaxil/mmalomx.h new file mode 100644 index 0000000..d58971a --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/openmaxil/mmalomx.h @@ -0,0 +1,130 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. +*/ + +/** \file + * OpenMAX IL adaptation layer for MMAL + */ + +#include "interface/vmcs_host/khronos/IL/OMX_Core.h" +#include "interface/vmcs_host/khronos/IL/OMX_Component.h" +#include "interface/vmcs_host/khronos/IL/OMX_Video.h" +#include "interface/vmcs_host/khronos/IL/OMX_Audio.h" +#include +#include + +/* Define this to 1 if you want to log all buffer transfers */ +#define ENABLE_MMAL_EXTRA_LOGGING 0 + +#ifndef MMALOMX_EXPORT +# define MMALOMX_EXPORT(a) a +#endif +#ifndef MMALOMX_IMPORT +# define MMALOMX_IMPORT(a) a +#endif + +#define MAX_MARKS_NUM 2 +#define MAX_ENCODINGS_NUM 20 + +/** Per-port context data */ +typedef struct MMALOMX_PORT_T +{ + struct MMALOMX_COMPONENT_T *component; + MMAL_PORT_T *mmal; + OMX_DIRTYPE direction; + unsigned int index; + unsigned int buffers; + unsigned int buffers_in_transit; + + MMAL_BOOL_T buffers_allocated:1; + MMAL_BOOL_T enabled:1; + MMAL_BOOL_T populated:1; + MMAL_BOOL_T zero_copy:1; + MMAL_BOOL_T no_cropping:1; + MMAL_BOOL_T format_changed:1; + MMAL_POOL_T *pool; + + uint32_t actions; + + OMX_MARKTYPE marks[MAX_MARKS_NUM]; + unsigned int marks_first:8; + unsigned int marks_num:8; + + OMX_FORMAT_PARAM_TYPE format_param; + + MMAL_PARAMETER_HEADER_T encodings_header; + MMAL_FOURCC_T encodings[MAX_ENCODINGS_NUM]; + unsigned int encodings_num; + +} MMALOMX_PORT_T; + +/** Component context data */ +typedef struct MMALOMX_COMPONENT_T { + OMX_COMPONENTTYPE omx; /**< OMX component type structure */ + + unsigned int registry_id; + const char *name; + uint32_t role; + OMX_CALLBACKTYPE callbacks; + OMX_PTR callbacks_data; + + struct MMAL_COMPONENT_T *mmal; + OMX_STATETYPE state; + unsigned int state_transition; + + MMALOMX_PORT_T *ports; + unsigned int ports_num; + unsigned int ports_domain_num[4]; + + MMAL_BOOL_T actions_running; + + OMX_U32 group_id; + OMX_U32 group_priority; + + /* Support for command queues */ + MMAL_POOL_T *cmd_pool; + MMAL_QUEUE_T *cmd_queue; + VCOS_THREAD_T cmd_thread; + MMAL_BOOL_T cmd_thread_used; + VCOS_SEMAPHORE_T cmd_sema; + + VCOS_MUTEX_T lock; /**< Used to protect component state */ + VCOS_MUTEX_T lock_port; /**< Used to protect port state */ + +} MMALOMX_COMPONENT_T; + +OMX_ERRORTYPE mmalomx_callback_event_handler( + MMALOMX_COMPONENT_T *component, + OMX_EVENTTYPE eEvent, + OMX_U32 nData1, + OMX_U32 nData2, + OMX_PTR pEventData); + +#define MMALOMX_LOCK(a) vcos_mutex_lock(&a->lock) +#define MMALOMX_UNLOCK(a) vcos_mutex_unlock(&a->lock) +#define MMALOMX_LOCK_PORT(a,b) vcos_mutex_lock(&a->lock_port) +#define MMALOMX_UNLOCK_PORT(a,b) vcos_mutex_unlock(&a->lock_port) + diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/openmaxil/mmalomx_buffer.c b/external_src/raspicam-0.1.3/dependencies/mmal/openmaxil/mmalomx_buffer.c new file mode 100644 index 0000000..ef78baa --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/openmaxil/mmalomx_buffer.c @@ -0,0 +1,235 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 "mmalomx.h" +#include "mmalomx_buffer.h" +#include "mmalomx_commands.h" +#include "mmalomx_marks.h" +#include "mmalomx_logging.h" + +#include + +/*****************************************************************************/ +OMX_ERRORTYPE mmalomx_buffer_send( + MMALOMX_COMPONENT_T *component, + OMX_BUFFERHEADERTYPE *omx_buffer, + OMX_DIRTYPE direction) +{ + OMX_ERRORTYPE status = OMX_ErrorNone; + MMAL_BUFFER_HEADER_T *mmal_buffer; + MMAL_STATUS_T mmal_status; + MMALOMX_PORT_T *port; + unsigned int index; + + /* Sanity checks */ + if (!component) + return OMX_ErrorInvalidComponent; + if (component->state == OMX_StateInvalid) + return OMX_ErrorInvalidState; + + if (!omx_buffer || omx_buffer->nSize != sizeof(OMX_BUFFERHEADERTYPE) || + omx_buffer->nOffset + omx_buffer->nFilledLen > omx_buffer->nAllocLen) + return OMX_ErrorBadParameter; + + index = direction == OMX_DirInput ? omx_buffer->nInputPortIndex : omx_buffer->nOutputPortIndex; + if (index >= component->ports_num) + return OMX_ErrorBadPortIndex; + + port = &component->ports[index]; + if (port->direction != direction) + return OMX_ErrorBadPortIndex; + + MMALOMX_LOCK_PORT(component, port); + + if (component->state != OMX_StatePause && component->state != OMX_StateExecuting) + status = OMX_ErrorIncorrectStateOperation; + if (!port->enabled /* FIXME: || flushing || pending idle */) + status = OMX_ErrorIncorrectStateOperation; + if (status != OMX_ErrorNone) + goto error; + + mmal_buffer = mmal_queue_get( port->pool->queue ); + if (!vcos_verify(mmal_buffer)) /* Should never happen */ + { + status = OMX_ErrorUndefined; + goto error; + } + + mmalomx_mark_process_incoming(component, port, omx_buffer); + + mmal_buffer->user_data = (void *)omx_buffer; + mmalil_buffer_header_to_mmal(mmal_buffer, omx_buffer); + + mmal_status = mmal_port_send_buffer(port->mmal, mmal_buffer); + if (!vcos_verify(mmal_status == MMAL_SUCCESS)) + { + LOG_ERROR("failed to send buffer on %s", port->mmal->name); + mmal_queue_put_back( port->pool->queue, mmal_buffer ); + status = mmalil_error_to_omx(mmal_status); + } + else + { + port->buffers_in_transit++; + } + +error: + MMALOMX_UNLOCK_PORT(component, port); + return status; +} + +/*****************************************************************************/ +static void mmalomx_buffer_event( + MMALOMX_PORT_T *port, + MMAL_BUFFER_HEADER_T *mmal_buffer) +{ + MMALOMX_COMPONENT_T *component = port->component; + MMAL_EVENT_FORMAT_CHANGED_T *event; + + LOG_TRACE("hComponent %p, port %i, event %4.4s", component, port->index, + (char *)&mmal_buffer->cmd); + + if (mmal_buffer->cmd == MMAL_EVENT_ERROR ) + { + mmalomx_callback_event_handler(component, OMX_EventError, + mmalil_error_to_omx(*(MMAL_STATUS_T *)mmal_buffer->data), 0, NULL); + return; + } + + event = mmal_event_format_changed_get(mmal_buffer); + if (event && port->mmal->type == MMAL_PORT_TYPE_OUTPUT && + port->mmal->format->type == MMAL_ES_TYPE_VIDEO) + { + uint32_t diff = mmal_format_compare(event->format, port->mmal->format); + MMAL_ES_FORMAT_T *format = port->mmal->format; + MMAL_VIDEO_FORMAT_T video = format->es->video; + + /* Update the port settings with the new values */ + mmal_format_copy(format, event->format); + port->mmal->buffer_num_min = event->buffer_num_min; + port->mmal->buffer_size_min = event->buffer_size_min; + port->format_changed = MMAL_TRUE; + + if ((diff & MMAL_ES_FORMAT_COMPARE_FLAG_VIDEO_ASPECT_RATIO) && + /* Do not report a change if going from unspecified to 1:1 */ + !(format->es->video.par.num == format->es->video.par.den && !video.par.num)) + { + LOG_DEBUG("aspect ratio change %ix%i->%ix%i", (int)video.par.num, (int)video.par.den, + (int)format->es->video.par.num, (int)format->es->video.par.den); + mmalomx_callback_event_handler(component, OMX_EventPortSettingsChanged, + port->index, OMX_IndexParamBrcmPixelAspectRatio, NULL); + } + + if (diff & (MMAL_ES_FORMAT_COMPARE_FLAG_ENCODING| + MMAL_ES_FORMAT_COMPARE_FLAG_VIDEO_RESOLUTION| + MMAL_ES_FORMAT_COMPARE_FLAG_VIDEO_CROPPING)) + { + LOG_DEBUG("format change %ix%i(%ix%i) -> %ix%i(%ix%i)", + (int)video.width, (int)video.height, + (int)video.crop.width, (int)video.crop.height, + (int)format->es->video.width, (int)format->es->video.height, + (int)format->es->video.crop.width, (int)format->es->video.crop.height); + mmalomx_callback_event_handler(component, OMX_EventPortSettingsChanged, + port->index, 0, NULL); + } + } + else if (event && port->mmal->type == MMAL_PORT_TYPE_OUTPUT && + port->mmal->format->type == MMAL_ES_TYPE_AUDIO) + { + uint32_t diff = mmal_format_compare(event->format, port->mmal->format); + MMAL_ES_FORMAT_T *format = port->mmal->format; + MMAL_AUDIO_FORMAT_T audio = format->es->audio; + + /* Update the port settings with the new values */ + mmal_format_copy(format, event->format); + port->mmal->buffer_num_min = event->buffer_num_min; + port->mmal->buffer_size_min = event->buffer_size_min; + port->format_changed = MMAL_TRUE; + + if (diff) + { + LOG_DEBUG("format change %ich, %iHz, %ibps -> %ich, %iHz, %ibps", + (int)audio.channels, (int)audio.sample_rate, + (int)audio.bits_per_sample, + (int)format->es->audio.channels, + (int)format->es->audio.sample_rate, + (int)format->es->audio.bits_per_sample); + mmalomx_callback_event_handler(component, OMX_EventPortSettingsChanged, + port->index, 0, NULL); + } + } +} + +/*****************************************************************************/ +OMX_ERRORTYPE mmalomx_buffer_return( + MMALOMX_PORT_T *port, + MMAL_BUFFER_HEADER_T *mmal_buffer) +{ + MMALOMX_COMPONENT_T *component = port->component; + OMX_BUFFERHEADERTYPE *omx_buffer = (OMX_BUFFERHEADERTYPE *)mmal_buffer->user_data; + MMAL_BOOL_T signal; + + if (mmal_buffer->cmd) + { + mmalomx_buffer_event(port, mmal_buffer); + mmal_buffer_header_release(mmal_buffer); + return OMX_ErrorNone; + } + + if (ENABLE_MMAL_EXTRA_LOGGING) + LOG_TRACE("hComponent %p, port %i, pBuffer %p", component, + port->index, omx_buffer); + + vcos_assert(omx_buffer->pBuffer == mmal_buffer->data); + mmalil_buffer_header_to_omx(omx_buffer, mmal_buffer); + mmal_buffer_header_release(mmal_buffer); + + if ((omx_buffer->nFlags & OMX_BUFFERFLAG_EOS) && port->direction == OMX_DirOutput) + { + mmalomx_callback_event_handler(component, OMX_EventBufferFlag, + port->index, omx_buffer->nFlags, NULL); + } + + mmalomx_mark_process_outgoing(component, port, omx_buffer); + + if (port->direction == OMX_DirInput) + component->callbacks.EmptyBufferDone((OMX_HANDLETYPE)&component->omx, + component->callbacks_data, omx_buffer ); + else + component->callbacks.FillBufferDone((OMX_HANDLETYPE)&component->omx, + component->callbacks_data, omx_buffer ); + + MMALOMX_LOCK_PORT(component, port); + signal = port->actions & MMALOMX_ACTION_CHECK_FLUSHED; + port->buffers_in_transit--; + MMALOMX_UNLOCK_PORT(component, port); + + if (signal) + mmalomx_commands_actions_signal(component); + + return OMX_ErrorNone; +} + diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/openmaxil/mmalomx_buffer.h b/external_src/raspicam-0.1.3/dependencies/mmal/openmaxil/mmalomx_buffer.h new file mode 100644 index 0000000..425f7ef --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/openmaxil/mmalomx_buffer.h @@ -0,0 +1,39 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. +*/ + +/** \file + * OpenMAX IL adaptation layer for MMAL - Buffer related functions + */ + +OMX_ERRORTYPE mmalomx_buffer_send( + MMALOMX_COMPONENT_T *component, + OMX_BUFFERHEADERTYPE *omx_buffer, + OMX_DIRTYPE direction); + +OMX_ERRORTYPE mmalomx_buffer_return( + MMALOMX_PORT_T *port, + MMAL_BUFFER_HEADER_T *mmal_buffer); diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/openmaxil/mmalomx_commands.c b/external_src/raspicam-0.1.3/dependencies/mmal/openmaxil/mmalomx_commands.c new file mode 100644 index 0000000..dd395d4 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/openmaxil/mmalomx_commands.c @@ -0,0 +1,462 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 "mmalomx.h" +#include "mmalomx_commands.h" +#include "mmalomx_buffer.h" +#include "mmalomx_logging.h" + +typedef struct { + OMX_STATETYPE state; + OMX_STATETYPE request; + uint32_t actions; +} MMALOMX_STATE_TRANSITION_T; + +MMALOMX_STATE_TRANSITION_T state_transition_table[] = +{ + {OMX_StateInvalid, OMX_StateInvalid, 0}, + {OMX_StateLoaded, OMX_StateIdle, MMALOMX_ACTION_CHECK_ALLOCATED|MMALOMX_ACTION_ENABLE}, + {OMX_StateLoaded, OMX_StateWaitForResources, 0}, + {OMX_StateWaitForResources, OMX_StateLoaded, 0}, + {OMX_StateWaitForResources, OMX_StateIdle, MMALOMX_ACTION_CHECK_ALLOCATED|MMALOMX_ACTION_ENABLE}, + {OMX_StateIdle, OMX_StateLoaded, MMALOMX_ACTION_CHECK_DEALLOCATED|MMALOMX_ACTION_DISABLE}, + {OMX_StateIdle, OMX_StateExecuting, 0}, + {OMX_StateIdle, OMX_StatePause, 0}, + {OMX_StateExecuting, OMX_StateIdle, MMALOMX_ACTION_FLUSH|MMALOMX_ACTION_CHECK_FLUSHED}, + {OMX_StateExecuting, OMX_StatePause, 0}, + {OMX_StatePause, OMX_StateIdle, 0}, + {OMX_StatePause, OMX_StateExecuting, 0}, + {OMX_StateMax, OMX_StateMax, 0} +}; + +/*****************************************************************************/ +static unsigned int mmalomx_state_transition_get(OMX_STATETYPE state, OMX_STATETYPE request) +{ + unsigned int i; + + for (i = 0; state_transition_table[i].state != OMX_StateMax; i++) + if (state_transition_table[i].state == state && + state_transition_table[i].request == request) + break; + + return state_transition_table[i].state != OMX_StateMax ? i : 0; +} + +/*****************************************************************************/ +static void mmalomx_buffer_cb_io(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) +{ + mmalomx_buffer_return((MMALOMX_PORT_T *)port->userdata, buffer); +} + +/*****************************************************************************/ +static void mmalomx_commands_check_port_actions(MMALOMX_COMPONENT_T *component, + MMALOMX_PORT_T *port) +{ + uint32_t exec_actions = 0; + MMAL_STATUS_T status; + + MMALOMX_LOCK_PORT(component, port); + if (!port->actions) + { + MMALOMX_UNLOCK_PORT(component, port); + return; + } + + if (port->actions & MMALOMX_ACTION_FLUSH) + { + port->actions &= ~MMALOMX_ACTION_FLUSH; + port->actions |= MMALOMX_ACTION_PENDING_FLUSH; + exec_actions |= MMALOMX_ACTION_PENDING_FLUSH; + } + if ((port->actions & MMALOMX_ACTION_DISABLE) && + (!port->buffers_in_transit || + !(port->actions & MMALOMX_ACTION_CHECK_FLUSHED))) + { + port->actions &= ~MMALOMX_ACTION_DISABLE; + port->actions |= MMALOMX_ACTION_PENDING_DISABLE; + exec_actions |= MMALOMX_ACTION_PENDING_DISABLE; + } + if ((port->actions & MMALOMX_ACTION_ENABLE) && + port->buffers) + { + /* We defer enabling the mmal port until the first buffer allocation + * has been done. Only at that point do we know for sure whether we + * are going to use shared memory or not. + * We might want to delay it to just before sending the event to the client ??? + */ + port->actions &= ~MMALOMX_ACTION_ENABLE; + port->actions |= MMALOMX_ACTION_PENDING_ENABLE; + exec_actions |= MMALOMX_ACTION_PENDING_ENABLE; + } + MMALOMX_UNLOCK_PORT(component, port); + + if (exec_actions & MMALOMX_ACTION_PENDING_FLUSH) + mmal_port_flush(port->mmal); + + if (exec_actions & MMALOMX_ACTION_PENDING_DISABLE) + { + mmal_port_disable(port->mmal); + + /* If there was a port format changed event, we need to make sure + * the new format has been committed */ + if (port->format_changed) + { + status = mmal_port_format_commit(port->mmal); + if (status != MMAL_SUCCESS) + LOG_WARN("could not commit new format (%i)", status); + port->format_changed = MMAL_FALSE; + } + } + + if (exec_actions & MMALOMX_ACTION_PENDING_ENABLE) + { + status = mmal_port_enable(port->mmal, mmalomx_buffer_cb_io); + if (status == MMAL_SUCCESS) + status = mmal_pool_resize(port->pool, port->mmal->buffer_num, 0); + if (status != MMAL_SUCCESS) + mmalomx_callback_event_handler(component, OMX_EventError, mmalil_error_to_omx(status), 0, NULL); + /* FIXME: we're still going to generate a cmd complete. Not sure if that's an issue. */ + } + + MMALOMX_LOCK_PORT(component, port); + + port->actions &= ~exec_actions; + if ((port->actions & MMALOMX_ACTION_CHECK_ALLOCATED) && port->populated) + port->actions &= ~MMALOMX_ACTION_CHECK_ALLOCATED; + if ((port->actions & MMALOMX_ACTION_CHECK_DEALLOCATED) && !port->buffers) + port->actions &= ~MMALOMX_ACTION_CHECK_DEALLOCATED; + if ((port->actions & MMALOMX_ACTION_CHECK_FLUSHED) && !port->buffers_in_transit) + port->actions &= ~MMALOMX_ACTION_CHECK_FLUSHED; + exec_actions = port->actions; + + if (port->actions == MMALOMX_ACTION_NOTIFY_FLUSH || + port->actions == MMALOMX_ACTION_NOTIFY_ENABLE || + port->actions == MMALOMX_ACTION_NOTIFY_DISABLE) + port->actions = 0; /* We're done */ + + MMALOMX_UNLOCK_PORT(component, port); + + if (exec_actions == MMALOMX_ACTION_NOTIFY_FLUSH) + mmalomx_callback_event_handler(component, OMX_EventCmdComplete, + OMX_CommandFlush, port->index, NULL); + else if (exec_actions == MMALOMX_ACTION_NOTIFY_ENABLE) + mmalomx_callback_event_handler(component, OMX_EventCmdComplete, + OMX_CommandPortEnable, port->index, NULL); + else if (exec_actions == MMALOMX_ACTION_NOTIFY_DISABLE) + mmalomx_callback_event_handler(component, OMX_EventCmdComplete, + OMX_CommandPortDisable, port->index, NULL); +} + +/*****************************************************************************/ +void mmalomx_commands_actions_check(MMALOMX_COMPONENT_T *component) +{ + uint32_t actions_left = 0; + unsigned int i; + + for (i = 0; i < component->ports_num; i++) + mmalomx_commands_check_port_actions(component, &component->ports[i]); + + MMALOMX_LOCK(component); + for (i = 0; i < component->ports_num; i++) + actions_left |= component->ports[i].actions; + + if (!actions_left && component->state_transition) + { + component->state = state_transition_table[component->state_transition].request; + component->state_transition = 0; + actions_left = MMALOMX_ACTION_NOTIFY_STATE; + } + MMALOMX_UNLOCK(component); + + if (actions_left == MMALOMX_ACTION_NOTIFY_STATE) + { + mmalomx_callback_event_handler(component, OMX_EventCmdComplete, + OMX_CommandStateSet, component->state, NULL); + actions_left = 0; + } + + /* If we're not currently processing a command, we can start processing + * the next one. */ + if (!actions_left) + mmalomx_commands_actions_next(component); +} + +/*****************************************************************************/ +void mmalomx_commands_actions_signal(MMALOMX_COMPONENT_T *component) +{ + if (component->cmd_thread_used) + vcos_semaphore_post(&component->cmd_sema); + else + mmalomx_commands_actions_check(component); +} + +/*****************************************************************************/ +OMX_ERRORTYPE mmalomx_command_state_set( + OMX_HANDLETYPE hComponent, + OMX_STATETYPE state) +{ + MMALOMX_COMPONENT_T *component = (MMALOMX_COMPONENT_T *)hComponent; + unsigned int i, transition; + + if (component->state == state) + { + mmalomx_callback_event_handler(component, OMX_EventError, OMX_ErrorSameState, 0, NULL); + return OMX_ErrorNone; + } + + /* We're asked to transition to StateInvalid */ + if (state == OMX_StateInvalid) + { + component->state = state; + mmalomx_callback_event_handler(component, OMX_EventError, OMX_ErrorInvalidState, 0, NULL); + return OMX_ErrorNone; + } + + /* Commands are being queued so we should never get into that state */ + vcos_assert(!component->state_transition); + + /* Check the transition is valid */ + transition = mmalomx_state_transition_get(component->state, state); + if (!transition) + { + mmalomx_callback_event_handler(component, OMX_EventError, OMX_ErrorIncorrectStateTransition, 0, NULL); + return OMX_ErrorNone; + } + + /* Special case for transition in and out of Executing */ + if (state == OMX_StateExecuting || component->state == OMX_StateExecuting) + { + MMAL_STATUS_T status; + + if (state == OMX_StateExecuting) + status = mmal_component_enable(component->mmal); + else + status = mmal_component_disable(component->mmal); + + if (status != MMAL_SUCCESS) + { + LOG_ERROR("could not %s %s", state == OMX_StateExecuting ? "enable" : "disable", component->name); + mmalomx_callback_event_handler(component, OMX_EventError, mmalil_error_to_omx(status), 0, NULL); + return OMX_ErrorNone; + } + } + + MMALOMX_LOCK(component); + component->state_transition = transition; + + for (i = 0; i < component->ports_num; i++) + { + if (!component->ports[i].enabled) + continue; + + MMALOMX_LOCK_PORT(component, component->ports + i); + component->ports[i].actions = state_transition_table[transition].actions; + + /* If we're transitionning from Idle to Loaded we'd rather do a flush first + * to avoid the cmd thread to block for too long (mmal_disable is a + * blocking call). */ + if (state_transition_table[transition].state == OMX_StateIdle && + state_transition_table[transition].request == OMX_StateLoaded && + component->cmd_thread_used) + component->ports[i].actions |= MMALOMX_ACTION_FLUSH|MMALOMX_ACTION_CHECK_FLUSHED; + MMALOMX_UNLOCK_PORT(component, component->ports + i); + } + MMALOMX_UNLOCK(component); + + mmalomx_commands_actions_check(component); + return OMX_ErrorNone; +} + +/*****************************************************************************/ +OMX_ERRORTYPE mmalomx_command_port_mark( + OMX_HANDLETYPE hComponent, + OMX_U32 nPortIndex, + OMX_PTR *pCmdData) +{ + MMALOMX_COMPONENT_T *component = (MMALOMX_COMPONENT_T *)hComponent; + OMX_MARKTYPE *mark = (OMX_MARKTYPE *)pCmdData; + MMALOMX_PORT_T *port; + + if (nPortIndex >= component->ports_num) + return OMX_ErrorBadPortIndex; + port = &component->ports[nPortIndex]; + + if (port->marks_num == MAX_MARKS_NUM) + return OMX_ErrorInsufficientResources; + + port->marks[(port->marks_first + port->marks_num) % MAX_MARKS_NUM] = *mark; + port->marks_num++; + + return OMX_ErrorNone; +} + +/*****************************************************************************/ +OMX_ERRORTYPE mmalomx_command_port_flush( + OMX_HANDLETYPE hComponent, + OMX_U32 nPortIndex) +{ + MMALOMX_COMPONENT_T *component = (MMALOMX_COMPONENT_T *)hComponent; + + MMALOMX_LOCK_PORT(component, &component->ports[nPortIndex]); + component->ports[nPortIndex].actions = + MMALOMX_ACTION_FLUSH|MMALOMX_ACTION_CHECK_FLUSHED|MMALOMX_ACTION_NOTIFY_FLUSH; + MMALOMX_UNLOCK_PORT(component, &component->ports[nPortIndex]); + + mmalomx_commands_actions_check(component); + + return OMX_ErrorNone; +} + +/*****************************************************************************/ +OMX_ERRORTYPE mmalomx_command_port_enable( + OMX_HANDLETYPE hComponent, + OMX_U32 nPortIndex) +{ + MMALOMX_COMPONENT_T *component = (MMALOMX_COMPONENT_T *)hComponent; + component->ports[nPortIndex].enabled = MMAL_TRUE; + + if (component->state == OMX_StateLoaded || + component->state == OMX_StateWaitForResources) + { + mmalomx_callback_event_handler(component, OMX_EventCmdComplete, OMX_CommandPortEnable, nPortIndex, NULL); + return OMX_ErrorNone; + } + + MMALOMX_LOCK_PORT(component, &component->ports[nPortIndex]); + component->ports[nPortIndex].actions = + MMALOMX_ACTION_CHECK_ALLOCATED|MMALOMX_ACTION_ENABLE|MMALOMX_ACTION_NOTIFY_ENABLE; + MMALOMX_UNLOCK_PORT(component, &component->ports[nPortIndex]); + + mmalomx_commands_actions_check(component); + + return OMX_ErrorNone; +} + +/*****************************************************************************/ +OMX_ERRORTYPE mmalomx_command_port_disable( + OMX_HANDLETYPE hComponent, + OMX_U32 nPortIndex) +{ + MMALOMX_COMPONENT_T *component = (MMALOMX_COMPONENT_T *)hComponent; + component->ports[nPortIndex].enabled = MMAL_FALSE; + + if (component->state == OMX_StateLoaded || + component->state == OMX_StateWaitForResources) + { + mmalomx_callback_event_handler(component, OMX_EventCmdComplete, OMX_CommandPortDisable, nPortIndex, NULL); + return OMX_ErrorNone; + } + + MMALOMX_LOCK_PORT(component, &component->ports[nPortIndex]); + component->ports[nPortIndex].actions = + MMALOMX_ACTION_DISABLE|MMALOMX_ACTION_CHECK_DEALLOCATED|MMALOMX_ACTION_NOTIFY_DISABLE; + if (component->cmd_thread_used) + component->ports[nPortIndex].actions |= + MMALOMX_ACTION_FLUSH|MMALOMX_ACTION_CHECK_FLUSHED; + MMALOMX_UNLOCK_PORT(component, &component->ports[nPortIndex]); + + mmalomx_commands_actions_check(component); + + return OMX_ErrorNone; +} + +/*****************************************************************************/ +OMX_ERRORTYPE mmalomx_command_queue( + MMALOMX_COMPONENT_T *component, + OMX_U32 arg1, OMX_U32 arg2) +{ + MMAL_BUFFER_HEADER_T *cmd = mmal_queue_get(component->cmd_pool->queue); + + if (!vcos_verify(cmd)) + { + LOG_ERROR("command queue too small"); + return OMX_ErrorInsufficientResources; + } + + cmd->cmd = arg1; + cmd->offset = arg2; + mmal_queue_put(component->cmd_queue, cmd); + + mmalomx_commands_actions_signal(component); + + return OMX_ErrorNone; +} + +/*****************************************************************************/ +OMX_ERRORTYPE mmalomx_command_dequeue( + MMALOMX_COMPONENT_T *component, + OMX_U32 *arg1, OMX_U32 *arg2) +{ + MMAL_BUFFER_HEADER_T *cmd = mmal_queue_get(component->cmd_queue); + if (!cmd) + return OMX_ErrorNoMore; + + *arg1 = cmd->cmd; + *arg2 = cmd->offset; + mmal_buffer_header_release(cmd); + return OMX_ErrorNone; +} + +/*****************************************************************************/ +void mmalomx_commands_actions_next(MMALOMX_COMPONENT_T *component) +{ + OMX_ERRORTYPE status = OMX_ErrorNone; + OMX_COMMANDTYPE cmd; + OMX_U32 arg1, arg2, nParam1; + unsigned int i; + + status = mmalomx_command_dequeue(component, &arg1, &arg2); + if (status != OMX_ErrorNone) + return; + + cmd = (OMX_COMMANDTYPE)arg1; + nParam1 = arg2; + + if (cmd == OMX_CommandStateSet) + { + mmalomx_command_state_set((OMX_HANDLETYPE)&component->omx, nParam1); + } + else if (cmd == OMX_CommandFlush) + { + for (i = 0; i < component->ports_num; i++) + if (i == nParam1 || nParam1 == OMX_ALL) + mmalomx_command_port_flush((OMX_HANDLETYPE)&component->omx, i); + } + else if (cmd == OMX_CommandPortEnable) + { + for (i = 0; i < component->ports_num; i++) + if (i == nParam1 || nParam1 == OMX_ALL) + mmalomx_command_port_enable((OMX_HANDLETYPE)&component->omx, i); + } + else if (cmd == OMX_CommandPortDisable) + { + for (i = 0; i < component->ports_num; i++) + if (i == nParam1 || nParam1 == OMX_ALL) + mmalomx_command_port_disable((OMX_HANDLETYPE)&component->omx, i); + } +} + diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/openmaxil/mmalomx_commands.h b/external_src/raspicam-0.1.3/dependencies/mmal/openmaxil/mmalomx_commands.h new file mode 100644 index 0000000..976b598 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/openmaxil/mmalomx_commands.h @@ -0,0 +1,85 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. +*/ + +/** \file + * OpenMAX IL adaptation layer for MMAL - Commands related functions + */ + +OMX_ERRORTYPE mmalomx_command_state_set( + OMX_HANDLETYPE hComponent, + OMX_STATETYPE state); + +OMX_ERRORTYPE mmalomx_command_port_mark( + OMX_HANDLETYPE hComponent, + OMX_U32 nPortIndex, + OMX_PTR *pCmdData); + +OMX_ERRORTYPE mmalomx_command_port_flush( + OMX_HANDLETYPE hComponent, + OMX_U32 nPortIndex); + +OMX_ERRORTYPE mmalomx_command_port_enable( + OMX_HANDLETYPE hComponent, + OMX_U32 nPortIndex); + +OMX_ERRORTYPE mmalomx_command_port_disable( + OMX_HANDLETYPE hComponent, + OMX_U32 nPortIndex); + +#define MMALOMX_ACTION_ENABLE 0x01 +#define MMALOMX_ACTION_DISABLE 0x02 +#define MMALOMX_ACTION_FLUSH 0x04 + +#define MMALOMX_ACTION_PENDING_ENABLE 0x010 +#define MMALOMX_ACTION_PENDING_DISABLE 0x020 +#define MMALOMX_ACTION_PENDING_FLUSH 0x040 + +#define MMALOMX_ACTION_CHECK_ALLOCATED 0x0100 +#define MMALOMX_ACTION_CHECK_DEALLOCATED 0x0200 +#define MMALOMX_ACTION_CHECK_FLUSHED 0x0400 + +#define MMALOMX_ACTION_NOTIFY_DISABLE 0x1000 +#define MMALOMX_ACTION_NOTIFY_ENABLE 0x2000 +#define MMALOMX_ACTION_NOTIFY_FLUSH 0x4000 +#define MMALOMX_ACTION_NOTIFY_STATE 0x8000 + +#define MMALOMX_COMMAND_EXIT 0 +#define MMALOMX_COMMAND_STATE_SET 1 +#define MMALOMX_COMMAND_PORT_MARK 2 +#define MMALOMX_COMMAND_PORT_FLUSH 3 +#define MMALOMX_COMMAND_PORT_ENABLE 4 +#define MMALOMX_COMMAND_PORT_DISABLE 5 + +OMX_ERRORTYPE mmalomx_command_queue( + MMALOMX_COMPONENT_T *component, OMX_U32 arg1, OMX_U32 arg2); +OMX_ERRORTYPE mmalomx_command_dequeue( + MMALOMX_COMPONENT_T *component, OMX_U32 *arg1, OMX_U32 *arg2); + +void mmalomx_commands_actions_check(MMALOMX_COMPONENT_T *component); +void mmalomx_commands_actions_signal(MMALOMX_COMPONENT_T *component); +void mmalomx_commands_actions_next(MMALOMX_COMPONENT_T *component); + diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/openmaxil/mmalomx_core.c b/external_src/raspicam-0.1.3/dependencies/mmal/openmaxil/mmalomx_core.c new file mode 100644 index 0000000..da66b0b --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/openmaxil/mmalomx_core.c @@ -0,0 +1,1577 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 "interface/vmcs_host/khronos/IL/OMX_Broadcom.h" +#include "mmalomx.h" +#include "mmalomx_commands.h" +#include "mmalomx_roles.h" +#include "mmalomx_registry.h" +#include "mmalomx_buffer.h" +#include "mmalomx_parameters.h" +#include "mmalomx_logging.h" + +#include +#include +#include +#include + +#define MAX_CMD_BUFFERS 5 + +#define PARAM_GET_PORT(port, component, index) \ + if (index >= component->ports_num) return OMX_ErrorBadPortIndex; \ + port = &component->ports[index] + +static void *mmalomx_cmd_thread_func(void *arg); +#define MMALOMX_ZERO_COPY_THRESHOLD 256 + +/*****************************************************************************/ +OMX_ERRORTYPE mmalomx_callback_event_handler( + MMALOMX_COMPONENT_T *component, + OMX_EVENTTYPE eEvent, + OMX_U32 nData1, + OMX_U32 nData2, + OMX_PTR pEventData) +{ + LOG_DEBUG("component %p, eEvent %i, nData1 %u, nData2 %u, pEventData %p", + component, (int)eEvent, (unsigned int)nData1, (unsigned int)nData2, pEventData); + return component->callbacks.EventHandler((OMX_HANDLETYPE)&component->omx, + component->callbacks_data, eEvent, nData1, nData2, pEventData); +} + +/*****************************************************************************/ +static OMX_ERRORTYPE mmalomx_ComponentGetComponentVersion( + OMX_HANDLETYPE hComponent, + OMX_STRING pComponentName, + OMX_VERSIONTYPE* pComponentVersion, + OMX_VERSIONTYPE* pSpecVersion, + OMX_UUIDTYPE* pComponentUUID) +{ + MMALOMX_COMPONENT_T *component = (MMALOMX_COMPONENT_T *)hComponent; + const char *short_name, *prefix; + + LOG_TRACE("hComponent %p, componentName %p, componentVersion %p, " + "pSpecVersion %p, componentUUID %p", + hComponent, pComponentName, pComponentVersion, pSpecVersion, + pComponentUUID); + + /* Sanity checks */ + if (!hComponent) + return OMX_ErrorInvalidComponent; + if (component->state == OMX_StateInvalid) + return OMX_ErrorInvalidState; + if (!pComponentName || !pComponentVersion || !pSpecVersion || !pComponentUUID ) + return OMX_ErrorBadParameter; + + short_name = mmalomx_registry_component_name(component->registry_id, &prefix); + + snprintf(pComponentName, OMX_MAX_STRINGNAME_SIZE, "%s%s", short_name, prefix); + pComponentVersion->nVersion = 0; + pSpecVersion->nVersion = OMX_VERSION; + snprintf((char *)(*pComponentUUID), sizeof(OMX_UUIDTYPE), "%s", pComponentName); + + return OMX_ErrorNone; +} + +/*****************************************************************************/ +static OMX_ERRORTYPE mmalomx_ComponentSendCommand( + OMX_HANDLETYPE hComponent, + OMX_COMMANDTYPE Cmd, + OMX_U32 nParam1, + OMX_PTR pCmdData) +{ + MMALOMX_COMPONENT_T *component = (MMALOMX_COMPONENT_T *)hComponent; + OMX_ERRORTYPE status = OMX_ErrorNone; + + LOG_TRACE("hComponent %p, Cmd %i (%s), nParam1 %i (%s), pCmdData %p", + hComponent, Cmd, mmalomx_cmd_to_string(Cmd), (int)nParam1, + Cmd == OMX_CommandStateSet ? mmalomx_state_to_string((OMX_STATETYPE)nParam1) : "", + pCmdData); + + /* Sanity checks */ + if (!hComponent) + return OMX_ErrorInvalidComponent; + if (component->state == OMX_StateInvalid) + return OMX_ErrorInvalidState; + + /* Sanity check port index */ + if (Cmd == OMX_CommandFlush || Cmd == OMX_CommandMarkBuffer || + Cmd == OMX_CommandPortEnable || Cmd == OMX_CommandPortDisable) + { + if (nParam1 != OMX_ALL && nParam1 >= component->ports_num) + return OMX_ErrorBadPortIndex; + } + + if (Cmd == OMX_CommandStateSet || + Cmd == OMX_CommandFlush || + Cmd == OMX_CommandPortEnable || + Cmd == OMX_CommandPortDisable) + { + status = mmalomx_command_queue(component, Cmd, nParam1); + } + else if (Cmd == OMX_CommandMarkBuffer) + { + status = mmalomx_command_port_mark(hComponent, nParam1, pCmdData); + } + else + { + status = OMX_ErrorNotImplemented; + } + + return status; +} + +/*****************************************************************************/ +static MMAL_STATUS_T mmalomx_get_port_settings(MMALOMX_PORT_T *port, OMX_PARAM_PORTDEFINITIONTYPE *def) +{ + MMAL_STATUS_T status = MMAL_SUCCESS; + MMAL_PORT_T *mmal = port->mmal; + + def->eDomain = mmalil_es_type_to_omx_domain(mmal->format->type); + def->eDir = OMX_DirInput; + if (mmal->type == MMAL_PORT_TYPE_OUTPUT) + def->eDir = OMX_DirOutput; + + if (def->eDomain == OMX_PortDomainVideo) + { + def->format.video.eColorFormat = OMX_COLOR_FormatUnused; + def->format.video.eCompressionFormat = mmalil_encoding_to_omx_video_coding(mmal->format->encoding); + if (def->format.video.eCompressionFormat == OMX_VIDEO_CodingUnused) + def->format.video.eColorFormat = mmalil_encoding_to_omx_color_format(mmal->format->encoding); + + def->format.video.nBitrate = mmal->format->bitrate; + def->format.video.nFrameWidth = mmal->format->es->video.width; + if (mmal->format->es->video.crop.width) + def->format.video.nFrameWidth = mmal->format->es->video.crop.width; + def->format.video.nStride = mmal->format->es->video.width; + if (port->no_cropping) + def->format.video.nFrameWidth = def->format.video.nStride; + def->format.video.nStride = + mmal_encoding_width_to_stride(mmal->format->encoding, def->format.video.nStride); + def->format.video.nFrameHeight = mmal->format->es->video.height; + if (mmal->format->es->video.crop.height) + def->format.video.nFrameHeight = mmal->format->es->video.crop.height; + def->format.video.nSliceHeight = mmal->format->es->video.height; + if (port->no_cropping) + def->format.video.nFrameHeight = def->format.video.nSliceHeight; + if (mmal->format->es->video.frame_rate.den) + def->format.video.xFramerate = (((int64_t)mmal->format->es->video.frame_rate.num) << 16) / + mmal->format->es->video.frame_rate.den; + else + def->format.video.xFramerate = 0; + } + else if (def->eDomain == OMX_PortDomainImage) + { + def->format.image.eColorFormat = OMX_COLOR_FormatUnused; + def->format.image.eCompressionFormat = mmalil_encoding_to_omx_image_coding(mmal->format->encoding); + if (def->format.image.eCompressionFormat == OMX_IMAGE_CodingUnused) + def->format.image.eColorFormat = mmalil_encoding_to_omx_color_format(mmal->format->encoding); + if (mmal->format->encoding == MMAL_ENCODING_UNKNOWN) + def->format.image.eCompressionFormat = OMX_IMAGE_CodingAutoDetect; + def->format.image.nFrameWidth = mmal->format->es->video.width; + if (mmal->format->es->video.crop.width) + def->format.image.nFrameWidth = mmal->format->es->video.crop.width; + def->format.image.nStride = mmal->format->es->video.width; + if (port->no_cropping) + def->format.image.nFrameWidth = def->format.image.nStride; + def->format.image.nStride = + mmal_encoding_width_to_stride(mmal->format->encoding, def->format.image.nStride); + def->format.image.nFrameHeight = mmal->format->es->video.height; + if (mmal->format->es->video.crop.height) + def->format.image.nFrameHeight = mmal->format->es->video.crop.height; + def->format.image.nSliceHeight = mmal->format->es->video.height; + if (port->no_cropping) + def->format.image.nFrameHeight = def->format.image.nSliceHeight; + } + else if(def->eDomain == OMX_PortDomainAudio) + { + def->format.audio.eEncoding = mmalil_encoding_to_omx_audio_coding(mmal->format->encoding); + } + else + { + LOG_ERROR("%s: unsupported domain (%u)", mmal->name, def->eDomain); + status = MMAL_EINVAL; + goto finish; + } + + def->nBufferAlignment = mmal->buffer_alignment_min; + def->nBufferCountActual = mmal->buffer_num; + def->nBufferCountMin = mmal->buffer_num_min; + def->nBufferSize = mmal->buffer_size; + if (def->nBufferSize < mmal->buffer_size_min) + def->nBufferSize = mmal->buffer_size_min; + def->bEnabled = port->enabled; + def->bPopulated = port->populated; + + finish: + return status; +} + +/*****************************************************************************/ +static OMX_ERRORTYPE mmalomx_ComponentGetParameter( + OMX_HANDLETYPE hComponent, + OMX_INDEXTYPE nParamIndex, + OMX_PTR pParam) +{ + MMALOMX_COMPONENT_T *component = (MMALOMX_COMPONENT_T *)hComponent; + MMALOMX_PORT_T *port = NULL; + + LOG_TRACE("hComponent %p, nParamIndex 0x%x (%s), pParam %p", + hComponent, nParamIndex, mmalomx_param_to_string(nParamIndex), pParam); + + /* Sanity checks */ + if (!hComponent) + return OMX_ErrorInvalidComponent; + if (!pParam) + return OMX_ErrorBadParameter; + if (*(OMX_U32 *)pParam < sizeof(OMX_U32) + sizeof(OMX_VERSIONTYPE)) + return OMX_ErrorBadParameter; + if (component->state == OMX_StateInvalid) + return OMX_ErrorInvalidState; + + switch(nParamIndex) + { + case OMX_IndexParamAudioInit: + case OMX_IndexParamVideoInit: + case OMX_IndexParamImageInit: + case OMX_IndexParamOtherInit: + { + OMX_PORT_PARAM_TYPE *param = (OMX_PORT_PARAM_TYPE *)pParam; + param->nStartPortNumber = 0; + param->nPorts = component->ports_domain_num[OMX_PortDomainAudio]; + if (nParamIndex == OMX_IndexParamAudioInit) + return OMX_ErrorNone; + param->nStartPortNumber += param->nPorts; + param->nPorts = component->ports_domain_num[OMX_PortDomainVideo]; + if (nParamIndex == OMX_IndexParamVideoInit) + return OMX_ErrorNone; + param->nStartPortNumber += param->nPorts; + param->nPorts = component->ports_domain_num[OMX_PortDomainImage]; + if (nParamIndex == OMX_IndexParamImageInit) + return OMX_ErrorNone; + param->nStartPortNumber += param->nPorts; + param->nPorts = component->ports_domain_num[OMX_PortDomainOther]; + } + return OMX_ErrorNone; + break; + case OMX_IndexParamPortDefinition: + { + OMX_PARAM_PORTDEFINITIONTYPE *param = (OMX_PARAM_PORTDEFINITIONTYPE *)pParam; + PARAM_GET_PORT(port, component, param->nPortIndex); + return mmalomx_get_port_settings(port, param); + } + return OMX_ErrorNone; + break; + case OMX_IndexParamCompBufferSupplier: + { + OMX_PARAM_BUFFERSUPPLIERTYPE *param = (OMX_PARAM_BUFFERSUPPLIERTYPE *)pParam; + PARAM_GET_PORT(port, component, param->nPortIndex); + param->eBufferSupplier = OMX_BufferSupplyUnspecified; + } + return OMX_ErrorNone; + break; + case OMX_IndexParamPriorityMgmt: + { + OMX_PRIORITYMGMTTYPE *param = (OMX_PRIORITYMGMTTYPE *)pParam; + param->nGroupPriority = component->group_priority; + param->nGroupID = component->group_id; + } + return OMX_ErrorNone; + break; + case OMX_IndexParamVideoPortFormat: + case OMX_IndexParamAudioPortFormat: + { + OMX_VIDEO_PARAM_PORTFORMATTYPE *param = (OMX_VIDEO_PARAM_PORTFORMATTYPE *)pParam; + PARAM_GET_PORT(port, component, param->nPortIndex); + + /* Populate our internal list of encodings the first time around */ + if (!port->encodings_num) + { + port->encodings_header.id = MMAL_PARAMETER_SUPPORTED_ENCODINGS; + port->encodings_header.size = sizeof(port->encodings_header) + sizeof(port->encodings); + if (mmal_port_parameter_get(port->mmal, &port->encodings_header) == MMAL_SUCCESS) + { + port->encodings_num = (port->encodings_header.size - sizeof(port->encodings_header)) / + sizeof(port->encodings[0]); + } + if (!port->encodings_num) + { + port->encodings_num = 1; + port->encodings[0] = port->mmal->format->encoding; + } + } + + if (param->nIndex >= port->encodings_num) + return OMX_ErrorNoMore; + + if (nParamIndex == OMX_IndexParamVideoPortFormat) + { + param->eColorFormat = OMX_COLOR_FormatUnused; + param->eCompressionFormat = + mmalil_encoding_to_omx_video_coding(port->encodings[param->nIndex]); + if (param->eCompressionFormat == OMX_VIDEO_CodingUnused) + param->eColorFormat = + mmalil_encoding_to_omx_color_format(port->encodings[param->nIndex]); + param->xFramerate = 0; + } + else + { + OMX_AUDIO_PARAM_PORTFORMATTYPE *aparam = + (OMX_AUDIO_PARAM_PORTFORMATTYPE *)pParam; + aparam->eEncoding = + mmalil_encoding_to_omx_audio_coding(port->encodings[param->nIndex]); + } + return OMX_ErrorNone; + } + break; + case OMX_IndexParamImagePortFormat: + case OMX_IndexParamOtherPortFormat: + break; + case OMX_IndexParamStandardComponentRole: + { + OMX_PARAM_COMPONENTROLETYPE *param = (OMX_PARAM_COMPONENTROLETYPE *)pParam; + const char *role = mmalomx_role_to_name(component->role); + if (!role) + role = component->name; + snprintf((char *)param->cRole, sizeof(param->cRole), "%s", role); + } + return OMX_ErrorNone; + default: + return mmalomx_parameter_get(component, nParamIndex, pParam); + } + + return OMX_ErrorNotImplemented; +} + +/*****************************************************************************/ +static MMAL_STATUS_T mmalomx_set_port_settings(MMALOMX_PORT_T *mmalomx_port, + OMX_PARAM_PORTDEFINITIONTYPE *def) +{ + MMAL_PORT_T *port = mmalomx_port->mmal; + uint32_t buffer_size_min = port->buffer_size_min; + MMAL_STATUS_T status; + + port->format->type = mmalil_omx_domain_to_es_type(def->eDomain); + port->format->encoding_variant = 0; + + if(def->eDomain == OMX_PortDomainVideo) + { + if (def->format.video.eCompressionFormat != OMX_VIDEO_CodingUnused) + port->format->encoding = mmalil_omx_video_coding_to_encoding(def->format.video.eCompressionFormat); + else + port->format->encoding = mmalil_omx_color_format_to_encoding(def->format.video.eColorFormat); + + port->format->bitrate = def->format.video.nBitrate; + port->format->es->video.width = def->format.video.nFrameWidth; + if (!mmalomx_port->no_cropping) + port->format->es->video.crop.width = port->format->es->video.width; + if (mmal_encoding_stride_to_width(port->format->encoding, def->format.video.nStride)) + port->format->es->video.width = + mmal_encoding_stride_to_width(port->format->encoding, def->format.video.nStride); + port->format->es->video.height = def->format.video.nFrameHeight; + if (!mmalomx_port->no_cropping) + port->format->es->video.crop.height = port->format->es->video.height; + if (def->format.video.nSliceHeight > def->format.video.nFrameHeight) + port->format->es->video.height = def->format.video.nSliceHeight; + port->format->es->video.frame_rate.num = def->format.video.xFramerate; + port->format->es->video.frame_rate.den = (1<<16); + } + else if(def->eDomain == OMX_PortDomainImage) + { + if (def->format.image.eCompressionFormat != OMX_IMAGE_CodingUnused) + port->format->encoding = mmalil_omx_image_coding_to_encoding(def->format.image.eCompressionFormat); + else + port->format->encoding = mmalil_omx_color_format_to_encoding(def->format.image.eColorFormat); + + port->format->es->video.width = def->format.image.nFrameWidth; + if (!mmalomx_port->no_cropping) + port->format->es->video.crop.width = port->format->es->video.width; + if (mmal_encoding_stride_to_width(port->format->encoding, def->format.image.nStride)) + port->format->es->video.width = + mmal_encoding_stride_to_width(port->format->encoding, def->format.image.nStride); + port->format->es->video.height = def->format.image.nFrameHeight; + if (!mmalomx_port->no_cropping) + port->format->es->video.crop.height = port->format->es->video.height; + if (def->format.image.nSliceHeight > def->format.image.nFrameHeight) + port->format->es->video.height = def->format.image.nSliceHeight; + } + else if(def->eDomain == OMX_PortDomainAudio) + { + port->format->encoding = mmalil_omx_audio_coding_to_encoding(def->format.audio.eEncoding); + } + else + { + port->format->encoding = MMAL_ENCODING_UNKNOWN; + } + + port->buffer_num = def->nBufferCountActual; + port->buffer_size = def->nBufferSize; + if (port->buffer_size < port->buffer_size_min) + port->buffer_size = port->buffer_size_min; + + status = mmal_port_format_commit(port); + if (status != MMAL_SUCCESS) + return status; + + /* Acknowledge any ongoing port format changed event */ + mmalomx_port->format_changed = MMAL_FALSE; + + /* The minimum buffer size only changes when the format significantly changes + * and in that case we want to advertise the new requirement to the client. */ + if (port->buffer_size_min != buffer_size_min) + port->buffer_size = port->buffer_size_min; + + return MMAL_SUCCESS; +} + +/*****************************************************************************/ +static OMX_ERRORTYPE mmalomx_ComponentSetParameter( + OMX_HANDLETYPE hComponent, + OMX_INDEXTYPE nParamIndex, + OMX_PTR pParam) +{ + MMALOMX_COMPONENT_T *component = (MMALOMX_COMPONENT_T *)hComponent; + MMALOMX_PORT_T *port = NULL; + + LOG_TRACE("hComponent %p, nParamIndex 0x%x (%s), pParam %p", + hComponent, nParamIndex, mmalomx_param_to_string(nParamIndex), pParam); + + /* Sanity checks */ + if (!hComponent) + return OMX_ErrorInvalidComponent; + if (!pParam) + return OMX_ErrorBadParameter; + if (*(OMX_U32 *)pParam < sizeof(OMX_U32) + sizeof(OMX_VERSIONTYPE)) + return OMX_ErrorBadParameter; + if (component->state == OMX_StateInvalid) + return OMX_ErrorInvalidState; + + switch(nParamIndex) + { + case OMX_IndexParamPortDefinition: + { + OMX_PARAM_PORTDEFINITIONTYPE *param = (OMX_PARAM_PORTDEFINITIONTYPE *)pParam; + PARAM_GET_PORT(port, component, param->nPortIndex); + return mmalomx_set_port_settings(port, param); + } + return OMX_ErrorNone; + break; + case OMX_IndexParamCompBufferSupplier: + { + OMX_PARAM_BUFFERSUPPLIERTYPE *param = (OMX_PARAM_BUFFERSUPPLIERTYPE *)pParam; + PARAM_GET_PORT(port, component, param->nPortIndex); + //param->eBufferSupplier = OMX_BufferSupplyUnspecified; + } + return OMX_ErrorNone; + break; + case OMX_IndexParamPriorityMgmt: + { + OMX_PRIORITYMGMTTYPE *param = (OMX_PRIORITYMGMTTYPE *)pParam; + + if (component->state != OMX_StateLoaded) + return OMX_ErrorIncorrectStateOperation; + + component->group_priority = param->nGroupPriority; + component->group_id = param->nGroupID; + } + return OMX_ErrorNone; + break; + case OMX_IndexParamAudioPortFormat: + { + OMX_AUDIO_PARAM_PORTFORMATTYPE *param = (OMX_AUDIO_PARAM_PORTFORMATTYPE *)pParam; + PARAM_GET_PORT(port, component, param->nPortIndex); + port->mmal->format->encoding = mmalil_omx_audio_coding_to_encoding(param->eEncoding); + port->mmal->format->encoding_variant = 0; + if (mmal_port_format_commit(port->mmal) != MMAL_SUCCESS) + LOG_ERROR("OMX_IndexParamAudioPortFormat commit failed"); + return OMX_ErrorNone; + } + break; + case OMX_IndexParamVideoPortFormat: + { + OMX_VIDEO_PARAM_PORTFORMATTYPE *param = (OMX_VIDEO_PARAM_PORTFORMATTYPE *)pParam; + PARAM_GET_PORT(port, component, param->nPortIndex); + if (param->eCompressionFormat != OMX_VIDEO_CodingUnused) + port->mmal->format->encoding = mmalil_omx_video_coding_to_encoding(param->eCompressionFormat); + else + port->mmal->format->encoding = mmalil_omx_color_format_to_encoding(param->eColorFormat); + port->mmal->format->encoding_variant = 0; + + if (mmal_port_format_commit(port->mmal) != MMAL_SUCCESS) + LOG_ERROR("OMX_IndexParamAudioPortFormat commit failed"); + return OMX_ErrorNone; + } + break; + case OMX_IndexParamImagePortFormat: + case OMX_IndexParamOtherPortFormat: + break; + case OMX_IndexParamStandardComponentRole: + { + OMX_PARAM_COMPONENTROLETYPE *param = (OMX_PARAM_COMPONENTROLETYPE *)pParam; + return mmalomx_role_set(component, (const char *)param->cRole); + } + break; + default: + { + OMX_ERRORTYPE status = mmalomx_parameter_set(component, nParamIndex, pParam); + + /* Keep track of the zero-copy state */ + if (status == OMX_ErrorNone && nParamIndex == OMX_IndexParamBrcmZeroCopy) + { + PARAM_GET_PORT(port, component, ((OMX_CONFIG_PORTBOOLEANTYPE *)pParam)->nPortIndex); + port->zero_copy = ((OMX_CONFIG_PORTBOOLEANTYPE *)pParam)->bEnabled; + } + + return status; + } + } + + return OMX_ErrorNotImplemented; +} + +/*****************************************************************************/ +static OMX_ERRORTYPE mmalomx_ComponentGetConfig( + OMX_HANDLETYPE hComponent, + OMX_INDEXTYPE nParamIndex, + OMX_PTR pParam) +{ + MMALOMX_COMPONENT_T *component = (MMALOMX_COMPONENT_T *)hComponent; + + LOG_TRACE("hComponent %p, nParamIndex 0x%x (%s), pParam %p", + hComponent, nParamIndex, mmalomx_param_to_string(nParamIndex), pParam); + + /* Sanity checks */ + if (!hComponent) + return OMX_ErrorInvalidComponent; + if (!pParam) + return OMX_ErrorBadParameter; + if (*(OMX_U32 *)pParam < sizeof(OMX_U32) + sizeof(OMX_VERSIONTYPE)) + return OMX_ErrorBadParameter; + if (component->state == OMX_StateInvalid) + return OMX_ErrorInvalidState; + + return mmalomx_parameter_get(component, nParamIndex, pParam); +} + +/*****************************************************************************/ +static OMX_ERRORTYPE mmalomx_ComponentSetConfig( + OMX_HANDLETYPE hComponent, + OMX_INDEXTYPE nParamIndex, + OMX_PTR pParam) +{ + MMALOMX_COMPONENT_T *component = (MMALOMX_COMPONENT_T *)hComponent; + + LOG_TRACE("hComponent %p, nParamIndex 0x%x (%s), pParam %p", + hComponent, nParamIndex, mmalomx_param_to_string(nParamIndex), pParam); + + /* Sanity checks */ + if (!hComponent) + return OMX_ErrorInvalidComponent; + if (!pParam) + return OMX_ErrorBadParameter; + if (*(OMX_U32 *)pParam < sizeof(OMX_U32) + sizeof(OMX_VERSIONTYPE)) + return OMX_ErrorBadParameter; + if (component->state == OMX_StateInvalid) + return OMX_ErrorInvalidState; + + return mmalomx_parameter_set(component, nParamIndex, pParam); +} + +/*****************************************************************************/ +static OMX_ERRORTYPE mmalomx_ComponentGetExtensionIndex( + OMX_HANDLETYPE hComponent, + OMX_STRING cParameterName, + OMX_INDEXTYPE* pIndexType) +{ + MMALOMX_COMPONENT_T *component = (MMALOMX_COMPONENT_T *)hComponent; + + LOG_TRACE("hComponent %p, cParameterName %s, pIndexType %p", + hComponent, cParameterName, pIndexType); + + /* Sanity checks */ + if (!hComponent) + return OMX_ErrorInvalidComponent; + if (component->state == OMX_StateInvalid) + return OMX_ErrorInvalidState; + + return mmalomx_parameter_extension_index_get(cParameterName, pIndexType); +} + +/*****************************************************************************/ +static OMX_ERRORTYPE mmalomx_ComponentGetState( + OMX_HANDLETYPE hComponent, + OMX_STATETYPE* pState) +{ + MMALOMX_COMPONENT_T *component = (MMALOMX_COMPONENT_T *)hComponent; + MMAL_PARAM_UNUSED(component); + + LOG_TRACE("hComponent %p, pState, %p", hComponent, pState); + + /* Sanity checks */ + if (!hComponent) + return OMX_ErrorInvalidComponent; + if (!pState) + return OMX_ErrorBadParameter; + + *pState = component->state; + return OMX_ErrorNone; +} + +/*****************************************************************************/ +static OMX_ERRORTYPE mmalomx_ComponentTunnelRequest( + OMX_HANDLETYPE hComponent, + OMX_U32 nPort, + OMX_HANDLETYPE hTunneledComp, + OMX_U32 nTunneledPort, + OMX_TUNNELSETUPTYPE* pTunnelSetup) +{ + MMALOMX_COMPONENT_T *component = (MMALOMX_COMPONENT_T *)hComponent; + MMAL_PARAM_UNUSED(component); + + LOG_TRACE("hComponent %p, nPort %i, hTunneledComp %p, nTunneledPort %i, " + "pTunnelSetup %p", hComponent, (int)nPort, hTunneledComp, + (int)nTunneledPort, pTunnelSetup); + + /* Sanity checks */ + if (!hComponent) + return OMX_ErrorInvalidComponent; + if (component->state == OMX_StateInvalid) + return OMX_ErrorInvalidState; + if (nPort >= component->ports_num) + return OMX_ErrorBadPortIndex; + if (component->state != OMX_StateLoaded && component->ports[nPort].enabled) + return OMX_ErrorIncorrectStateOperation; + if (hTunneledComp && !pTunnelSetup) + return OMX_ErrorBadParameter; + + if (!hTunneledComp) + return OMX_ErrorNone; + return OMX_ErrorNotImplemented; +} + +/*****************************************************************************/ +static OMX_ERRORTYPE mmalomx_ComponentUseBuffer( + OMX_HANDLETYPE hComponent, + OMX_BUFFERHEADERTYPE** ppBuffer, + OMX_U32 nPortIndex, + OMX_PTR pAppPrivate, + OMX_U32 nSizeBytes, + OMX_U8* pBuffer) +{ + MMALOMX_COMPONENT_T *component = (MMALOMX_COMPONENT_T *)hComponent; + OMX_ERRORTYPE status = OMX_ErrorNone; + MMAL_BOOL_T populated = MMAL_FALSE; + OMX_BUFFERHEADERTYPE *buffer; + MMALOMX_PORT_T *port; + + LOG_TRACE("hComponent %p, ppBufferHdr %p, nPortIndex %i, pAppPrivate %p," + " nSizeBytes %i, pBuffer %p", hComponent, ppBuffer, + (int)nPortIndex, pAppPrivate, (int)nSizeBytes, pBuffer); + + /* Sanity checks */ + if (!hComponent) + return OMX_ErrorInvalidComponent; + if (!ppBuffer) + return OMX_ErrorBadParameter; + if (component->state == OMX_StateInvalid) + return OMX_ErrorInvalidState; + if (nPortIndex >= component->ports_num) + return OMX_ErrorBadPortIndex; + + /* Make sure any previous command has been processed. + * This is not ideal since done inline but in practice the actual + * notification to the client will not be done as part of this call. */ + mmalomx_commands_actions_check(component); + + port = &component->ports[nPortIndex]; + MMALOMX_LOCK_PORT(component, port); + + if (!(port->actions & MMALOMX_ACTION_CHECK_ALLOCATED)) + status = OMX_ErrorIncorrectStateOperation; + if (port->populated) + status = OMX_ErrorIncorrectStateOperation; + if (status != OMX_ErrorNone) + goto error; + + /* Check for mismatched calls to UseBuffer/AllocateBuffer */ + if (port->buffers && port->buffers_allocated) + { + status = OMX_ErrorBadParameter; + goto error; + } + + /* Sanity check buffer size */ + if (nSizeBytes < port->mmal->buffer_size_min) + { + LOG_ERROR("buffer size too small (%i/%i)", (int)nSizeBytes, + (int)port->mmal->buffer_size_min); + status = OMX_ErrorBadParameter; + goto error; + } + if (!port->buffers) + port->mmal->buffer_size = nSizeBytes; + if (nSizeBytes > port->mmal->buffer_size) + { + LOG_ERROR("buffer size too big (%i/%i)", (int)nSizeBytes, + (int)port->mmal->buffer_size); + status = OMX_ErrorBadParameter; + goto error; + } + + buffer = calloc( 1, sizeof(*buffer) ); + if (!buffer) + { + status = OMX_ErrorInsufficientResources; + goto error; + } + + buffer->nSize = sizeof(*buffer); + buffer->nVersion.nVersion = OMX_VERSION; + buffer->nAllocLen = nSizeBytes; + buffer->pBuffer = pBuffer; + buffer->pAppPrivate = pAppPrivate; + if (port->direction == OMX_DirInput) + { + buffer->nInputPortIndex = nPortIndex; + buffer->pOutputPortPrivate = pAppPrivate; + } + else + { + buffer->nOutputPortIndex = nPortIndex; + buffer->pInputPortPrivate = pAppPrivate; + } + + *ppBuffer = buffer; + port->buffers++; + port->buffers_allocated = MMAL_FALSE; + port->populated = populated = port->buffers == port->mmal->buffer_num; + + MMALOMX_UNLOCK_PORT(component, port); + + LOG_DEBUG("allocated %i/%i buffers", port->buffers, port->mmal->buffer_num); + + if (populated) + mmalomx_commands_actions_signal(component); + + return OMX_ErrorNone; + +error: + MMALOMX_UNLOCK_PORT(component, port); + return status; +} + +/*****************************************************************************/ +static OMX_ERRORTYPE mmalomx_ComponentAllocateBuffer( + OMX_HANDLETYPE hComponent, + OMX_BUFFERHEADERTYPE** ppBuffer, + OMX_U32 nPortIndex, + OMX_PTR pAppPrivate, + OMX_U32 nSizeBytes) +{ + MMALOMX_COMPONENT_T *component = (MMALOMX_COMPONENT_T *)hComponent; + OMX_ERRORTYPE status = OMX_ErrorNone; + MMAL_BOOL_T populated = MMAL_FALSE; + OMX_BUFFERHEADERTYPE *buffer = 0; + MMALOMX_PORT_T *port; + + LOG_TRACE("hComponent %p, ppBuffer %p, nPortIndex %i, pAppPrivate %p, " + "nSizeBytes %i", hComponent, ppBuffer, (int)nPortIndex, + pAppPrivate, (int)nSizeBytes); + + /* Sanity checks */ + if (!hComponent) + return OMX_ErrorInvalidComponent; + if (!ppBuffer) + return OMX_ErrorBadParameter; + if (component->state == OMX_StateInvalid) + return OMX_ErrorInvalidState; + if (nPortIndex >= component->ports_num) + return OMX_ErrorBadPortIndex; + + /* Make sure any previous command has been processed. + * This is not ideal since done inline but in practice the actual + * notification to the client will not be done as part of this call. */ + mmalomx_commands_actions_check(component); + + port = &component->ports[nPortIndex]; + MMALOMX_LOCK_PORT(component, port); + + if (!(port->actions & MMALOMX_ACTION_CHECK_ALLOCATED)) + status = OMX_ErrorIncorrectStateOperation; + if (port->populated) + status = OMX_ErrorIncorrectStateOperation; + if (status != OMX_ErrorNone) + goto error; + + /* Check for mismatched calls to UseBuffer/AllocateBuffer */ + if (!status && port->buffers && !port->buffers_allocated) + { + status = OMX_ErrorBadParameter; + goto error; + } + + /* Sanity check buffer size */ + if (nSizeBytes < port->mmal->buffer_size_min) + { + LOG_ERROR("buffer size too small (%i/%i)", (int)nSizeBytes, + (int)port->mmal->buffer_size_min); + status = OMX_ErrorBadParameter; + goto error; + } + if (!port->buffers) + port->mmal->buffer_size = nSizeBytes; + if (nSizeBytes > port->mmal->buffer_size) + { + LOG_ERROR("buffer size too big (%i/%i)", (int)nSizeBytes, + (int)port->mmal->buffer_size); + status = OMX_ErrorBadParameter; + goto error; + } + + /* Set the zero-copy mode */ + if (!port->buffers_allocated && nSizeBytes > MMALOMX_ZERO_COPY_THRESHOLD && + !port->zero_copy) + { + MMAL_STATUS_T status = mmal_port_parameter_set_boolean(port->mmal, + MMAL_PARAMETER_ZERO_COPY, MMAL_TRUE); + if (status != MMAL_SUCCESS && status != MMAL_ENOSYS) + LOG_ERROR("failed to enable zero copy on %s", port->mmal->name); + } + + buffer = calloc( 1, sizeof(*buffer) ); + if (!buffer) + { + status = OMX_ErrorInsufficientResources; + goto error; + } + + buffer->pBuffer = mmal_port_payload_alloc(port->mmal, nSizeBytes); + if (!buffer->pBuffer) + { + status = OMX_ErrorInsufficientResources; + goto error; + } + + buffer->nSize = sizeof(*buffer); + buffer->nVersion.nVersion = OMX_VERSION; + buffer->nAllocLen = nSizeBytes; + buffer->pAppPrivate = pAppPrivate; + if (port->direction == OMX_DirInput) + { + buffer->nInputPortIndex = nPortIndex; + buffer->pOutputPortPrivate = pAppPrivate; + } + else + { + buffer->nOutputPortIndex = nPortIndex; + buffer->pInputPortPrivate = pAppPrivate; + } + /* Keep an unmodified copy of the pointer for when we come to free it */ + buffer->pPlatformPrivate = (OMX_PTR)buffer->pBuffer; + + *ppBuffer = buffer; + port->buffers++; + port->buffers_allocated = MMAL_TRUE; + port->populated = populated = port->buffers == port->mmal->buffer_num; + + MMALOMX_UNLOCK_PORT(component, port); + + LOG_DEBUG("allocated %i/%i buffers", port->buffers, port->mmal->buffer_num); + + if (populated) + mmalomx_commands_actions_signal(component); + + return OMX_ErrorNone; + +error: + if (!port->buffers_allocated && !port->zero_copy) + mmal_port_parameter_set_boolean(port->mmal, MMAL_PARAMETER_ZERO_COPY, MMAL_FALSE); + + MMALOMX_UNLOCK_PORT(component, port); + LOG_ERROR("failed to allocate %i/%i buffers", port->buffers, port->mmal->buffer_num); + if (buffer) + free(buffer); + return status; +} + +/*****************************************************************************/ +static OMX_ERRORTYPE mmalomx_ComponentFreeBuffer( + OMX_HANDLETYPE hComponent, + OMX_U32 nPortIndex, + OMX_BUFFERHEADERTYPE* pBuffer) +{ + MMALOMX_COMPONENT_T *component = (MMALOMX_COMPONENT_T *)hComponent; + OMX_ERRORTYPE status = OMX_ErrorNone; + MMAL_BOOL_T unpopulated, allocated; + MMALOMX_PORT_T *port; + unsigned int buffers; + + LOG_TRACE("hComponent %p, nPortIndex %i, pBuffer %p", + hComponent, (int)nPortIndex, pBuffer); + + /* Sanity checks */ + if (!hComponent) + return OMX_ErrorInvalidComponent; + if (!pBuffer) + return OMX_ErrorBadParameter; + if (nPortIndex >= component->ports_num) + return OMX_ErrorBadPortIndex; + + /* Make sure any previous command has been processed. + * This is not ideal since done inline but in practice the actual + * notification to the client will not be done as part of this call. */ + mmalomx_commands_actions_check(component); + + port = &component->ports[nPortIndex]; + MMALOMX_LOCK_PORT(component, port); + + if (!port->buffers) + { + status = OMX_ErrorBadParameter; + goto error; + } + + buffers = --port->buffers; + port->populated = MMAL_FALSE; + unpopulated = !(port->actions & MMALOMX_ACTION_CHECK_DEALLOCATED); + allocated = port->buffers_allocated; + + MMALOMX_UNLOCK_PORT(component, port); + + if (allocated) /* Free the unmodified pointer */ + mmal_port_payload_free(port->mmal, pBuffer->pPlatformPrivate); + free(pBuffer); + + if (allocated && !port->zero_copy) /* Reset the zero-copy status */ + mmal_port_parameter_set_boolean(port->mmal, MMAL_PARAMETER_ZERO_COPY, MMAL_FALSE); + + LOG_DEBUG("freed %i/%i buffers", port->mmal->buffer_num - port->buffers, port->mmal->buffer_num); + + if (unpopulated) + mmalomx_callback_event_handler(component, OMX_EventError, OMX_ErrorPortUnpopulated, 0, NULL); + + if (!buffers) + mmalomx_commands_actions_signal(component); + + return OMX_ErrorNone; + +error: + MMALOMX_UNLOCK_PORT(component, port); + return status; +} + +/*****************************************************************************/ +static OMX_ERRORTYPE mmalomx_ComponentEmptyThisBuffer( + OMX_HANDLETYPE hComponent, + OMX_BUFFERHEADERTYPE* pBuffer) +{ + MMALOMX_COMPONENT_T *component = (MMALOMX_COMPONENT_T *)hComponent; + + if (ENABLE_MMAL_EXTRA_LOGGING) + LOG_TRACE("hComponent %p, port %i, pBuffer %p", hComponent, + pBuffer ? (int)pBuffer->nInputPortIndex : -1, pBuffer); + + return mmalomx_buffer_send(component, pBuffer, OMX_DirInput); +} + +/*****************************************************************************/ +static OMX_ERRORTYPE mmalomx_ComponentFillThisBuffer( + OMX_HANDLETYPE hComponent, + OMX_BUFFERHEADERTYPE* pBuffer) +{ + MMALOMX_COMPONENT_T *component = (MMALOMX_COMPONENT_T *)hComponent; + + if (ENABLE_MMAL_EXTRA_LOGGING) + LOG_TRACE("hComponent %p, port %i, pBuffer %p", hComponent, + pBuffer ? (int)pBuffer->nOutputPortIndex : -1, pBuffer); + + return mmalomx_buffer_send(component, pBuffer, OMX_DirOutput); +} + +/*****************************************************************************/ +static OMX_ERRORTYPE mmalomx_ComponentSetCallbacks( + OMX_HANDLETYPE hComponent, + OMX_CALLBACKTYPE* pCallbacks, + OMX_PTR pAppData) +{ + MMALOMX_COMPONENT_T *component = (MMALOMX_COMPONENT_T *)hComponent; + MMAL_PARAM_UNUSED(component); + + LOG_TRACE("hComponent %p, pCallbacks %p, pAppData %p", + hComponent, pCallbacks, pAppData); + + /* Sanity checks */ + if (!hComponent) + return OMX_ErrorInvalidComponent; + if (!pCallbacks) + return OMX_ErrorBadParameter; + if (component->state == OMX_StateInvalid) + return OMX_ErrorInvalidState; + + if (component->state != OMX_StateLoaded) + return OMX_ErrorInvalidState; + + component->callbacks = *pCallbacks; + component->callbacks_data = pAppData; + return OMX_ErrorNone; +} + +/*****************************************************************************/ +static OMX_ERRORTYPE mmalomx_ComponentDeInit( + OMX_HANDLETYPE hComponent) +{ + MMALOMX_COMPONENT_T *component = (MMALOMX_COMPONENT_T *)hComponent; + MMAL_PARAM_UNUSED(component); + + LOG_TRACE("hComponent %p", hComponent); + + /* Sanity checks */ + if (!hComponent) + return OMX_ErrorInvalidComponent; + + return OMX_ErrorNone; +} + +/*****************************************************************************/ +static OMX_ERRORTYPE mmalomx_ComponentUseEGLImage( + OMX_HANDLETYPE hComponent, + OMX_BUFFERHEADERTYPE** ppBufferHdr, + OMX_U32 nPortIndex, + OMX_PTR pAppPrivate, + void* eglImage) +{ + MMALOMX_COMPONENT_T *component = (MMALOMX_COMPONENT_T *)hComponent; + MMAL_PARAM_UNUSED(component); + + LOG_TRACE("hComponent %p, ppBufferHdr %p, nPortIndex %i, pAppPrivate %p," + " eglImage %p", hComponent, ppBufferHdr, (int)nPortIndex, + pAppPrivate, eglImage); + + /* Sanity checks */ + if (!hComponent) + return OMX_ErrorInvalidComponent; + if (component->state == OMX_StateInvalid) + return OMX_ErrorInvalidState; + + return OMX_ErrorNotImplemented; +} + +/*****************************************************************************/ +static OMX_ERRORTYPE mmalomx_ComponentRoleEnum( + OMX_HANDLETYPE hComponent, + OMX_U8 *cRole, + OMX_U32 nIndex) +{ + MMALOMX_COMPONENT_T *component = (MMALOMX_COMPONENT_T *)hComponent; + MMALOMX_ROLE_T role; + + LOG_TRACE("hComponent %p, cRole %p, nIndex %i", + hComponent, cRole, (int)nIndex); + + /* Sanity checks */ + if (!hComponent) + return OMX_ErrorInvalidComponent; + if (component->state == OMX_StateInvalid) + return OMX_ErrorInvalidState; + + role = mmalomx_registry_component_roles(component->registry_id, nIndex); + if (!role) + return OMX_ErrorNoMore; + if (!mmalomx_role_to_name(role)) + return OMX_ErrorNoMore; + + strcpy((char *)cRole, mmalomx_role_to_name(role)); + return OMX_ErrorNone; +} + +/*****************************************************************************/ +OMX_API OMX_ERRORTYPE OMX_APIENTRY MMALOMX_EXPORT(OMX_Init)(void) +{ + mmalomx_logging_init(); + LOG_TRACE("Init"); + return OMX_ErrorNone; +} + +/*****************************************************************************/ +OMX_API OMX_ERRORTYPE OMX_APIENTRY MMALOMX_EXPORT(OMX_Deinit)(void) +{ + LOG_TRACE("Deinit"); + mmalomx_logging_deinit(); + return OMX_ErrorNone; +} + +/*****************************************************************************/ +OMX_API OMX_ERRORTYPE OMX_APIENTRY MMALOMX_EXPORT(OMX_ComponentNameEnum)( + OMX_STRING cComponentName, + OMX_U32 nNameLength, + OMX_U32 nIndex) +{ + const char *prefix, *name; + name = mmalomx_registry_component_name(nIndex, &prefix); + + LOG_TRACE("cComponentName %p, nNameLength %i, nIndex %i", + cComponentName, (int)nNameLength, (int)nIndex); + + /* Sanity checking */ + if (!cComponentName) + return OMX_ErrorBadParameter; + if (!name) + return OMX_ErrorNoMore; + if (nNameLength <= strlen(name) + strlen(prefix)) + return OMX_ErrorBadParameter; + + sprintf(cComponentName, "%s%s", prefix, name); + LOG_TRACE("cComponentName: %s", cComponentName); + return OMX_ErrorNone; +} + +/*****************************************************************************/ +static void mmalomx_buffer_cb_control( + MMAL_PORT_T *port, + MMAL_BUFFER_HEADER_T *buffer) +{ + MMALOMX_COMPONENT_T *component = (MMALOMX_COMPONENT_T *)port->userdata; + + LOG_DEBUG("received event %4.4s on port %s", (char *)&buffer->cmd, port->name); + + if (buffer->cmd == MMAL_EVENT_ERROR) + { + mmalomx_callback_event_handler(component, OMX_EventError, + mmalil_error_to_omx(*(MMAL_STATUS_T *)buffer->data), 0, NULL); + } + else if (buffer->cmd == MMAL_EVENT_EOS && + buffer->length == sizeof(MMAL_EVENT_END_OF_STREAM_T)) + { + MMAL_EVENT_END_OF_STREAM_T *eos = (MMAL_EVENT_END_OF_STREAM_T *)buffer->data; + if (eos->port_index < port->component->input_num) + { + MMALOMX_PORT_T *omx_port = (MMALOMX_PORT_T *) + port->component->input[eos->port_index]->userdata; + LOG_DEBUG("send EOS on %i", omx_port->index); + mmalomx_callback_event_handler(component, OMX_EventBufferFlag, + omx_port->index, OMX_BUFFERFLAG_EOS, NULL); + } + } + + mmal_buffer_header_release(buffer); +} + +/*****************************************************************************/ +OMX_API OMX_ERRORTYPE OMX_APIENTRY MMALOMX_EXPORT(OMX_GetHandle)( + OMX_HANDLETYPE* pHandle, + OMX_STRING cComponentName, + OMX_PTR pAppData, + OMX_CALLBACKTYPE* pCallBacks) +{ + OMX_ERRORTYPE status = OMX_ErrorInsufficientResources; + MMALOMX_COMPONENT_T *component = 0; + MMAL_COMPONENT_T *mmal_component = 0; + MMAL_STATUS_T mmal_status; + unsigned int i, ports_num; + OMX_PORTDOMAINTYPE domain; + const char *mmal_name; + int registry_id; + + LOG_TRACE("pHandle %p, cComponentName %s, pAppData %p, pCallBacks %p", + pHandle, cComponentName, pAppData, pCallBacks); + + /* Sanity check params */ + if (!pHandle || !cComponentName || !pCallBacks) + return OMX_ErrorBadParameter; + + /* Find component */ + registry_id = mmalomx_registry_find_component(cComponentName); + if (registry_id < 0) + return OMX_ErrorComponentNotFound; + + /* create and setup component */ + mmal_name = mmalomx_registry_component_mmal(registry_id); + mmal_status = mmal_component_create(mmal_name, &mmal_component); + if (mmal_status != MMAL_SUCCESS) + { + LOG_ERROR("could not create mmal component %s", mmal_name); + return mmalil_error_to_omx(mmal_status); + } + mmal_status = mmal_port_enable(mmal_component->control, mmalomx_buffer_cb_control); + if (mmal_status != MMAL_SUCCESS) + { + LOG_ERROR("could not enable %s", mmal_component->control->name); + mmal_component_destroy(mmal_component); + return mmalil_error_to_omx(mmal_status); + } + + ports_num = mmal_component->port_num - 1; + + component = calloc(1, sizeof(*component) + ports_num * sizeof(*component->ports)); + if (!component) + { + mmal_component_destroy(mmal_component); + return OMX_ErrorInsufficientResources; + } + + if (vcos_mutex_create(&component->lock, "mmalomx lock") != VCOS_SUCCESS) + { + mmal_component_destroy(mmal_component); + free(component); + return OMX_ErrorInsufficientResources; + } + if (vcos_mutex_create(&component->lock_port, "mmalomx port lock") != VCOS_SUCCESS) + { + vcos_mutex_delete(&component->lock); + mmal_component_destroy(mmal_component); + free(component); + return OMX_ErrorInsufficientResources; + } + + component->omx.nSize = sizeof(component->omx); + component->omx.nVersion.nVersion = OMX_VERSION; + component->mmal = mmal_component; + component->state = OMX_StateLoaded; + component->callbacks = *pCallBacks; + component->callbacks_data = pAppData; + component->ports = (MMALOMX_PORT_T *)&component[1]; + component->registry_id = registry_id; + component->name = mmalomx_registry_component_name(registry_id, 0); + component->role = mmalomx_registry_component_roles(registry_id, 0); + + // FIXME: make this configurable + component->cmd_thread_used = MMAL_TRUE; + + /* Sort the ports into separate OMX domains */ + for (domain = OMX_PortDomainAudio; domain < OMX_PortDomainOther; domain++) + { + for (i = 1; i < mmal_component->port_num; i++) + { + if (domain == mmalil_es_type_to_omx_domain(mmal_component->port[i]->format->type)) + { + component->ports[component->ports_num].mmal = mmal_component->port[i]; + component->ports_domain_num[domain]++; + component->ports_num++; + } + } + } + LOG_DEBUG("ports: %i audio, %i video", + component->ports_domain_num[OMX_PortDomainAudio], + component->ports_domain_num[OMX_PortDomainVideo]); + + /* Setup our ports */ + for (i = 0; i < component->ports_num; i++) + { + component->ports[i].component = component; + if (component->ports[i].mmal->type == MMAL_PORT_TYPE_OUTPUT) + component->ports[i].direction = OMX_DirOutput; + component->ports[i].index = i; + component->ports[i].enabled = MMAL_TRUE; + component->ports[i].pool = + mmal_port_pool_create(component->ports[i].mmal, 0, 0); + if (!component->ports[i].pool) + goto error; + component->ports[i].mmal->userdata = (struct MMAL_PORT_USERDATA_T *)&component->ports[i]; + } + mmal_component->control->userdata = (struct MMAL_PORT_USERDATA_T *)component; + + /* Create our OMX commands queue */ + component->cmd_queue = mmal_queue_create(); + if (!component->cmd_queue) + goto error; + component->cmd_pool = mmal_pool_create(MAX_CMD_BUFFERS, 0); + if (!component->cmd_pool) + goto error; + + if (component->cmd_thread_used && + vcos_semaphore_create(&component->cmd_sema, + "mmalomx sema", 0) != VCOS_SUCCESS) + { + component->cmd_thread_used = MMAL_FALSE; + goto error; + } + + if (component->cmd_thread_used && + vcos_thread_create(&component->cmd_thread, component->name, NULL, + mmalomx_cmd_thread_func, component) != VCOS_SUCCESS) + { + vcos_semaphore_delete(&component->cmd_sema); + component->cmd_thread_used = MMAL_FALSE; + goto error; + } + + /* Set the function pointer for the component's interface */ + component->omx.GetComponentVersion = mmalomx_ComponentGetComponentVersion; + component->omx.SendCommand = mmalomx_ComponentSendCommand; + component->omx.GetParameter = mmalomx_ComponentGetParameter; + component->omx.SetParameter = mmalomx_ComponentSetParameter; + component->omx.GetConfig = mmalomx_ComponentGetConfig; + component->omx.SetConfig = mmalomx_ComponentSetConfig; + component->omx.GetExtensionIndex = mmalomx_ComponentGetExtensionIndex; + component->omx.GetState = mmalomx_ComponentGetState; + component->omx.ComponentTunnelRequest = mmalomx_ComponentTunnelRequest; + component->omx.UseBuffer = mmalomx_ComponentUseBuffer; + component->omx.AllocateBuffer = mmalomx_ComponentAllocateBuffer; + component->omx.FreeBuffer = mmalomx_ComponentFreeBuffer; + component->omx.EmptyThisBuffer = mmalomx_ComponentEmptyThisBuffer; + component->omx.FillThisBuffer = mmalomx_ComponentFillThisBuffer; + component->omx.SetCallbacks = mmalomx_ComponentSetCallbacks; + component->omx.ComponentDeInit = mmalomx_ComponentDeInit; + component->omx.UseEGLImage = mmalomx_ComponentUseEGLImage; + component->omx.ComponentRoleEnum = mmalomx_ComponentRoleEnum; + *pHandle = (OMX_HANDLETYPE)&component->omx; + + return OMX_ErrorNone; + + error: + MMALOMX_IMPORT(OMX_FreeHandle)((OMX_HANDLETYPE)&component->omx); + return status; +} + +/*****************************************************************************/ +OMX_API OMX_ERRORTYPE OMX_APIENTRY MMALOMX_EXPORT(OMX_FreeHandle)( + OMX_HANDLETYPE hComponent) +{ + MMALOMX_COMPONENT_T *component = (MMALOMX_COMPONENT_T *)hComponent; + OMX_ERRORTYPE status; + unsigned int i; + + LOG_TRACE("hComponent %p", hComponent); + + /* Sanity check */ + if (!hComponent) + return OMX_ErrorInvalidComponent; + + if (component->omx.ComponentDeInit) + { + status = component->omx.ComponentDeInit(hComponent); + if (status != OMX_ErrorNone) + { + LOG_ERROR("ComponentDeInit failed"); + return status; + } + } + + if (component->cmd_thread_used) + { + component->cmd_thread_used = MMAL_FALSE; + vcos_semaphore_post(&component->cmd_sema); + vcos_thread_join(&component->cmd_thread, NULL); + } + + mmal_component_destroy(component->mmal); + for (i = 0; i < component->ports_num; i++) + if (component->ports[i].pool) + mmal_pool_destroy(component->ports[i].pool); + + if (component->cmd_pool) + mmal_pool_destroy(component->cmd_pool); + if (component->cmd_queue) + mmal_queue_destroy(component->cmd_queue); + if (component->cmd_thread_used) + vcos_semaphore_delete(&component->cmd_sema); + vcos_mutex_delete(&component->lock_port); + vcos_mutex_delete(&component->lock); + free(component); + return OMX_ErrorNone; +} + +/*****************************************************************************/ +OMX_API OMX_ERRORTYPE MMALOMX_EXPORT(OMX_GetRolesOfComponent)( + OMX_STRING compName, + OMX_U32 *pNumRoles, + OMX_U8 **roles) +{ + OMX_U32 i, num_roles; + MMALOMX_ROLE_T role; + int registry_id; + + LOG_TRACE("compName %s, pNumRoles %p, roles %p", compName, pNumRoles, roles); + + /* Sanity checks */ + if (!compName || !pNumRoles) + return OMX_ErrorBadParameter; + + if (!roles || *pNumRoles > MMALOMX_MAX_ROLES) + num_roles = MMALOMX_MAX_ROLES; + else + num_roles = *pNumRoles; + *pNumRoles = 0; + + /* Find component */ + registry_id = mmalomx_registry_find_component(compName); + if (registry_id < 0) + return OMX_ErrorComponentNotFound; + + /* Enumerate Roles */ + for (i = 0; i < num_roles; i++) + { + role = mmalomx_registry_component_roles(registry_id, i); + if (!role || !mmalomx_role_to_name(role)) + break; + + if(roles) + { + strncpy((char *)roles[i], mmalomx_role_to_name(role), OMX_MAX_STRINGNAME_SIZE); + LOG_DEBUG("found role: %s", roles[i]); + } + } + LOG_DEBUG("found %i roles", (int)i); + *pNumRoles = i; + + return OMX_ErrorNone; +} + +/*****************************************************************************/ +OMX_API OMX_ERRORTYPE MMALOMX_EXPORT(OMX_GetComponentsOfRole)( + OMX_STRING role, + OMX_U32 *pNumComps, + OMX_U8 **compNames) +{ + OMX_ERRORTYPE status; + OMX_HANDLETYPE handle; + OMX_COMPONENTTYPE *comp; + OMX_U8 name[OMX_MAX_STRINGNAME_SIZE], compRole[OMX_MAX_STRINGNAME_SIZE]; + OMX_U32 nNameLength = OMX_MAX_STRINGNAME_SIZE, nIndex = 0; + OMX_U32 nRoles, nIndexRoles, nComps = 0; + OMX_CALLBACKTYPE callbacks = {0,0,0}; + + LOG_TRACE("role %s, pNumComps %p, compNames %p", role, pNumComps, compNames); + + /* Sanity checks */ + if (!role || !pNumComps) + return OMX_ErrorBadParameter; + + /* Enumerates components */ + while ((status = OMX_ComponentNameEnum((OMX_STRING)name, nNameLength, + nIndex++)) == OMX_ErrorNone) + { + /* Find component */ + status = MMALOMX_IMPORT(OMX_GetHandle)(&handle, (OMX_STRING)name, 0, &callbacks); + if(status != OMX_ErrorNone) continue; + comp = (OMX_COMPONENTTYPE *)handle; + + /* Enumerate Roles */ + status = MMALOMX_IMPORT(OMX_GetRolesOfComponent)((OMX_STRING)name, &nRoles, 0); + if(status != OMX_ErrorNone) continue; + + for (nIndexRoles = 0; nIndexRoles < nRoles; nIndexRoles++) + { + status = comp->ComponentRoleEnum(handle, compRole, nIndexRoles); + if(status != OMX_ErrorNone) break; + + if(!strncmp((char *)role, (char *)compRole, OMX_MAX_STRINGNAME_SIZE)) + { + /* Found one */ + nComps++; + + if(!compNames) break; + + /* Check if enough space was provided for all the component names */ + if(nComps > *pNumComps) return OMX_ErrorBadParameter; + + strncpy((char *)compNames[nComps-1], (char *)name, OMX_MAX_STRINGNAME_SIZE); + + LOG_DEBUG("found component: %s", name); + } + } + + MMALOMX_IMPORT(OMX_FreeHandle)(handle); + } + LOG_DEBUG("found %i components", (int)nComps); + *pNumComps = nComps; + + return OMX_ErrorNone; +} + +/*****************************************************************************/ +OMX_API OMX_ERRORTYPE OMX_APIENTRY MMALOMX_EXPORT(OMX_SetupTunnel)( + OMX_HANDLETYPE hOutput, + OMX_U32 nPortOutput, + OMX_HANDLETYPE hInput, + OMX_U32 nPortInput) +{ + OMX_TUNNELSETUPTYPE tunnel_setup = {0, OMX_BufferSupplyUnspecified}; + OMX_ERRORTYPE status = OMX_ErrorNone; + + LOG_TRACE("hOutput %p, nPortOutput %d, hInput %p, nPortInput %d", + hOutput, (int)nPortOutput, hInput, (int)nPortInput); + + /* Sanity checks */ + if (!hOutput && !hInput) + return OMX_ErrorBadParameter; + + if (hOutput) + { + status = ((OMX_COMPONENTTYPE *)hOutput)->ComponentTunnelRequest( + hOutput, nPortOutput, hInput, nPortInput, &tunnel_setup); + if (status != OMX_ErrorNone) + LOG_DEBUG("OMX_SetupTunnel failed on output port (%i)", status); + } + + if (status == OMX_ErrorNone && hInput) + { + status = ((OMX_COMPONENTTYPE *)hInput)->ComponentTunnelRequest( + hInput, nPortInput, hOutput, nPortOutput, &tunnel_setup); + if (status != OMX_ErrorNone) + { + LOG_DEBUG("OMX_SetupTunnel failed on input port (%i)", status); + /* Cancel request on output port */ + if (hOutput) + ((OMX_COMPONENTTYPE *)hOutput)->ComponentTunnelRequest( + hOutput, nPortOutput, NULL, 0, NULL); + } + } + + return status; +} + +OMX_API OMX_ERRORTYPE MMALOMX_EXPORT(OMX_GetContentPipe)( + OMX_HANDLETYPE *hPipe, + OMX_STRING szURI) +{ + MMAL_PARAM_UNUSED(hPipe); + MMAL_PARAM_UNUSED(szURI); + + LOG_TRACE("hPipe %p, szURI %s", hPipe, szURI); + + return OMX_ErrorNotImplemented; +} + +/***************************************************************************** + * Processing thread + *****************************************************************************/ +static void *mmalomx_cmd_thread_func(void *arg) +{ + MMALOMX_COMPONENT_T *component = (MMALOMX_COMPONENT_T *)arg; + VCOS_STATUS_T status; + + while (component->cmd_thread_used) + { + status = vcos_semaphore_wait(&component->cmd_sema); + if (status == VCOS_EAGAIN) + continue; + mmalomx_commands_actions_check(component); + } + + return 0; +} + diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/openmaxil/mmalomx_logging.c b/external_src/raspicam-0.1.3/dependencies/mmal/openmaxil/mmalomx_logging.c new file mode 100644 index 0000000..3c2f70d --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/openmaxil/mmalomx_logging.c @@ -0,0 +1,176 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 "interface/vmcs_host/khronos/IL/OMX_Core.h" +#include "interface/vmcs_host/khronos/IL/OMX_Component.h" +#include "interface/vmcs_host/khronos/IL/OMX_Video.h" +#include "interface/vmcs_host/khronos/IL/OMX_Audio.h" +#include "interface/vmcs_host/khronos/IL/OMX_Broadcom.h" +#include "mmalomx_logging.h" +#include "mmalomx.h" +#include "mmalomx_util_params.h" +#include "interface/vcos/vcos_types.h" + +VCOS_LOG_CAT_T mmalomx_log_category; +static VCOS_LOG_LEVEL_T mmalomx_log_level = VCOS_LOG_ERROR; + +#define MMALOMX_SAT(a,b,c) ((a)<(b)?(a):(a)>(c)?(c):(a)) + +void mmalomx_logging_init(void) +{ + vcos_log_set_level(VCOS_LOG_CATEGORY, mmalomx_log_level); + vcos_log_register("mmalomx", VCOS_LOG_CATEGORY); +} + +void mmalomx_logging_deinit(void) +{ + mmalomx_log_level = mmalomx_log_category.level; + vcos_log_unregister(VCOS_LOG_CATEGORY); +} + +const char *mmalomx_param_to_string(OMX_INDEXTYPE param) +{ + static const struct { + const char *string; + const OMX_INDEXTYPE param; + } param_to_names[] = + { + {"OMX_IndexParamPriorityMgmt", OMX_IndexParamPriorityMgmt}, + {"OMX_IndexParamAudioInit", OMX_IndexParamAudioInit}, + {"OMX_IndexParamImageInit", OMX_IndexParamImageInit}, + {"OMX_IndexParamVideoInit", OMX_IndexParamVideoInit}, + {"OMX_IndexParamOtherInit", OMX_IndexParamOtherInit}, + {"OMX_IndexParamPortDefinition", OMX_IndexParamPortDefinition}, + {"OMX_IndexParamCompBufferSupplier", OMX_IndexParamCompBufferSupplier}, + {"OMX_IndexParamAudioPortFormat", OMX_IndexParamAudioPortFormat}, + {"OMX_IndexParamVideoPortFormat", OMX_IndexParamVideoPortFormat}, + {"OMX_IndexParamImagePortFormat", OMX_IndexParamImagePortFormat}, + {"OMX_IndexParamOtherPortFormat", OMX_IndexParamOtherPortFormat}, + {"OMX_IndexParamAudioPcm", OMX_IndexParamAudioPcm}, + {"OMX_IndexParamAudioAac", OMX_IndexParamAudioAac}, + {"OMX_IndexParamAudioMp3", OMX_IndexParamAudioMp3}, + {"OMX_IndexParamVideoMpeg2", OMX_IndexParamVideoMpeg2}, + {"OMX_IndexParamVideoMpeg4", OMX_IndexParamVideoMpeg4}, + {"OMX_IndexParamVideoWmv", OMX_IndexParamVideoWmv}, + {"OMX_IndexParamVideoRv", OMX_IndexParamVideoRv}, + {"OMX_IndexParamVideoAvc", OMX_IndexParamVideoAvc}, + {"OMX_IndexParamVideoH263", OMX_IndexParamVideoH263}, + {"OMX_IndexParamStandardComponentRole", OMX_IndexParamStandardComponentRole}, + {"OMX_IndexParamContentURI", OMX_IndexParamContentURI}, + {"OMX_IndexParamCommonSensorMode", OMX_IndexParamCommonSensorMode}, + {"OMX_IndexConfigCommonWhiteBalance", OMX_IndexConfigCommonWhiteBalance}, + {"OMX_IndexConfigCommonDigitalZoom", OMX_IndexConfigCommonDigitalZoom}, + {"OMX_IndexConfigCommonExposureValue", OMX_IndexConfigCommonExposureValue}, + {"OMX_IndexConfigCapturing", OMX_IndexConfigCapturing}, + {"OMX_IndexAutoPauseAfterCapture", OMX_IndexAutoPauseAfterCapture}, + {"OMX_IndexConfigCommonRotate", OMX_IndexConfigCommonRotate}, + {"OMX_IndexConfigCommonMirror", OMX_IndexConfigCommonMirror}, + {"OMX_IndexConfigCommonScale", OMX_IndexConfigCommonScale}, + {"OMX_IndexConfigCommonInputCrop", OMX_IndexConfigCommonInputCrop}, + {"OMX_IndexConfigCommonOutputCrop", OMX_IndexConfigCommonOutputCrop}, + {"OMX_IndexParamNumAvailableStreams", OMX_IndexParamNumAvailableStreams}, + {"OMX_IndexParamActiveStream", OMX_IndexParamActiveStream}, + {"OMX_IndexParamVideoBitrate", OMX_IndexParamVideoBitrate}, + {"OMX_IndexParamVideoProfileLevelQuerySupported", OMX_IndexParamVideoProfileLevelQuerySupported}, + + {"OMX_IndexParam unknown", (OMX_INDEXTYPE)0} + }; + const char *name = mmalomx_parameter_name_omx((uint32_t)param); + int i; + + if (name) + return name; + + for(i = 0; param_to_names[i].param && + param_to_names[i].param != param; i++); + + return param_to_names[i].string; +} + +const char *mmalomx_cmd_to_string(OMX_COMMANDTYPE cmd) +{ + static const char *names[] = { + "OMX_CommandStateSet", "OMX_CommandFlush", "OMX_CommandPortDisable", + "OMX_CommandPortEnable", "OMX_CommandMarkBuffer", "OMX_Command unknown" + }; + + return names[MMALOMX_SAT((int)cmd, 0, (int)vcos_countof(names)-1)]; +} + +const char *mmalomx_state_to_string(OMX_STATETYPE state) +{ + static const char *names[] = { + "OMX_StateInvalid", "OMX_StateLoaded", "OMX_StateIdle", + "OMX_StateExecuting", "OMX_StatePause", "OMX_StateWaitForResources", + "OMX_State unknown" + }; + + return names[MMALOMX_SAT((int)state, 0, (int)vcos_countof(names)-1)]; +} + +const char *mmalomx_event_to_string(OMX_EVENTTYPE event) +{ + static const char *names[] = { + "OMX_EventCmdComplete", "OMX_EventError", "OMX_EventMark", + "OMX_EventPortSettingsChanged", "OMX_EventBufferFlag", + "OMX_EventResourcesAcquired", "OMX_EventComponentResumed", + "OMX_EventDynamicResourcesAvailable", "OMX_EventPortFormatDetected", + "OMX_Event unknown" + }; + + return names[MMALOMX_SAT((int)event, 0, (int)vcos_countof(names)-1)]; +} + +const char *mmalomx_error_to_string(OMX_ERRORTYPE error) +{ + static const char *names[] = { + "OMX_ErrorInsufficientResources", "OMX_ErrorUndefined", + "OMX_ErrorInvalidComponentName", "OMX_ErrorComponentNotFound", + "OMX_ErrorInvalidComponent", "OMX_ErrorBadParameter", + "OMX_ErrorNotImplemented", "OMX_ErrorUnderflow", + "OMX_ErrorOverflow", "OMX_ErrorHardware", "OMX_ErrorInvalidState", + "OMX_ErrorStreamCorrupt", "OMX_ErrorPortsNotCompatible", + "OMX_ErrorResourcesLost", "OMX_ErrorNoMore", "OMX_ErrorVersionMismatch", + "OMX_ErrorNotReady", "OMX_ErrorTimeout", "OMX_ErrorSameState", + "OMX_ErrorResourcesPreempted", "OMX_ErrorPortUnresponsiveDuringAllocation", + "OMX_ErrorPortUnresponsiveDuringDeallocation", + "OMX_ErrorPortUnresponsiveDuringStop", "OMX_ErrorIncorrectStateTransition", + "OMX_ErrorIncorrectStateOperation", "OMX_ErrorUnsupportedSetting", + "OMX_ErrorUnsupportedIndex", "OMX_ErrorBadPortIndex", + "OMX_ErrorPortUnpopulated", "OMX_ErrorComponentSuspended", + "OMX_ErrorDynamicResourcesUnavailable", "OMX_ErrorMbErrorsInFrame", + "OMX_ErrorFormatNotDetected", "OMX_ErrorContentPipeOpenFailed", + "OMX_ErrorContentPipeCreationFailed", "OMX_ErrorSeperateTablesUsed", + "OMX_ErrorTunnelingUnsupported", + "OMX_Error unkown" + }; + + if(error == OMX_ErrorNone) return "OMX_ErrorNone"; + + error -= OMX_ErrorInsufficientResources; + return names[MMALOMX_SAT((int)error, 0, (int)vcos_countof(names)-1)]; +} diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/openmaxil/mmalomx_logging.h b/external_src/raspicam-0.1.3/dependencies/mmal/openmaxil/mmalomx_logging.h new file mode 100644 index 0000000..eb583ab --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/openmaxil/mmalomx_logging.h @@ -0,0 +1,46 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. +*/ + +/** \file + * OpenMAX IL adaptation layer for MMAL - Logging functions + */ + +#include "mmal_common.h" +#include "interface/vcos/vcos_logging.h" + +#define VCOS_LOG_CATEGORY (&mmalomx_log_category) +extern VCOS_LOG_CAT_T mmalomx_log_category; +#include + +void mmalomx_logging_init(void); +void mmalomx_logging_deinit(void); + +const char *mmalomx_param_to_string(OMX_INDEXTYPE param); +const char *mmalomx_cmd_to_string(OMX_COMMANDTYPE cmd); +const char *mmalomx_state_to_string(OMX_STATETYPE state); +const char *mmalomx_event_to_string(OMX_EVENTTYPE event); +const char *mmalomx_error_to_string(OMX_ERRORTYPE error); diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/openmaxil/mmalomx_marks.c b/external_src/raspicam-0.1.3/dependencies/mmal/openmaxil/mmalomx_marks.c new file mode 100644 index 0000000..a645af6 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/openmaxil/mmalomx_marks.c @@ -0,0 +1,101 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. +*/ + +/** \file + * OpenMAX IL adaptation layer for MMAL - Marking related functions + * + * Note that we do not support buffer marks properly other than for conformance + * testing. For input ports, we just move the mark over to the output port. + */ + +#include "mmalomx.h" +#include "mmalomx_buffer.h" +#include "mmalomx_marks.h" +#include "mmalomx_commands.h" +#include "mmalomx_logging.h" + +#define MMALOMX_GET_MARK(port, mark) \ + mark = &port->marks[port->marks_first]; \ + port->marks_num--; \ + port->marks_first = ++port->marks_first == MAX_MARKS_NUM ? 0 : port->marks_first +#define MMALOMX_PUT_MARK(port, mark) \ + port->marks[(port->marks_first + port->marks_num) % MAX_MARKS_NUM] = *mark; \ + port->marks_num++; + +void mmalomx_mark_process_incoming(MMALOMX_COMPONENT_T *component, + MMALOMX_PORT_T *port, OMX_BUFFERHEADERTYPE *omx_buffer) +{ + /* Tag buffers with OMX marks */ + if (!omx_buffer->hMarkTargetComponent && port->marks_num > 0 && + port->direction == OMX_DirInput) + { + OMX_MARKTYPE *mark; + MMALOMX_GET_MARK(port, mark); + omx_buffer->hMarkTargetComponent = mark->hMarkTargetComponent; + omx_buffer->pMarkData = mark->pMarkData; + + mmalomx_callback_event_handler(component, OMX_EventCmdComplete, + OMX_CommandMarkBuffer, port->index, NULL); + } + /* We do not support buffer marks properly other than for conformance testing. + * For input ports, we just move the mark over to the output port. */ + if (port->direction == OMX_DirInput && omx_buffer->hMarkTargetComponent) + { + OMX_MARKTYPE mark = {omx_buffer->hMarkTargetComponent, omx_buffer->pMarkData}; + unsigned int i; + for (i = 0; i < component->ports_num; i++) + { + if (component->ports[i].direction != OMX_DirOutput || + component->ports[i].marks_num >= MAX_MARKS_NUM) + continue; + + MMALOMX_PUT_MARK((&component->ports[i]), (&mark)); + } + } +} + +void mmalomx_mark_process_outgoing(MMALOMX_COMPONENT_T *component, + MMALOMX_PORT_T *port, OMX_BUFFERHEADERTYPE *omx_buffer) +{ + /* Tag buffers with OMX marks */ + if (port->direction == OMX_DirOutput && + !omx_buffer->hMarkTargetComponent && port->marks_num) + { + OMX_MARKTYPE *mark; + MMALOMX_GET_MARK(port, mark); + omx_buffer->hMarkTargetComponent = mark->hMarkTargetComponent; + omx_buffer->pMarkData = mark->pMarkData; + } + /* Check if we need to trigger a Mark event */ + if (omx_buffer->hMarkTargetComponent && + omx_buffer->hMarkTargetComponent == (OMX_HANDLETYPE)&component->omx) + { + mmalomx_callback_event_handler(component, OMX_EventMark, 0, 0, omx_buffer->pMarkData); + omx_buffer->hMarkTargetComponent = NULL; + omx_buffer->pMarkData = NULL; + } +} diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/openmaxil/mmalomx_marks.h b/external_src/raspicam-0.1.3/dependencies/mmal/openmaxil/mmalomx_marks.h new file mode 100644 index 0000000..f543396 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/openmaxil/mmalomx_marks.h @@ -0,0 +1,36 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. +*/ + +/** \file + * OpenMAX IL adaptation layer for MMAL - Marking related functions + */ + +void mmalomx_mark_process_incoming(MMALOMX_COMPONENT_T *component, + MMALOMX_PORT_T *port, OMX_BUFFERHEADERTYPE *omx_buffer); +void mmalomx_mark_process_outgoing(MMALOMX_COMPONENT_T *component, + MMALOMX_PORT_T *port, OMX_BUFFERHEADERTYPE *omx_buffer); + diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/openmaxil/mmalomx_parameters.c b/external_src/raspicam-0.1.3/dependencies/mmal/openmaxil/mmalomx_parameters.c new file mode 100644 index 0000000..a91b68c --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/openmaxil/mmalomx_parameters.c @@ -0,0 +1,578 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 "interface/vmcs_host/khronos/IL/OMX_Broadcom.h" +#include "mmalomx.h" +#include "mmalomx_parameters.h" +#include "mmalomx_util_params.h" +#include "mmalomx_roles.h" +#include "mmalomx_registry.h" +#include "mmalomx_logging.h" +#include +#include +#include + +#define PARAM_GET_PORT(port, component, index) \ + if (index >= component->ports_num) return OMX_ErrorBadPortIndex; \ + port = &component->ports[index] + +#define MMALOMX_PARAM_GENERIC_MAX 256 + +/** A structure capable of holding any OMX parameter that contains a port */ +typedef struct MMALOMX_PARAM_OMX_GENERIC_T +{ + MMALOMX_PARAM_OMX_HEADER_T header; + uint8_t data[MMALOMX_PARAM_GENERIC_MAX]; +} MMALOMX_PARAM_OMX_GENERIC_T; + +/** A structure capable of holding any OMX parameter that doesn't contain a port */ +typedef struct MMALOMX_PARAM_OMX_GENERIC_PORTLESS_T +{ + MMALOMX_PARAM_OMX_HEADER_PORTLESS_T hdr; + uint8_t data[MMALOMX_PARAM_GENERIC_MAX]; +} MMALOMX_PARAM_OMX_GENERIC_PORTLESS_T; + +/** A structure capable of holding any MMAL parameter */ +typedef struct MMALOMX_PARAM_MMAL_GENERIC_T +{ + MMAL_PARAMETER_HEADER_T header; + uint8_t data[MMALOMX_PARAM_GENERIC_MAX]; +} MMALOMX_PARAM_MMAL_GENERIC_T; + +static OMX_ERRORTYPE mmalomx_parameter_set_xlat(MMALOMX_COMPONENT_T *component, + OMX_INDEXTYPE nParamIndex, OMX_PTR pParam) +{ + const MMALOMX_PARAM_TRANSLATION_T *xlat = mmalomx_find_parameter_from_omx_id(nParamIndex); + MMALOMX_PARAM_OMX_HEADER_T *omx_header = (MMALOMX_PARAM_OMX_HEADER_T *)pParam; + MMALOMX_PARAM_MMAL_GENERIC_T mmal_generic; + MMAL_PARAMETER_HEADER_T *mmal_header = &mmal_generic.header; + MMAL_PORT_T *mmal_port = component->mmal->control; + MMAL_STATUS_T status; + + if (!xlat) + { + LOG_DEBUG("no translation for omx id 0x%08x", nParamIndex); + return OMX_ErrorNotImplemented; + } + + if (!xlat->portless) + { + if (omx_header->nSize < sizeof(*omx_header)) + return OMX_ErrorBadParameter; + if (omx_header->nPortIndex >= component->ports_num) + return OMX_ErrorBadPortIndex; + mmal_port = component->ports[omx_header->nPortIndex].mmal; + } + + if (omx_header->nSize < xlat->omx_size) + return OMX_ErrorBadParameter; + + /* Handle the direct case first */ + if (xlat->type == MMALOMX_PARAM_TRANSLATION_TYPE_DIRECT) + { + mmal_header = (MMAL_PARAMETER_HEADER_T *)(((uint8_t *)pParam) + (xlat->portless ? 0 : 4)); + mmal_generic.header = *mmal_header; + mmal_header->size = omx_header->nSize - (xlat->portless ? 0 : 4); + mmal_header->id = xlat->mmal_id; + status = mmal_port_parameter_set(mmal_port, mmal_header); + *mmal_header = mmal_generic.header; + return mmalil_error_to_omx(status); + } + + if (!xlat->fn.generic && !xlat->fn.simple) + { + // FIXME + return OMX_ErrorNotImplemented; + } + + // FIXME: check size of mmal_generic is sufficient + if (sizeof(mmal_generic) < xlat->mmal_size) + return OMX_ErrorBadParameter; + + mmal_header->size = xlat->mmal_size; + mmal_header->id = xlat->mmal_id; + if (xlat->fn.generic) + status = xlat->fn.generic(MMALOMX_PARAM_MAPPING_TO_MMAL, xlat, mmal_header, pParam, mmal_port); + else + status = xlat->fn.simple(MMALOMX_PARAM_MAPPING_TO_MMAL, mmal_header, pParam); + if (status != MMAL_SUCCESS) + goto error; + + status = mmal_port_parameter_set(mmal_port, mmal_header); + + error: + return mmalil_error_to_omx(status); +} + +static OMX_ERRORTYPE mmalomx_parameter_get_xlat(MMALOMX_COMPONENT_T *component, + OMX_INDEXTYPE nParamIndex, OMX_PTR pParam) +{ + const MMALOMX_PARAM_TRANSLATION_T *xlat = mmalomx_find_parameter_from_omx_id(nParamIndex); + MMALOMX_PARAM_OMX_HEADER_T *omx_header = (MMALOMX_PARAM_OMX_HEADER_T *)pParam; + MMALOMX_PARAM_MMAL_GENERIC_T mmal_generic; + MMAL_PARAMETER_HEADER_T *mmal_header = &mmal_generic.header; + MMAL_PORT_T *mmal_port = component->mmal->control; + MMAL_STATUS_T status = MMAL_SUCCESS; + + if (!xlat) + return OMX_ErrorNotImplemented; + + if (!xlat->portless) + { + if (omx_header->nSize < sizeof(*omx_header)) + return OMX_ErrorBadParameter; + if (omx_header->nPortIndex >= component->ports_num) + return OMX_ErrorBadPortIndex; + mmal_port = component->ports[omx_header->nPortIndex].mmal; + } + + if (omx_header->nSize < xlat->omx_size) + return OMX_ErrorBadParameter; + + /* Handle the direct case first */ + if (xlat->type == MMALOMX_PARAM_TRANSLATION_TYPE_DIRECT) + { + OMX_U32 size; + mmal_header = (MMAL_PARAMETER_HEADER_T *)(((uint8_t *)pParam) + (xlat->portless ? 0 : 4)); + mmal_generic.header = *mmal_header; + mmal_header->size = omx_header->nSize - (xlat->portless ? 0 : 4); + mmal_header->id = xlat->mmal_id; + status = mmal_port_parameter_get(mmal_port, mmal_header); + *mmal_header = mmal_generic.header; + size = mmal_header->size + (xlat->portless ? 0 : 4); + omx_header->nSize = size; + return mmalil_error_to_omx(status); + } + + if (xlat->fn.custom) + { + return xlat->fn.custom(MMALOMX_PARAM_MAPPING_TO_OMX, xlat, mmal_header, + pParam, mmal_port); + } + + if (xlat->fn.list) + { + OMX_U32 index, elements; + mmal_header = mmal_port_parameter_alloc_get(mmal_port, xlat->mmal_id, + 10*xlat->mmal_size, &status); + if (!mmal_header) + return OMX_ErrorInsufficientResources; + + /* Check we're not requesting too much */ + index = *(OMX_U32 *)(((uint8_t *)pParam) + xlat->xlat_enum_num); + elements = (mmal_header->size - sizeof(MMAL_PARAMETER_HEADER_T)) / + (xlat->mmal_size - sizeof(MMAL_PARAMETER_HEADER_T)); + if (index >= elements) + { + vcos_free(mmal_header); + return OMX_ErrorNoMore; + } + status = xlat->fn.list(MMALOMX_PARAM_MAPPING_TO_OMX, xlat, index, mmal_header, pParam, mmal_port); + vcos_free(mmal_header); + return mmalil_error_to_omx(status); + } + + if (!xlat->fn.generic && !xlat->fn.simple) + { + // FIXME + return OMX_ErrorNotImplemented; + } + + // FIXME: check size of mmal_generic is sufficient + if (sizeof(mmal_generic) < xlat->mmal_size) + return OMX_ErrorBadParameter; + + mmal_header->size = xlat->mmal_size; + mmal_header->id = xlat->mmal_id; + + if (xlat->double_translation) + { + if (xlat->fn.generic) + status = xlat->fn.generic(MMALOMX_PARAM_MAPPING_TO_MMAL, xlat, mmal_header, pParam, mmal_port); + else + status = xlat->fn.simple(MMALOMX_PARAM_MAPPING_TO_MMAL, mmal_header, pParam); + } + if (status != MMAL_SUCCESS) + goto error; + + status = mmal_port_parameter_get(mmal_port, mmal_header); + if (status != MMAL_SUCCESS) + goto error; + + if (xlat->fn.generic) + status = xlat->fn.generic(MMALOMX_PARAM_MAPPING_TO_OMX, xlat, mmal_header, pParam, mmal_port); + else + status = xlat->fn.simple(MMALOMX_PARAM_MAPPING_TO_OMX, mmal_header, pParam); + + error: + return mmalil_error_to_omx(status); +} + +OMX_ERRORTYPE mmalomx_parameter_extension_index_get(OMX_STRING cParameterName, + OMX_INDEXTYPE *pIndex) +{ + const MMALOMX_PARAM_TRANSLATION_T *xlat; + MMAL_BOOL_T config = MMAL_FALSE; + unsigned int i = 0; + + /* Check we're dealing with our extensions */ + if (!vcos_strncasecmp(cParameterName, MMALOMX_COMPONENT_PREFIX, sizeof(MMALOMX_COMPONENT_PREFIX)-1)) + return OMX_ErrorNotImplemented; + cParameterName += sizeof(MMALOMX_COMPONENT_PREFIX)-1; + + /* Check if we're dealing with a config or param */ + if (!vcos_strncasecmp(cParameterName, "index.config.", sizeof("index.config.")-1)) + config = MMAL_TRUE; + if (!config && vcos_strncasecmp(cParameterName, "index.param.", sizeof("index.param.")-1)) + return OMX_ErrorNotImplemented; + if (config) + cParameterName += sizeof("index.config.")-1; + else + cParameterName += sizeof("index.param.")-1; + + /* Loop through all the */ + while ((xlat = mmalomx_find_parameter_enum(i++)) != NULL) + { + const char *name = xlat->omx_name; + + /* We only report vendor extensions */ + if (xlat->omx_id < OMX_IndexVendorStartUnused) + continue; + + /* Strip out the standard prefix */ + if (config) + { + if (!strncmp(name, "OMX_IndexConfigBrcm", sizeof("OMX_IndexConfigBrcm")-1)) + name += sizeof("OMX_IndexConfigBrcm")-1; + else if (!strncmp(name, "OMX_IndexConfig", sizeof("OMX_IndexConfig")-1)) + name += sizeof("OMX_IndexConfig")-1; + else continue; + } + else + { + if (!strncmp(name, "OMX_IndexParamBrcm", sizeof("OMX_IndexParamBrcm")-1)) + name += sizeof("OMX_IndexParamBrcm")-1; + else if (!strncmp(name, "OMX_IndexParam", sizeof("OMX_IndexParam")-1)) + name += sizeof("OMX_IndexParam")-1; + else continue; + } + + /* Compare the last part of the name */ + if (!vcos_strcasecmp(name, cParameterName)) + { + *pIndex = xlat->omx_id; + return OMX_ErrorNone; + } + } + + return OMX_ErrorNotImplemented; +} + +/*****************************************************************************/ +static OMX_ERRORTYPE mmalomx_get_video_param(MMALOMX_PORT_T *port, + uint32_t *profile, uint32_t *level, uint32_t *intraperiod) +{ + MMAL_PARAMETER_VIDEO_PROFILE_T mmal_param = {{MMAL_PARAMETER_PROFILE, sizeof(mmal_param)}, + {{(MMAL_VIDEO_PROFILE_T)0, (MMAL_VIDEO_LEVEL_T)0}}}; + + *profile = *level = *intraperiod = 0; + + mmal_port_parameter_get_uint32(port->mmal, MMAL_PARAMETER_INTRAPERIOD, intraperiod); + + if (mmal_port_parameter_get(port->mmal, &mmal_param.hdr) == MMAL_SUCCESS) + { + *profile = mmalil_video_profile_to_omx(mmal_param.profile[0].profile); + *level = mmalil_video_level_to_omx(mmal_param.profile[0].level); + } + + return OMX_ErrorNone; +} + +/*****************************************************************************/ +OMX_ERRORTYPE mmalomx_parameter_get(MMALOMX_COMPONENT_T *component, + OMX_INDEXTYPE nParamIndex, OMX_PTR pParam) +{ + MMALOMX_PORT_T *port = NULL; + + switch(nParamIndex) + { + /* All OMX_IndexParamVideo parameters are only partially implemented + * and we try and use sensible hard-coded values for the rest. */ + case OMX_IndexParamVideoAvc: + { + OMX_VIDEO_PARAM_AVCTYPE *param = (OMX_VIDEO_PARAM_AVCTYPE *)pParam; + uint32_t profile, level, intraperiod; + PARAM_GET_PORT(port, component, param->nPortIndex); + if (param->nSize < sizeof(*param)) + return OMX_ErrorBadParameter; + memset(¶m->nSliceHeaderSpacing, 0, + param->nSize - offsetof(OMX_VIDEO_PARAM_AVCTYPE, nSliceHeaderSpacing)); + + mmalomx_get_video_param(port, &profile, &level, &intraperiod); + param->eProfile = (OMX_VIDEO_AVCPROFILETYPE)profile; + param->eLevel = (OMX_VIDEO_AVCLEVELTYPE)level; + param->nPFrames = intraperiod - 1; + param->bUseHadamard = OMX_TRUE; + param->nRefFrames = 1; + param->nAllowedPictureTypes = OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP; + param->bFrameMBsOnly = OMX_TRUE; + if (param->eProfile != OMX_VIDEO_AVCProfileBaseline) + param->bEntropyCodingCABAC = OMX_TRUE; + param->eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable; + } + return OMX_ErrorNone; + case OMX_IndexParamVideoMpeg4: + { + OMX_VIDEO_PARAM_MPEG4TYPE *param = (OMX_VIDEO_PARAM_MPEG4TYPE *)pParam; + uint32_t profile, level, intraperiod; + PARAM_GET_PORT(port, component, param->nPortIndex); + if (param->nSize < sizeof(*param)) + return OMX_ErrorBadParameter; + memset(¶m->nSliceHeaderSpacing, 0, + param->nSize - offsetof(OMX_VIDEO_PARAM_MPEG4TYPE, nSliceHeaderSpacing)); + + mmalomx_get_video_param(port, &profile, &level, &intraperiod); + param->eProfile = (OMX_VIDEO_MPEG4PROFILETYPE)profile; + param->eLevel = (OMX_VIDEO_MPEG4LEVELTYPE)level; + param->nPFrames = intraperiod - 1; + param->bACPred = OMX_TRUE; + param->nAllowedPictureTypes = OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP; + } + return OMX_ErrorNone; + case OMX_IndexParamVideoH263: + { + OMX_VIDEO_PARAM_H263TYPE *param = (OMX_VIDEO_PARAM_H263TYPE *)pParam; + uint32_t profile, level, intraperiod; + PARAM_GET_PORT(port, component, param->nPortIndex); + if (param->nSize < sizeof(*param)) + return OMX_ErrorBadParameter; + memset(¶m->nPFrames, 0, + param->nSize - offsetof(OMX_VIDEO_PARAM_H263TYPE, nPFrames)); + + mmalomx_get_video_param(port, &profile, &level, &intraperiod); + param->eProfile = (OMX_VIDEO_H263PROFILETYPE)profile; + param->eLevel = (OMX_VIDEO_H263LEVELTYPE)level; + param->nPFrames = intraperiod - 1; + param->nAllowedPictureTypes = OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP; + } + return OMX_ErrorNone; + case OMX_IndexParamVideoMpeg2: + case OMX_IndexParamVideoWmv: + case OMX_IndexParamVideoRv: + { + OMX_FORMAT_PARAM_TYPE *param = (OMX_FORMAT_PARAM_TYPE *)pParam; + PARAM_GET_PORT(port, component, param->common.nPortIndex); + OMX_U32 offset = offsetof(OMX_PARAM_U32TYPE, nU32); + if (param->common.nSize > sizeof(port->format_param) || + param->common.nSize < offset) + return OMX_ErrorBadParameter; + memcpy(¶m->common.nU32, &port->format_param.common.nU32, + param->common.nSize - offset); + return OMX_ErrorNone; + } + case OMX_IndexParamAudioPcm: + case OMX_IndexParamAudioAac: + case OMX_IndexParamAudioMp3: + case OMX_IndexParamAudioDdp: + { + OMX_FORMAT_PARAM_TYPE *param = (OMX_FORMAT_PARAM_TYPE *)pParam; + PARAM_GET_PORT(port, component, param->common.nPortIndex); + OMX_U32 offset = offsetof(OMX_PARAM_U32TYPE, nU32); + if (param->common.nSize > sizeof(port->format_param) || + param->common.nSize < offset) + return OMX_ErrorBadParameter; + memcpy(¶m->common.nU32, &port->format_param.common.nU32, + param->common.nSize - offset); + mmalil_format_to_omx_audio_param(param, NULL, port->mmal->format); + return OMX_ErrorNone; + } + case OMX_IndexParamBrcmPixelAspectRatio: + { + OMX_CONFIG_POINTTYPE *param = (OMX_CONFIG_POINTTYPE *)pParam; + PARAM_GET_PORT(port, component, param->nPortIndex); + param->nX = port->mmal->format->es->video.par.num; + param->nY = port->mmal->format->es->video.par.den; + return OMX_ErrorNone; + } + case OMX_IndexParamColorSpace: + { + OMX_PARAM_COLORSPACETYPE *param = (OMX_PARAM_COLORSPACETYPE *)pParam; + PARAM_GET_PORT(port, component, param->nPortIndex); + param->eColorSpace = mmalil_color_space_to_omx(port->mmal->format->es->video.color_space); + return OMX_ErrorNone; + } + case OMX_IndexConfigCommonOutputCrop: + { + OMX_CONFIG_RECTTYPE *param = (OMX_CONFIG_RECTTYPE *)pParam; + PARAM_GET_PORT(port, component, param->nPortIndex); + param->nLeft = port->mmal->format->es->video.crop.x; + param->nTop = port->mmal->format->es->video.crop.y; + param->nWidth = port->mmal->format->es->video.width; + if (port->mmal->format->es->video.crop.width) + param->nWidth = port->mmal->format->es->video.crop.width; + param->nHeight = port->mmal->format->es->video.height; + if (port->mmal->format->es->video.crop.height) + param->nHeight = port->mmal->format->es->video.crop.height; + return OMX_ErrorNone; + } + case OMX_IndexConfigCommonScale: + { + OMX_CONFIG_SCALEFACTORTYPE *param = (OMX_CONFIG_SCALEFACTORTYPE *)pParam; + PARAM_GET_PORT(port, component, param->nPortIndex); + param->xWidth = param->xHeight = 1<<16; + if (port->mmal->format->es->video.par.num && + port->mmal->format->es->video.par.den) + param->xWidth = mmal_rational_to_fixed_16_16(port->mmal->format->es->video.par); + return OMX_ErrorNone; + } + default: + return mmalomx_parameter_get_xlat(component, nParamIndex, pParam); + } + + return OMX_ErrorNotImplemented; +} + +/*****************************************************************************/ +static OMX_ERRORTYPE mmalomx_set_video_param(MMALOMX_PORT_T *port, + uint32_t profile, uint32_t level, uint32_t intraperiod) +{ + MMAL_PARAMETER_VIDEO_PROFILE_T mmal_param = {{MMAL_PARAMETER_PROFILE, sizeof(mmal_param)}, + {{(MMAL_VIDEO_PROFILE_T)0, (MMAL_VIDEO_LEVEL_T)0}}}; + OMX_VIDEO_CODINGTYPE coding = + mmalil_encoding_to_omx_video_coding(port->mmal->format->encoding); + + if (mmal_port_parameter_set_uint32(port->mmal, MMAL_PARAMETER_INTRAPERIOD, + intraperiod) != MMAL_SUCCESS) + return OMX_ErrorBadParameter; + + mmal_param.profile[0].profile = (MMAL_VIDEO_PROFILE_T) + mmalil_omx_video_profile_to_mmal(profile, coding); + mmal_param.profile[0].level = (MMAL_VIDEO_LEVEL_T) + mmalil_omx_video_level_to_mmal(level, coding); + if (mmal_port_parameter_set(port->mmal, &mmal_param.hdr) != MMAL_SUCCESS) + return OMX_ErrorBadParameter; + + return OMX_ErrorNone; +} + +/*****************************************************************************/ +OMX_ERRORTYPE mmalomx_parameter_set(MMALOMX_COMPONENT_T *component, + OMX_INDEXTYPE nParamIndex, OMX_PTR pParam) +{ + MMALOMX_PORT_T *port = NULL; + + switch(nParamIndex) + { + /* All OMX_IndexParamVideo parameters are only partially implemented */ + case OMX_IndexParamVideoAvc: + { + OMX_VIDEO_PARAM_AVCTYPE *param = (OMX_VIDEO_PARAM_AVCTYPE *)pParam; + PARAM_GET_PORT(port, component, param->nPortIndex); + if (param->nSize < sizeof(*param)) + return OMX_ErrorBadParameter; + return mmalomx_set_video_param(port, param->eProfile, param->eLevel, + param->nPFrames + 1); + } + case OMX_IndexParamVideoMpeg4: + { + OMX_VIDEO_PARAM_MPEG4TYPE *param = (OMX_VIDEO_PARAM_MPEG4TYPE *)pParam; + PARAM_GET_PORT(port, component, param->nPortIndex); + if (param->nSize < sizeof(*param)) + return OMX_ErrorBadParameter; + return mmalomx_set_video_param(port, param->eProfile, param->eLevel, + param->nPFrames + 1); + } + case OMX_IndexParamVideoH263: + { + OMX_VIDEO_PARAM_H263TYPE *param = (OMX_VIDEO_PARAM_H263TYPE *)pParam; + PARAM_GET_PORT(port, component, param->nPortIndex); + if (param->nSize < sizeof(*param)) + return OMX_ErrorBadParameter; + return mmalomx_set_video_param(port, param->eProfile, param->eLevel, + param->nPFrames + 1); + } + case OMX_IndexParamVideoMpeg2: + case OMX_IndexParamVideoWmv: + case OMX_IndexParamVideoRv: + { + OMX_FORMAT_PARAM_TYPE *param = (OMX_FORMAT_PARAM_TYPE *)pParam; + OMX_U32 offset = offsetof(OMX_PARAM_U32TYPE, nU32); + PARAM_GET_PORT(port, component, param->common.nPortIndex); + if (param->common.nSize > sizeof(port->format_param) || + param->common.nSize < offset) + return OMX_ErrorBadParameter; + memcpy(&port->format_param.common.nU32, ¶m->common.nU32, + param->common.nSize - offset); + return OMX_ErrorNone; + } + case OMX_IndexParamAudioPcm: + case OMX_IndexParamAudioAac: + case OMX_IndexParamAudioMp3: + case OMX_IndexParamAudioDdp: + { + OMX_FORMAT_PARAM_TYPE *param = (OMX_FORMAT_PARAM_TYPE *)pParam; + OMX_U32 offset = offsetof(OMX_PARAM_U32TYPE, nU32); + PARAM_GET_PORT(port, component, param->common.nPortIndex); + if (param->common.nSize > sizeof(port->format_param) || + param->common.nSize < offset) + return OMX_ErrorBadParameter; + memcpy(&port->format_param.common.nU32, ¶m->common.nU32, + param->common.nSize - offset); + mmalil_omx_audio_param_to_format(port->mmal->format, + mmalil_omx_audio_param_index_to_coding(nParamIndex), param); + mmal_port_format_commit(port->mmal); + return OMX_ErrorNone; + } + case OMX_IndexParamBrcmPixelAspectRatio: + { + OMX_CONFIG_POINTTYPE *param = (OMX_CONFIG_POINTTYPE *)pParam; + PARAM_GET_PORT(port, component, param->nPortIndex); + port->mmal->format->es->video.par.num = param->nX; + port->mmal->format->es->video.par.den = param->nY; + mmal_rational_simplify(&port->mmal->format->es->video.par); + return mmal_port_format_commit(port->mmal); + } + case OMX_IndexParamColorSpace: + { + OMX_PARAM_COLORSPACETYPE *param = (OMX_PARAM_COLORSPACETYPE *)pParam; + PARAM_GET_PORT(port, component, param->nPortIndex); + port->mmal->format->es->video.color_space = mmalil_omx_color_space_to_mmal(param->eColorSpace); + return mmal_port_format_commit(port->mmal); + } + case OMX_IndexParamBrcmVideoCroppingDisable: + { + OMX_CONFIG_PORTBOOLEANTYPE *param = (OMX_CONFIG_PORTBOOLEANTYPE *)pParam; + PARAM_GET_PORT(port, component, param->nPortIndex); + port->no_cropping = param->bEnabled; + return OMX_ErrorNone; + } + default: + return mmalomx_parameter_set_xlat(component, nParamIndex, pParam); + } + + return OMX_ErrorNotImplemented; +} diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/openmaxil/mmalomx_parameters.h b/external_src/raspicam-0.1.3/dependencies/mmal/openmaxil/mmalomx_parameters.h new file mode 100644 index 0000000..5c58c86 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/openmaxil/mmalomx_parameters.h @@ -0,0 +1,37 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. +*/ + +/** \file + * OpenMAX IL adaptation layer for MMAL - Parameters related functions + */ + +OMX_ERRORTYPE mmalomx_parameter_get(MMALOMX_COMPONENT_T *component, + OMX_INDEXTYPE nParamIndex, OMX_PTR pParam); +OMX_ERRORTYPE mmalomx_parameter_set(MMALOMX_COMPONENT_T *component, + OMX_INDEXTYPE nParamIndex, OMX_PTR pParam); +OMX_ERRORTYPE mmalomx_parameter_extension_index_get(OMX_STRING cParameterName, + OMX_INDEXTYPE *pIndex); diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/openmaxil/mmalomx_registry.c b/external_src/raspicam-0.1.3/dependencies/mmal/openmaxil/mmalomx_registry.c new file mode 100644 index 0000000..059ed6b --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/openmaxil/mmalomx_registry.c @@ -0,0 +1,159 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 "mmalomx.h" +#include "mmalomx_roles.h" +#include "mmalomx_registry.h" +#include "mmalomx_logging.h" +#include + +#ifndef ENABLE_MMALOMX_AUDIO_HW_DECODER +# define ENABLE_MMALOMX_AUDIO_HW_DECODER 0 +#endif +#ifndef ENABLE_MMALOMX_AUDIO_SPDIF +# define ENABLE_MMALOMX_AUDIO_SPDIF 1 +#endif + +static const struct { + const char *omx; + const char *omx_prefix; + const char *mmal; + MMALOMX_ROLE_T roles[MMALOMX_ROLE_MAX]; +} mmalomx_components[] = +{ + {"video.hw.decoder", 0, MMAL_COMPONENT_DEFAULT_VIDEO_DECODER, + {MMALOMX_ROLE_VIDEO_DECODER_H263, MMALOMX_ROLE_VIDEO_DECODER_MPEG2, + MMALOMX_ROLE_VIDEO_DECODER_MPEG4, MMALOMX_ROLE_VIDEO_DECODER_AVC, + MMALOMX_ROLE_VIDEO_DECODER_WMV, MMALOMX_ROLE_VIDEO_DECODER_VPX, + MMALOMX_ROLE_UNDEFINED}}, + {"video.hw.decoder.secure", 0, "drm_alloc.video_decode", + {MMALOMX_ROLE_VIDEO_DECODER_H263, MMALOMX_ROLE_VIDEO_DECODER_MPEG2, + MMALOMX_ROLE_VIDEO_DECODER_MPEG4, MMALOMX_ROLE_VIDEO_DECODER_AVC, + MMALOMX_ROLE_VIDEO_DECODER_WMV, MMALOMX_ROLE_VIDEO_DECODER_VPX, + MMALOMX_ROLE_UNDEFINED}}, + {"video.hw.decoder.divx_drm", 0, "aggregator.pipeline:divx_drm:vc.video_decode", + {MMALOMX_ROLE_VIDEO_DECODER_MPEG4, MMALOMX_ROLE_UNDEFINED}}, + {"video.vpx.decoder", 0, "libvpx", + {MMALOMX_ROLE_VIDEO_DECODER_VPX, MMALOMX_ROLE_UNDEFINED}}, + + {"video.hw.encoder", 0, MMAL_COMPONENT_DEFAULT_VIDEO_ENCODER, + {MMALOMX_ROLE_VIDEO_ENCODER_H263, MMALOMX_ROLE_VIDEO_ENCODER_MPEG4, + MMALOMX_ROLE_VIDEO_ENCODER_AVC, MMALOMX_ROLE_UNDEFINED}}, + + {"AIV.play", "", "aivplay", + {MMALOMX_ROLE_AIV_PLAY_101, MMALOMX_ROLE_AIV_PLAY_AVCDDP, MMALOMX_ROLE_UNDEFINED}}, + {"AIV.play.avcddp", "", "aivplay.ddp", + {MMALOMX_ROLE_AIV_PLAY_AVCDDP, MMALOMX_ROLE_AIV_PLAY_101, MMALOMX_ROLE_UNDEFINED}}, + +#if ENABLE_MMALOMX_AUDIO_HW_DECODER + {"audio.hw.decoder", 0, "vc.ril.audio_decode", + {MMALOMX_ROLE_AUDIO_DECODER_AAC, MMALOMX_ROLE_AUDIO_DECODER_MPGA_L1, + MMALOMX_ROLE_AUDIO_DECODER_MPGA_L2, MMALOMX_ROLE_AUDIO_DECODER_MPGA_L3, + MMALOMX_ROLE_AUDIO_DECODER_DDP, MMALOMX_ROLE_UNDEFINED}}, +#endif + +#if ENABLE_MMALOMX_AUDIO_SPDIF + {"audio.spdif", 0, "spdif", + {MMALOMX_ROLE_AUDIO_DECODER_DDP, MMALOMX_ROLE_UNDEFINED}}, +#endif + + {0, 0, 0, {MMALOMX_ROLE_UNDEFINED}} +}; + +int mmalomx_registry_find_component(const char *name) +{ + int i, prefix_size; + const char *prefix; + + for (i = 0; mmalomx_components[i].omx; i++) + { + /* Check the prefix first */ + prefix = mmalomx_components[i].omx_prefix; + if (!prefix) + prefix = MMALOMX_COMPONENT_PREFIX; + prefix_size = strlen(prefix); + if (strncmp(name, prefix, prefix_size)) + continue; + + /* Check the rest of the name */ + if (!strcmp(name + prefix_size, mmalomx_components[i].omx)) + break; + } + + return mmalomx_components[i].mmal ? i : -1; +} + +const char *mmalomx_registry_component_mmal(int id) +{ + if (id >= (int)MMAL_COUNTOF(mmalomx_components) || id < 0) + id = MMAL_COUNTOF(mmalomx_components) - 1; + + return mmalomx_components[id].mmal; +} + +MMALOMX_ROLE_T mmalomx_registry_component_roles(int id, unsigned int index) +{ + unsigned int i; + + if (id >= (int)MMAL_COUNTOF(mmalomx_components) || id < 0) + id = MMAL_COUNTOF(mmalomx_components) - 1; + + for (i = 0; i < index; i++) + if (mmalomx_components[id].roles[i] == MMALOMX_ROLE_UNDEFINED) + break; + + return mmalomx_components[id].roles[i]; +} + +MMAL_BOOL_T mmalomx_registry_component_supports_role(int id, MMALOMX_ROLE_T role) +{ + unsigned int i; + + if (id >= (int)MMAL_COUNTOF(mmalomx_components) || id < 0) + id = MMAL_COUNTOF(mmalomx_components) - 1; + + for (i = 0; mmalomx_components[id].roles[i] != MMALOMX_ROLE_UNDEFINED; i++) + if (mmalomx_components[id].roles[i] == role) + return MMAL_TRUE; + + return MMAL_FALSE; +} + +const char *mmalomx_registry_component_name(int id, const char **prefix) +{ + if (id >= (int)MMAL_COUNTOF(mmalomx_components) || id < 0) + id = MMAL_COUNTOF(mmalomx_components) - 1; + + if (prefix) + { + *prefix = mmalomx_components[id].omx_prefix; + if (!*prefix) + *prefix = MMALOMX_COMPONENT_PREFIX; + } + + return mmalomx_components[id].omx; +} diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/openmaxil/mmalomx_registry.h b/external_src/raspicam-0.1.3/dependencies/mmal/openmaxil/mmalomx_registry.h new file mode 100644 index 0000000..3a7c7f5 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/openmaxil/mmalomx_registry.h @@ -0,0 +1,41 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. +*/ + +/** \file + * OpenMAX IL adaptation layer for MMAL - Registry of components + */ + +#define MMALOMX_COMPONENT_PREFIX "OMX.brcm." + +int mmalomx_registry_find_component(const char *name); + +const char *mmalomx_registry_component_mmal(int id); + +MMALOMX_ROLE_T mmalomx_registry_component_roles(int id, unsigned int index); +MMAL_BOOL_T mmalomx_registry_component_supports_role(int id, MMALOMX_ROLE_T role); + +const char *mmalomx_registry_component_name(int index, const char **prefix); diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/openmaxil/mmalomx_roles.c b/external_src/raspicam-0.1.3/dependencies/mmal/openmaxil/mmalomx_roles.c new file mode 100644 index 0000000..17de66f --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/openmaxil/mmalomx_roles.c @@ -0,0 +1,210 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 "mmalomx.h" +#include "mmalomx_roles.h" +#include "mmalomx_registry.h" +#include "mmalomx_logging.h" + +static const struct { + const char *name; + MMALOMX_ROLE_T role; +} mmalomx_roles[] = +{ + {"video_decoder.h263", MMALOMX_ROLE_VIDEO_DECODER_H263}, + {"video_decoder.mpeg4", MMALOMX_ROLE_VIDEO_DECODER_MPEG4}, + {"video_decoder.avc", MMALOMX_ROLE_VIDEO_DECODER_AVC}, + {"video_decoder.mpeg2", MMALOMX_ROLE_VIDEO_DECODER_MPEG2}, + {"video_decoder.wmv", MMALOMX_ROLE_VIDEO_DECODER_WMV}, + {"video_decoder.vpx", MMALOMX_ROLE_VIDEO_DECODER_VPX}, + + {"video_encoder.h263", MMALOMX_ROLE_VIDEO_ENCODER_H263}, + {"video_encoder.mpeg4", MMALOMX_ROLE_VIDEO_ENCODER_MPEG4}, + {"video_encoder.avc", MMALOMX_ROLE_VIDEO_ENCODER_AVC}, + + {"audio_decoder.aac", MMALOMX_ROLE_AUDIO_DECODER_AAC}, + {"audio_decoder.mp1", MMALOMX_ROLE_AUDIO_DECODER_MPGA_L1}, + {"audio_decoder.mp2", MMALOMX_ROLE_AUDIO_DECODER_MPGA_L2}, + {"audio_decoder.mp3", MMALOMX_ROLE_AUDIO_DECODER_MPGA_L3}, + {"audio_decoder.ddp", MMALOMX_ROLE_AUDIO_DECODER_DDP}, + + {"AIV.play.101", MMALOMX_ROLE_AIV_PLAY_101}, + {"play.avcddp", MMALOMX_ROLE_AIV_PLAY_AVCDDP}, + + {0, 0} +}; + +const char *mmalomx_role_to_name(MMALOMX_ROLE_T role) +{ + unsigned int i; + for (i = 0; mmalomx_roles[i].name; i++) + if (mmalomx_roles[i].role == role) + break; + return mmalomx_roles[i].name; +} + +MMALOMX_ROLE_T mmalomx_role_from_name(const char *name) +{ + unsigned int i; + for (i = 0; mmalomx_roles[i].name; i++) + if (!strcmp(mmalomx_roles[i].name, name)) + break; + return mmalomx_roles[i].role; +} + +static void mmalomx_format_encoding_from_role(MMALOMX_ROLE_T role, + MMAL_FOURCC_T *encoding, MMAL_ES_TYPE_T *es_type, unsigned int *port) +{ + switch (role) + { + case MMALOMX_ROLE_VIDEO_DECODER_MPEG4: + case MMALOMX_ROLE_VIDEO_ENCODER_MPEG4: + *encoding = MMAL_ENCODING_MP4V; + *es_type = MMAL_ES_TYPE_VIDEO; + break; + case MMALOMX_ROLE_VIDEO_DECODER_AVC: + case MMALOMX_ROLE_VIDEO_ENCODER_AVC: + *encoding = MMAL_ENCODING_H264; + *es_type = MMAL_ES_TYPE_VIDEO; + break; + case MMALOMX_ROLE_VIDEO_DECODER_MPEG2: + *encoding = MMAL_ENCODING_MP2V; + *es_type = MMAL_ES_TYPE_VIDEO; + break; + case MMALOMX_ROLE_VIDEO_DECODER_WMV: + *encoding = MMAL_ENCODING_WMV3; + *es_type = MMAL_ES_TYPE_VIDEO; + break; + case MMALOMX_ROLE_VIDEO_DECODER_VPX: + *encoding = MMAL_ENCODING_VP8; + *es_type = MMAL_ES_TYPE_VIDEO; + break; + case MMALOMX_ROLE_VIDEO_DECODER_H263: + case MMALOMX_ROLE_VIDEO_ENCODER_H263: + *encoding = MMAL_ENCODING_H263; + *es_type = MMAL_ES_TYPE_VIDEO; + break; + case MMALOMX_ROLE_AUDIO_DECODER_AAC: + *encoding = MMAL_ENCODING_MP4A; + *es_type = MMAL_ES_TYPE_AUDIO; + break; + case MMALOMX_ROLE_AUDIO_DECODER_MPGA_L1: + case MMALOMX_ROLE_AUDIO_DECODER_MPGA_L2: + case MMALOMX_ROLE_AUDIO_DECODER_MPGA_L3: + *encoding = MMAL_ENCODING_MPGA; + *es_type = MMAL_ES_TYPE_AUDIO; + break; + + case MMALOMX_ROLE_AUDIO_DECODER_DDP: + *encoding = MMAL_ENCODING_AC3; + *es_type = MMAL_ES_TYPE_AUDIO; + break; + + default: + *encoding = MMAL_ENCODING_UNKNOWN; + *es_type = MMAL_ES_TYPE_UNKNOWN; + break; + } + + switch (role) + { + case MMALOMX_ROLE_VIDEO_ENCODER_H263: + case MMALOMX_ROLE_VIDEO_ENCODER_MPEG4: + case MMALOMX_ROLE_VIDEO_ENCODER_AVC: + *port = 1; + break; + default: + *port = 0; + break; + } +} + +OMX_ERRORTYPE mmalomx_role_set(MMALOMX_COMPONENT_T *component, const char *name) +{ + const MMALOMX_ROLE_T role = mmalomx_role_from_name(name); + MMAL_FOURCC_T encoding = MMAL_ENCODING_UNKNOWN; + MMAL_ES_TYPE_T es_type = MMAL_ES_TYPE_UNKNOWN; + unsigned int port; + MMAL_ES_FORMAT_T *format; + + if (!role || !mmalomx_registry_component_supports_role(component->registry_id, role)) + return OMX_ErrorUnsupportedSetting; + + component->role = role; + + mmalomx_format_encoding_from_role(role, &encoding, &es_type, &port); + if (encoding == MMAL_ENCODING_UNKNOWN) + return OMX_ErrorNone; + + format = component->ports[port].mmal->format; + format->type = es_type; + format->encoding = encoding; + format->bitrate = 64000; + switch (es_type) + { + case MMAL_ES_TYPE_VIDEO: + format->es->video.width = 176; + format->es->video.height = 144; + format->es->video.frame_rate.num = 15; + format->es->video.frame_rate.den = 1; + break; + default: + break; + } + + switch (role) + { + case MMALOMX_ROLE_VIDEO_DECODER_H263: + case MMALOMX_ROLE_VIDEO_ENCODER_H263: + component->ports[port].format_param.h263.eProfile = OMX_VIDEO_H263ProfileBaseline; + component->ports[port].format_param.h263.eLevel = OMX_VIDEO_H263Level10; + component->ports[port].format_param.h263.bPLUSPTYPEAllowed = OMX_FALSE; + component->ports[port].format_param.h263.bForceRoundingTypeToZero = OMX_TRUE; + break; + case MMALOMX_ROLE_VIDEO_DECODER_MPEG4: + case MMALOMX_ROLE_VIDEO_ENCODER_MPEG4: + component->ports[port].format_param.mpeg4.eProfile = OMX_VIDEO_MPEG4ProfileSimple; + component->ports[port].format_param.mpeg4.eLevel = OMX_VIDEO_MPEG4Level1; + break; + case MMALOMX_ROLE_VIDEO_DECODER_AVC: + case MMALOMX_ROLE_VIDEO_ENCODER_AVC: + component->ports[port].format_param.avc.eProfile = OMX_VIDEO_AVCProfileBaseline; + component->ports[port].format_param.avc.eLevel = OMX_VIDEO_AVCLevel1; + break; + case MMALOMX_ROLE_VIDEO_DECODER_WMV: + component->ports[port].format_param.wmv.eFormat = OMX_VIDEO_WMVFormat9; + break; + default: + break; + } + + if (mmal_port_format_commit(component->ports[port].mmal) != MMAL_SUCCESS) + LOG_ERROR("failed to commit format to %s for role %s", + component->ports[port].mmal->name, name); + + return OMX_ErrorNone; +} diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/openmaxil/mmalomx_roles.h b/external_src/raspicam-0.1.3/dependencies/mmal/openmaxil/mmalomx_roles.h new file mode 100644 index 0000000..cd4828d --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/openmaxil/mmalomx_roles.h @@ -0,0 +1,61 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. +*/ + +/** \file + * OpenMAX IL adaptation layer for MMAL - Role specific functions + */ + +#define MMALOMX_MAX_ROLES 16 + +typedef enum MMALOMX_ROLE_T { + MMALOMX_ROLE_UNDEFINED = 0, + MMALOMX_ROLE_VIDEO_DECODER_H263, + MMALOMX_ROLE_VIDEO_DECODER_MPEG4, + MMALOMX_ROLE_VIDEO_DECODER_AVC, + MMALOMX_ROLE_VIDEO_DECODER_MPEG2, + MMALOMX_ROLE_VIDEO_DECODER_WMV, + MMALOMX_ROLE_VIDEO_DECODER_VPX, + + MMALOMX_ROLE_VIDEO_ENCODER_H263, + MMALOMX_ROLE_VIDEO_ENCODER_MPEG4, + MMALOMX_ROLE_VIDEO_ENCODER_AVC, + + MMALOMX_ROLE_AUDIO_DECODER_AAC, + MMALOMX_ROLE_AUDIO_DECODER_MPGA_L1, + MMALOMX_ROLE_AUDIO_DECODER_MPGA_L2, + MMALOMX_ROLE_AUDIO_DECODER_MPGA_L3, + MMALOMX_ROLE_AUDIO_DECODER_DDP, + + MMALOMX_ROLE_AIV_PLAY_101, + MMALOMX_ROLE_AIV_PLAY_AVCDDP, + + MMALOMX_ROLE_MAX +} MMALOMX_ROLE_T; + +const char *mmalomx_role_to_name(MMALOMX_ROLE_T role); +MMALOMX_ROLE_T mmalomx_role_from_name(const char *name); +OMX_ERRORTYPE mmalomx_role_set(struct MMALOMX_COMPONENT_T *component, const char *name); diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/openmaxil/mmalomx_util_params.c b/external_src/raspicam-0.1.3/dependencies/mmal/openmaxil/mmalomx_util_params.c new file mode 100644 index 0000000..cb416cf --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/openmaxil/mmalomx_util_params.c @@ -0,0 +1,193 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 "interface/vmcs_host/khronos/IL/OMX_Broadcom.h" +#include "mmalomx.h" +#include "mmalomx_util_params.h" +#include "mmalomx_util_params_common.h" + +static const MMALOMX_PARAM_TRANSLATION_T *mmalomx_param_list[] = { + mmalomx_param_xlator_audio, mmalomx_param_xlator_video, + mmalomx_param_xlator_camera, mmalomx_param_xlator_misc}; + +const MMALOMX_PARAM_TRANSLATION_T *mmalomx_find_parameter_enum(unsigned int index) +{ + unsigned int i, j; + + for (i = 0; i < MMAL_COUNTOF(mmalomx_param_list); i++) + { + for (j = 0; mmalomx_param_list[i][j].mmal_id != MMAL_PARAMETER_UNUSED; j++) + { + if (!index--) + break; + } + if (mmalomx_param_list[i][j].mmal_id != MMAL_PARAMETER_UNUSED) + break; + } + + return i < MMAL_COUNTOF(mmalomx_param_list) ? &mmalomx_param_list[i][j] : NULL; +} + +const MMALOMX_PARAM_TRANSLATION_T *mmalomx_find_parameter_from_omx_id(uint32_t id) +{ + unsigned int i, j; + + for (i = 0; i < MMAL_COUNTOF(mmalomx_param_list); i++) + { + for (j = 0; mmalomx_param_list[i][j].mmal_id != MMAL_PARAMETER_UNUSED; j++) + { + if (mmalomx_param_list[i][j].omx_id == id) + break; + } + if (mmalomx_param_list[i][j].mmal_id != MMAL_PARAMETER_UNUSED) + break; + } + + return i < MMAL_COUNTOF(mmalomx_param_list) ? &mmalomx_param_list[i][j] : NULL; +} + +const MMALOMX_PARAM_TRANSLATION_T *mmalomx_find_parameter_from_mmal_id(uint32_t id) +{ + unsigned int i, j; + + for (i = 0; i < MMAL_COUNTOF(mmalomx_param_list); i++) + { + for (j = 0; mmalomx_param_list[i][j].mmal_id != MMAL_PARAMETER_UNUSED; j++) + { + if (mmalomx_param_list[i][j].mmal_id == id) + break; + } + if (mmalomx_param_list[i][j].mmal_id != MMAL_PARAMETER_UNUSED) + break; + } + + return i < MMAL_COUNTOF(mmalomx_param_list) ? &mmalomx_param_list[i][j] : NULL; +} + +const char *mmalomx_parameter_name_omx(uint32_t id) +{ + const MMALOMX_PARAM_TRANSLATION_T *xlat = mmalomx_find_parameter_from_omx_id(id); + return xlat ? xlat->omx_name : 0; +} + +const char *mmalomx_parameter_name_mmal(uint32_t id) +{ + const MMALOMX_PARAM_TRANSLATION_T *xlat = mmalomx_find_parameter_from_mmal_id(id); + return xlat ? xlat->mmal_name : 0; +} + +MMAL_STATUS_T mmalomx_param_mapping_generic(MMALOMX_PARAM_MAPPING_DIRECTION dir, + const MMALOMX_PARAM_TRANSLATION_T *xlat, + MMAL_PARAMETER_HEADER_T *mmal_param, OMX_PTR omx_param, MMAL_PORT_T *mmal_port) +{ + MMALOMX_PARAM_OMX_HEADER_T *omx_header = (MMALOMX_PARAM_OMX_HEADER_T *)omx_param; + uint8_t *mmal_data = ((uint8_t *)mmal_param) + sizeof(MMAL_PARAMETER_HEADER_T); + uint8_t *omx_data = ((uint8_t *)omx_param) + sizeof(MMALOMX_PARAM_OMX_HEADER_T); + unsigned int size = mmal_param->size - sizeof(MMAL_PARAMETER_HEADER_T); + MMAL_PARAM_UNUSED(mmal_port); + + if (xlat->portless) + omx_data -= sizeof(OMX_U32); + + if (((uint8_t *)omx_param) + omx_header->nSize != + omx_data + size) + { + VCOS_ALERT("mmalomx_param_mapping_generic: mismatch between mmal and omx paramters for (%u)", + (unsigned int)mmal_param->id); + return MMAL_EINVAL; + } + + if (dir == MMALOMX_PARAM_MAPPING_TO_MMAL) + memcpy(mmal_data, omx_data, size); + else + memcpy(omx_data, mmal_data, size); + + return MMAL_SUCCESS; +} + +MMAL_STATUS_T mmalomx_param_enum_generic(MMALOMX_PARAM_MAPPING_DIRECTION dir, + const MMALOMX_PARAM_TRANSLATION_T *xlat, + MMAL_PARAMETER_HEADER_T *mmal_param, OMX_PTR omx_param, MMAL_PORT_T *mmal_port) +{ + uint32_t *mmal = (uint32_t *)(((uint8_t *)mmal_param) + sizeof(MMAL_PARAMETER_HEADER_T)); + uint32_t *omx = (uint32_t *)(((uint8_t *)omx_param) + sizeof(MMALOMX_PARAM_OMX_HEADER_T)); + unsigned int i = 0; + MMAL_PARAM_UNUSED(mmal_port); + + if (xlat->portless) + omx -= 1; + + /* Find translation entry in lookup table */ + if (dir == MMALOMX_PARAM_MAPPING_TO_MMAL) + for (i = 0; i < xlat->xlat_enum_num && xlat->xlat_enum->omx != *omx; i++); + else + for (i = 0; i < xlat->xlat_enum_num && xlat->xlat_enum->mmal != *mmal; i++); + + if (i == xlat->xlat_enum_num) + { + if (dir == MMALOMX_PARAM_MAPPING_TO_MMAL) + VCOS_ALERT("mmalomx_param_enum_generic: omx enum value %u not supported", (unsigned int)*omx); + else + VCOS_ALERT("mmalomx_param_enum_generic: mmal enum value %u not supported", (unsigned int)*mmal); + return MMAL_EINVAL; + } + + if (dir == MMALOMX_PARAM_MAPPING_TO_MMAL) + *mmal = xlat->xlat_enum[i].mmal; + else + *omx = xlat->xlat_enum[i].omx; + + return MMAL_SUCCESS; +} + +MMAL_STATUS_T mmalomx_param_rational_generic(MMALOMX_PARAM_MAPPING_DIRECTION dir, + const MMALOMX_PARAM_TRANSLATION_T *xlat, + MMAL_PARAMETER_HEADER_T *mmal_param, OMX_PTR omx_param, MMAL_PORT_T *mmal_port) +{ + MMAL_RATIONAL_T *mmal = (MMAL_RATIONAL_T *)(((uint8_t *)mmal_param) + sizeof(MMAL_PARAMETER_HEADER_T)); + int32_t *omx = (int32_t *)(((uint8_t *)omx_param) + sizeof(MMALOMX_PARAM_OMX_HEADER_T)); + MMAL_PARAM_UNUSED(mmal_port); + + if (xlat->portless) + omx -= 1; + + if (dir == MMALOMX_PARAM_MAPPING_TO_MMAL) + { + mmal->num = *omx; + mmal->den = xlat->xlat_enum_num; + mmal_rational_simplify(mmal); + } + else + { + mmal_rational_simplify(mmal); + *omx = 0; + if (mmal->den) + *omx = mmal->num * xlat->xlat_enum_num / mmal->den; + } + + return MMAL_SUCCESS; +} diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/openmaxil/mmalomx_util_params.h b/external_src/raspicam-0.1.3/dependencies/mmal/openmaxil/mmalomx_util_params.h new file mode 100644 index 0000000..2520dfb --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/openmaxil/mmalomx_util_params.h @@ -0,0 +1,114 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. +*/ + +/** \file + * OpenMAX IL adaptation layer for MMAL - Parameters related functions + */ + +#ifndef MMALOMX_UTIL_PARAMS_H +#define MMALOMX_UTIL_PARAMS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** The structure that all OMX parameters containing a port start with */ +typedef struct MMALOMX_PARAM_OMX_HEADER_T +{ + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; +} MMALOMX_PARAM_OMX_HEADER_T; + +/** The structure that all OMX parameters without a port start with */ +typedef struct MMALOMX_PARAM_OMX_HEADER_PORTLESS_T +{ + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; +} MMALOMX_PARAM_OMX_HEADER_PORTLESS_T; + +typedef enum { + MMALOMX_PARAM_MAPPING_TO_MMAL, + MMALOMX_PARAM_MAPPING_TO_OMX +} MMALOMX_PARAM_MAPPING_DIRECTION; + +typedef struct MMALOMX_PARAM_ENUM_TRANSLATE_T { + uint32_t mmal; + uint32_t omx; +} MMALOMX_PARAM_ENUM_TRANSLATE_T; + +typedef enum MMALOMX_PARAM_TRANSLATION_TYPE_T { + MMALOMX_PARAM_TRANSLATION_TYPE_NONE = 0, + MMALOMX_PARAM_TRANSLATION_TYPE_SIMPLE, + MMALOMX_PARAM_TRANSLATION_TYPE_CUSTOM, + MMALOMX_PARAM_TRANSLATION_TYPE_DIRECT, +} MMALOMX_PARAM_TRANSLATION_TYPE_T; + +/** MMAL <-> OMX parameter translation information */ +typedef struct MMALOMX_PARAM_TRANSLATION_T +{ + uint32_t mmal_id; /**< MMAL parameter id */ + uint32_t omx_id; /**< OpenMAX IL parameter index */ + unsigned int mmal_size:16; + unsigned int omx_size:16; + unsigned int portless:1; + unsigned int double_translation:1; + MMALOMX_PARAM_TRANSLATION_TYPE_T type:4; + + struct { + MMAL_STATUS_T (*simple)(MMALOMX_PARAM_MAPPING_DIRECTION dir, + MMAL_PARAMETER_HEADER_T *mmal_param, OMX_PTR omx_param); + MMAL_STATUS_T (*generic)(MMALOMX_PARAM_MAPPING_DIRECTION dir, + const struct MMALOMX_PARAM_TRANSLATION_T *xlat, + MMAL_PARAMETER_HEADER_T *mmal_param, OMX_PTR omx_param, MMAL_PORT_T *mmal_port); + MMAL_STATUS_T (*list)(MMALOMX_PARAM_MAPPING_DIRECTION dir, + const struct MMALOMX_PARAM_TRANSLATION_T *xlat, unsigned int index, + MMAL_PARAMETER_HEADER_T *mmal_param, OMX_PTR omx_param, MMAL_PORT_T *mmal_port); + MMAL_STATUS_T (*custom)(MMALOMX_PARAM_MAPPING_DIRECTION dir, + const struct MMALOMX_PARAM_TRANSLATION_T *xlat, + MMAL_PARAMETER_HEADER_T *mmal_param, OMX_PTR omx_param, MMAL_PORT_T *mmal_port); + } fn; + + const struct MMALOMX_PARAM_ENUM_TRANSLATE_T *xlat_enum; + unsigned int xlat_enum_num; + + const char *mmal_name; /**< MMAL parameter name */ + const char *omx_name; /**< OMX parameter name */ + +} MMALOMX_PARAM_TRANSLATION_T; + +const char *mmalomx_parameter_name_omx(uint32_t id); +const char *mmalomx_parameter_name_mmal(uint32_t id); +const MMALOMX_PARAM_TRANSLATION_T *mmalomx_find_parameter_from_omx_id(uint32_t id); +const MMALOMX_PARAM_TRANSLATION_T *mmalomx_find_parameter_from_mmal_id(uint32_t id); +const MMALOMX_PARAM_TRANSLATION_T *mmalomx_find_parameter_enum(unsigned int index); + +#ifdef __cplusplus +} +#endif + +#endif /* MMALOMX_UTIL_PARAMS_H */ diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/openmaxil/mmalomx_util_params_audio.c b/external_src/raspicam-0.1.3/dependencies/mmal/openmaxil/mmalomx_util_params_audio.c new file mode 100644 index 0000000..2fb81bb --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/openmaxil/mmalomx_util_params_audio.c @@ -0,0 +1,34 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 "mmalomx.h" +#include "mmalomx_util_params_common.h" +#include "mmalomx_logging.h" + +const MMALOMX_PARAM_TRANSLATION_T mmalomx_param_xlator_audio[] = { + MMALOMX_PARAM_TERMINATE() +}; diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/openmaxil/mmalomx_util_params_camera.c b/external_src/raspicam-0.1.3/dependencies/mmal/openmaxil/mmalomx_util_params_camera.c new file mode 100644 index 0000000..936eadc --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/openmaxil/mmalomx_util_params_camera.c @@ -0,0 +1,556 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 "mmalomx.h" +#include "mmalomx_util_params_common.h" +#include "mmalomx_logging.h" + +static const MMALOMX_PARAM_ENUM_TRANSLATE_T mmalomx_param_enum_awb_mode[] = { + {MMAL_PARAM_AWBMODE_OFF, OMX_WhiteBalControlOff}, + {MMAL_PARAM_AWBMODE_AUTO, OMX_WhiteBalControlAuto}, + {MMAL_PARAM_AWBMODE_SUNLIGHT, OMX_WhiteBalControlSunLight}, + {MMAL_PARAM_AWBMODE_CLOUDY, OMX_WhiteBalControlCloudy}, + {MMAL_PARAM_AWBMODE_SHADE, OMX_WhiteBalControlShade}, + {MMAL_PARAM_AWBMODE_TUNGSTEN, OMX_WhiteBalControlTungsten}, + {MMAL_PARAM_AWBMODE_FLUORESCENT, OMX_WhiteBalControlFluorescent}, + {MMAL_PARAM_AWBMODE_INCANDESCENT,OMX_WhiteBalControlIncandescent}, + {MMAL_PARAM_AWBMODE_FLASH, OMX_WhiteBalControlFlash}, + {MMAL_PARAM_AWBMODE_HORIZON, OMX_WhiteBalControlHorizon}, +}; + +static const MMALOMX_PARAM_ENUM_TRANSLATE_T mmalomx_param_enum_image_effect[] = { + {MMAL_PARAM_IMAGEFX_NONE, OMX_ImageFilterNone}, + {MMAL_PARAM_IMAGEFX_NEGATIVE, OMX_ImageFilterNegative}, + {MMAL_PARAM_IMAGEFX_SOLARIZE, OMX_ImageFilterSolarize}, + {MMAL_PARAM_IMAGEFX_SKETCH, OMX_ImageFilterSketch}, + {MMAL_PARAM_IMAGEFX_DENOISE, OMX_ImageFilterNoise}, + {MMAL_PARAM_IMAGEFX_EMBOSS, OMX_ImageFilterEmboss}, + {MMAL_PARAM_IMAGEFX_OILPAINT, OMX_ImageFilterOilPaint}, + {MMAL_PARAM_IMAGEFX_HATCH, OMX_ImageFilterHatch}, + {MMAL_PARAM_IMAGEFX_GPEN, OMX_ImageFilterGpen}, + {MMAL_PARAM_IMAGEFX_PASTEL, OMX_ImageFilterPastel}, + {MMAL_PARAM_IMAGEFX_WATERCOLOUR, OMX_ImageFilterWatercolor}, + {MMAL_PARAM_IMAGEFX_FILM, OMX_ImageFilterFilm}, + {MMAL_PARAM_IMAGEFX_BLUR, OMX_ImageFilterBlur}, + {MMAL_PARAM_IMAGEFX_SATURATION, OMX_ImageFilterSaturation}, + {MMAL_PARAM_IMAGEFX_COLOURSWAP, OMX_ImageFilterColourSwap}, + {MMAL_PARAM_IMAGEFX_WASHEDOUT, OMX_ImageFilterWashedOut}, + {MMAL_PARAM_IMAGEFX_POSTERISE, OMX_ImageFilterPosterise}, + {MMAL_PARAM_IMAGEFX_COLOURPOINT, OMX_ImageFilterColourPoint}, + {MMAL_PARAM_IMAGEFX_COLOURBALANCE, OMX_ImageFilterColourBalance}, + {MMAL_PARAM_IMAGEFX_CARTOON, OMX_ImageFilterCartoon}, +}; + +static MMAL_STATUS_T mmalomx_param_mapping_colour_effect(MMALOMX_PARAM_MAPPING_DIRECTION dir, + MMAL_PARAMETER_HEADER_T *mmal_param, OMX_PTR omx_param) +{ + OMX_CONFIG_COLORENHANCEMENTTYPE *omx = (OMX_CONFIG_COLORENHANCEMENTTYPE *)omx_param; + MMAL_PARAMETER_COLOURFX_T *mmal = (MMAL_PARAMETER_COLOURFX_T *)mmal_param; + + if (dir == MMALOMX_PARAM_MAPPING_TO_MMAL) + { + mmal->enable = omx->bColorEnhancement; + mmal->u = omx->nCustomizedU; + mmal->v = omx->nCustomizedV; + } + else + { + omx->bColorEnhancement = mmal->enable; + omx->nCustomizedU = mmal->u; + omx->nCustomizedV = mmal->v; + } + + return MMAL_SUCCESS; +} + +static const MMALOMX_PARAM_ENUM_TRANSLATE_T mmalomx_param_enum_flicker_avoid[] = { + {MMAL_PARAM_FLICKERAVOID_OFF, OMX_COMMONFLICKERCANCEL_OFF}, + {MMAL_PARAM_FLICKERAVOID_AUTO, OMX_COMMONFLICKERCANCEL_AUTO}, + {MMAL_PARAM_FLICKERAVOID_50HZ, OMX_COMMONFLICKERCANCEL_50}, + {MMAL_PARAM_FLICKERAVOID_60HZ, OMX_COMMONFLICKERCANCEL_60}, +}; + +static const MMALOMX_PARAM_ENUM_TRANSLATE_T mmalomx_param_enum_flash[] = { + {MMAL_PARAM_FLASH_OFF, OMX_IMAGE_FlashControlOff}, + {MMAL_PARAM_FLASH_AUTO, OMX_IMAGE_FlashControlAuto}, + {MMAL_PARAM_FLASH_ON, OMX_IMAGE_FlashControlOn}, + {MMAL_PARAM_FLASH_REDEYE, OMX_IMAGE_FlashControlRedEyeReduction}, + {MMAL_PARAM_FLASH_FILLIN, OMX_IMAGE_FlashControlFillin}, + {MMAL_PARAM_FLASH_TORCH, OMX_IMAGE_FlashControlTorch}, +}; + +static const MMALOMX_PARAM_ENUM_TRANSLATE_T mmalomx_param_enum_redeye[] = { + {MMAL_PARAM_REDEYE_OFF, OMX_RedEyeRemovalNone}, + {MMAL_PARAM_REDEYE_ON, OMX_RedEyeRemovalOn}, + {MMAL_PARAM_REDEYE_ON, OMX_RedEyeRemovalAuto}, + {MMAL_PARAM_REDEYE_SIMPLE, OMX_RedEyeRemovalSimple} +}; + +static MMAL_STATUS_T mmalomx_param_mapping_focus(MMALOMX_PARAM_MAPPING_DIRECTION dir, + MMAL_PARAMETER_HEADER_T *mmal_param, OMX_PTR omx_param) +{ + static const struct MMALOMX_PARAM_ENUM_TRANSLATE_T mmalomx_param_enum_focus[] = { + {MMAL_PARAM_FOCUS_AUTO, OMX_IMAGE_FocusControlAutoLock}, + {MMAL_PARAM_FOCUS_CAF, OMX_IMAGE_FocusControlAuto}, + {MMAL_PARAM_FOCUS_FIXED_INFINITY, OMX_IMAGE_FocusControlInfinityFixed}, + {MMAL_PARAM_FOCUS_FIXED_HYPERFOCAL, OMX_IMAGE_FocusControlHyperfocal}, + {MMAL_PARAM_FOCUS_FIXED_NEAR, OMX_IMAGE_FocusControlNearFixed}, + {MMAL_PARAM_FOCUS_FIXED_MACRO, OMX_IMAGE_FocusControlMacroFixed}, + {MMAL_PARAM_FOCUS_AUTO_MACRO, OMX_IMAGE_FocusControlAutoLockMacro}, + {MMAL_PARAM_FOCUS_AUTO_NEAR, OMX_IMAGE_FocusControlAutoLock}, + {MMAL_PARAM_FOCUS_CAF_NEAR, OMX_IMAGE_FocusControlAutoNear}, + {MMAL_PARAM_FOCUS_CAF_MACRO, OMX_IMAGE_FocusControlAutoMacro}, + {MMAL_PARAM_FOCUS_CAF_FAST, OMX_IMAGE_FocusControlAutoFast}, + {MMAL_PARAM_FOCUS_CAF_MACRO_FAST, OMX_IMAGE_FocusControlAutoMacroFast}, + {MMAL_PARAM_FOCUS_CAF_NEAR_FAST, OMX_IMAGE_FocusControlAutoNearFast}, + /* {MMAL_PARAM_FOCUS_EDOF, ???}, */ + }; + OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE *omx = (OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE *)omx_param; + MMAL_PARAMETER_FOCUS_T *mmal = (MMAL_PARAMETER_FOCUS_T *)mmal_param; + MMALOMX_PARAM_ENUM_FIND(struct MMALOMX_PARAM_ENUM_TRANSLATE_T, xlat_enum, mmalomx_param_enum_focus, + dir, mmal->value, omx->eFocusControl); + + if (!xlat_enum) + return MMAL_EINVAL; + + if (dir == MMALOMX_PARAM_MAPPING_TO_MMAL) + { + mmal->value = xlat_enum->mmal; + } + else + { + omx->eFocusControl = xlat_enum->omx; + omx->nFocusStepIndex = -1; + } + + return MMAL_SUCCESS; +} + +static const MMALOMX_PARAM_ENUM_TRANSLATE_T mmalomx_param_enum_mirror[] = { + {MMAL_PARAM_MIRROR_NONE, OMX_MirrorNone}, + {MMAL_PARAM_MIRROR_VERTICAL, OMX_MirrorVertical}, + {MMAL_PARAM_MIRROR_HORIZONTAL, OMX_MirrorHorizontal}, + {MMAL_PARAM_MIRROR_BOTH, OMX_MirrorBoth} +}; + +static const MMALOMX_PARAM_ENUM_TRANSLATE_T mmalomx_param_enum_exposure_mode[] = { + {MMAL_PARAM_EXPOSUREMODE_OFF, OMX_ExposureControlOff}, + {MMAL_PARAM_EXPOSUREMODE_AUTO, OMX_ExposureControlAuto}, + {MMAL_PARAM_EXPOSUREMODE_NIGHT, OMX_ExposureControlNight}, + {MMAL_PARAM_EXPOSUREMODE_NIGHTPREVIEW, OMX_ExposureControlNightWithPreview}, + {MMAL_PARAM_EXPOSUREMODE_BACKLIGHT, OMX_ExposureControlBackLight}, + {MMAL_PARAM_EXPOSUREMODE_SPOTLIGHT, OMX_ExposureControlSpotLight}, + {MMAL_PARAM_EXPOSUREMODE_SPORTS, OMX_ExposureControlSports}, + {MMAL_PARAM_EXPOSUREMODE_SNOW, OMX_ExposureControlSnow}, + {MMAL_PARAM_EXPOSUREMODE_BEACH, OMX_ExposureControlBeach}, + {MMAL_PARAM_EXPOSUREMODE_VERYLONG, OMX_ExposureControlVeryLong}, + {MMAL_PARAM_EXPOSUREMODE_FIXEDFPS, OMX_ExposureControlFixedFps}, + {MMAL_PARAM_EXPOSUREMODE_ANTISHAKE, OMX_ExposureControlAntishake}, + {MMAL_PARAM_EXPOSUREMODE_FIREWORKS, OMX_ExposureControlFireworks}, +}; + +static const MMALOMX_PARAM_ENUM_TRANSLATE_T mmalomx_param_enum_capture_status[] = { + {MMAL_PARAM_CAPTURE_STATUS_NOT_CAPTURING, OMX_NotCapturing}, + {MMAL_PARAM_CAPTURE_STATUS_CAPTURE_STARTED, OMX_CaptureStarted}, + {MMAL_PARAM_CAPTURE_STATUS_CAPTURE_ENDED, OMX_CaptureComplete}, +}; + +static MMAL_STATUS_T mmalomx_param_mapping_face_track(MMALOMX_PARAM_MAPPING_DIRECTION dir, + MMAL_PARAMETER_HEADER_T *mmal_param, OMX_PTR omx_param) +{ + static const MMALOMX_PARAM_ENUM_TRANSLATE_T mmalomx_param_enum_face_track[] = { + {MMAL_PARAM_FACE_DETECT_NONE, OMX_FaceDetectionControlNone}, + {MMAL_PARAM_FACE_DETECT_ON, OMX_FaceDetectionControlOn}, + }; + OMX_CONFIG_FACEDETECTIONCONTROLTYPE *omx = (OMX_CONFIG_FACEDETECTIONCONTROLTYPE *)omx_param; + MMAL_PARAMETER_FACE_TRACK_T *mmal = (MMAL_PARAMETER_FACE_TRACK_T *)mmal_param; + MMALOMX_PARAM_ENUM_FIND(MMALOMX_PARAM_ENUM_TRANSLATE_T, xenum, mmalomx_param_enum_face_track, + dir, mmal->mode, omx->eMode); + + if (!xenum) + return MMAL_EINVAL; + + if (dir == MMALOMX_PARAM_MAPPING_TO_MMAL) + { + mmal->mode = xenum->mmal; + mmal->maxRegions = omx->nMaxRegions; + mmal->frames = omx->nFrames; + mmal->quality = omx->nQuality; + } + else + { + omx->eMode = xenum->omx; + omx->nMaxRegions = mmal->maxRegions; + omx->nFrames = mmal->frames; + omx->nQuality = mmal->quality; + } + + return MMAL_SUCCESS; +} + +static MMAL_STATUS_T mmalomx_param_mapping_thumb_cfg(MMALOMX_PARAM_MAPPING_DIRECTION dir, + MMAL_PARAMETER_HEADER_T *mmal_param, OMX_PTR omx_param) +{ + OMX_PARAM_BRCMTHUMBNAILTYPE *omx = (OMX_PARAM_BRCMTHUMBNAILTYPE *)omx_param; + MMAL_PARAMETER_THUMBNAIL_CONFIG_T *mmal = (MMAL_PARAMETER_THUMBNAIL_CONFIG_T *)mmal_param; + + if (dir == MMALOMX_PARAM_MAPPING_TO_MMAL) + { + mmal->enable = !!omx->bEnable; + mmal->width = omx->nWidth; + mmal->height = omx->nHeight; + mmal->quality = 0; + } + else + { + omx->bEnable = mmal->enable ? OMX_TRUE : OMX_FALSE; + omx->bUsePreview = OMX_FALSE; + omx->nWidth = mmal->width; + omx->nHeight = mmal->height; + /* We don't have an API for setting the thumbnail quality */ + } + + return MMAL_SUCCESS; +} + +static const MMALOMX_PARAM_ENUM_TRANSLATE_T mmalomx_param_enum_stc[] = { + {MMAL_PARAM_STC_MODE_OFF, OMX_TimestampModeZero}, + {MMAL_PARAM_STC_MODE_RAW, OMX_TimestampModeRawStc}, + {MMAL_PARAM_STC_MODE_COOKED, OMX_TimestampModeResetStc}, +}; + +static const MMALOMX_PARAM_ENUM_TRANSLATE_T mmalomx_param_enum_capture_mode[] = { + {MMAL_PARAM_CAPTUREMODE_WAIT_FOR_END, OMX_CameraCaptureModeWaitForCaptureEnd}, + {MMAL_PARAM_CAPTUREMODE_RESUME_VF_IMMEDIATELY, OMX_CameraCaptureModeResumeViewfinderImmediately}, + /*{MMAL_PARAM_CAPTUREMODE_WAIT_FOR_END_AND_HOLD, OMX_CameraCaptureModeWaitForCaptureEndAndUsePreviousInputImage}, Don't enable for now as not working */ +}; + +static MMAL_STATUS_T mmalomx_param_mapping_sensor_info(MMALOMX_PARAM_MAPPING_DIRECTION dir, + MMAL_PARAMETER_HEADER_T *mmal_param, OMX_PTR omx_param) +{ + OMX_CONFIG_CAMERAINFOTYPE *omx = (OMX_CONFIG_CAMERAINFOTYPE *)omx_param; + MMAL_PARAMETER_SENSOR_INFORMATION_T *mmal = (MMAL_PARAMETER_SENSOR_INFORMATION_T *)mmal_param; + + if (dir == MMALOMX_PARAM_MAPPING_TO_MMAL) + { + mmal->f_number = mmal_rational_from_fixed_16_16(omx->xFNumber); + mmal->focal_length = mmal_rational_from_fixed_16_16(omx->xFocalLength); + mmal->model_id = omx->nModelId; + mmal->manufacturer_id = omx->nManufacturerId; + mmal->revision = omx->nRevNum; + } + else + { + omx->xFNumber = mmal_rational_to_fixed_16_16(mmal->f_number); + omx->xFocalLength = mmal_rational_to_fixed_16_16(mmal->focal_length); + omx->nModelId = mmal->model_id; + omx->nManufacturerId = mmal->manufacturer_id; + omx->nRevNum = mmal->revision; + } + + return MMAL_SUCCESS; +} + +static const MMALOMX_PARAM_ENUM_TRANSLATE_T mmalomx_param_enum_flash_select[] = { + {MMAL_PARAMETER_CAMERA_INFO_FLASH_TYPE_XENON, OMX_CameraFlashXenon}, + {MMAL_PARAMETER_CAMERA_INFO_FLASH_TYPE_LED, OMX_CameraFlashLED}, + {MMAL_PARAMETER_CAMERA_INFO_FLASH_TYPE_OTHER, OMX_CameraFlashNone}, +}; + +static MMAL_STATUS_T mmalomx_param_mapping_fov(MMALOMX_PARAM_MAPPING_DIRECTION dir, + MMAL_PARAMETER_HEADER_T *mmal_param, OMX_PTR omx_param) +{ + OMX_CONFIG_BRCMFOVTYPE *omx = (OMX_CONFIG_BRCMFOVTYPE *)omx_param; + MMAL_PARAMETER_FIELD_OF_VIEW_T *mmal = (MMAL_PARAMETER_FIELD_OF_VIEW_T *)mmal_param; + + if (dir == MMALOMX_PARAM_MAPPING_TO_MMAL) + { + mmal->fov_h = mmal_rational_from_fixed_16_16(omx->xFieldOfViewHorizontal); + mmal->fov_v = mmal_rational_from_fixed_16_16(omx->xFieldOfViewVertical); + } + else + { + omx->xFieldOfViewHorizontal = mmal_rational_to_fixed_16_16(mmal->fov_h); + omx->xFieldOfViewVertical = mmal_rational_to_fixed_16_16(mmal->fov_v); + } + + return MMAL_SUCCESS; +} + +static const MMALOMX_PARAM_ENUM_TRANSLATE_T mmalomx_param_enum_drc[] = { + {MMAL_PARAMETER_DRC_STRENGTH_OFF, OMX_DynRangeExpOff}, + {MMAL_PARAMETER_DRC_STRENGTH_LOW, OMX_DynRangeExpLow}, + {MMAL_PARAMETER_DRC_STRENGTH_MEDIUM, OMX_DynRangeExpMedium}, + {MMAL_PARAMETER_DRC_STRENGTH_HIGH, OMX_DynRangeExpHigh}, +}; + +static MMAL_STATUS_T mmalomx_param_mapping_algo_ctrl(MMALOMX_PARAM_MAPPING_DIRECTION dir, + MMAL_PARAMETER_HEADER_T *mmal_param, OMX_PTR omx_param) +{ + static const MMALOMX_PARAM_ENUM_TRANSLATE_T mmalomx_param_enum_algo_ctrl[] = { + { MMAL_PARAMETER_ALGORITHM_CONTROL_ALGORITHMS_FACETRACKING, OMX_CameraDisableAlgorithmFacetracking}, + { MMAL_PARAMETER_ALGORITHM_CONTROL_ALGORITHMS_REDEYE_REDUCTION, OMX_CameraDisableAlgorithmRedEyeReduction}, + { MMAL_PARAMETER_ALGORITHM_CONTROL_ALGORITHMS_VIDEO_STABILISATION, OMX_CameraDisableAlgorithmVideoStabilisation}, + { MMAL_PARAMETER_ALGORITHM_CONTROL_ALGORITHMS_WRITE_RAW, OMX_CameraDisableAlgorithmWriteRaw}, + { MMAL_PARAMETER_ALGORITHM_CONTROL_ALGORITHMS_VIDEO_DENOISE, OMX_CameraDisableAlgorithmVideoDenoise}, + { MMAL_PARAMETER_ALGORITHM_CONTROL_ALGORITHMS_STILLS_DENOISE, OMX_CameraDisableAlgorithmStillsDenoise}, + { MMAL_PARAMETER_ALGORITHM_CONTROL_ALGORITHMS_TEMPORAL_DENOISE, OMX_CameraDisableAlgorithmMax}, + { MMAL_PARAMETER_ALGORITHM_CONTROL_ALGORITHMS_ANTISHAKE, OMX_CameraDisableAlgorithmAntiShake}, + { MMAL_PARAMETER_ALGORITHM_CONTROL_ALGORITHMS_IMAGE_EFFECTS, OMX_CameraDisableAlgorithmImageEffects}, + { MMAL_PARAMETER_ALGORITHM_CONTROL_ALGORITHMS_DYNAMIC_RANGE_COMPRESSION,OMX_CameraDisableAlgorithmDynamicRangeExpansion}, + { MMAL_PARAMETER_ALGORITHM_CONTROL_ALGORITHMS_FACE_RECOGNITION, OMX_CameraDisableAlgorithmFaceRecognition}, + { MMAL_PARAMETER_ALGORITHM_CONTROL_ALGORITHMS_FACE_BEAUTIFICATION, OMX_CameraDisableAlgorithmFaceBeautification}, + { MMAL_PARAMETER_ALGORITHM_CONTROL_ALGORITHMS_SCENE_DETECTION, OMX_CameraDisableAlgorithmSceneDetection}, + { MMAL_PARAMETER_ALGORITHM_CONTROL_ALGORITHMS_HIGH_DYNAMIC_RANGE, OMX_CameraDisableAlgorithmHighDynamicRange}, + }; + OMX_PARAM_CAMERADISABLEALGORITHMTYPE *omx = (OMX_PARAM_CAMERADISABLEALGORITHMTYPE *)omx_param; + MMAL_PARAMETER_ALGORITHM_CONTROL_T *mmal = (MMAL_PARAMETER_ALGORITHM_CONTROL_T *)mmal_param; + MMALOMX_PARAM_ENUM_FIND(MMALOMX_PARAM_ENUM_TRANSLATE_T, xenum, mmalomx_param_enum_algo_ctrl, + dir, mmal->algorithm, omx->eAlgorithm); + + if (!xenum) + return MMAL_EINVAL; + + if (dir == MMALOMX_PARAM_MAPPING_TO_MMAL) + { + mmal->algorithm = xenum->mmal; + mmal->enabled = !omx->bDisabled; + } + else + { + omx->eAlgorithm = xenum->omx; + omx->bDisabled = !mmal->enabled; + } + + return MMAL_SUCCESS; +} + +static MMAL_STATUS_T mmalomx_param_mapping_image_effect_params(MMALOMX_PARAM_MAPPING_DIRECTION dir, + MMAL_PARAMETER_HEADER_T *mmal_param, OMX_PTR omx_param) +{ + OMX_CONFIG_IMAGEFILTERPARAMSTYPE *omx = (OMX_CONFIG_IMAGEFILTERPARAMSTYPE *)omx_param; + MMAL_PARAMETER_IMAGEFX_PARAMETERS_T *mmal = (MMAL_PARAMETER_IMAGEFX_PARAMETERS_T *)mmal_param; + MMALOMX_PARAM_ENUM_FIND(MMALOMX_PARAM_ENUM_TRANSLATE_T, xenum, mmalomx_param_enum_image_effect, + dir, mmal->effect, omx->eImageFilter); + + if (!xenum) + return MMAL_EINVAL; + + if (dir == MMALOMX_PARAM_MAPPING_TO_MMAL) + { + if (omx->nNumParams > MMAL_COUNTOF(mmal->effect_parameter)) + return MMAL_EINVAL; + mmal->effect = xenum->mmal; + mmal->num_effect_params = omx->nNumParams; + memcpy(mmal->effect_parameter, omx->nParams, sizeof(uint32_t) * omx->nNumParams); + } + else + { + if (mmal->num_effect_params > MMAL_COUNTOF(omx->nParams)) + return MMAL_EINVAL; + omx->eImageFilter = xenum->omx; + omx->nNumParams = mmal->num_effect_params; + memcpy(omx->nParams, mmal->effect_parameter, sizeof(uint32_t) * omx->nNumParams); + } + + return MMAL_SUCCESS; +} + +static const MMALOMX_PARAM_ENUM_TRANSLATE_T mmalomx_param_enum_use_case[] = { + {MMAL_PARAM_CAMERA_USE_CASE_UNKNOWN, OMX_CameraUseCaseAuto}, + {MMAL_PARAM_CAMERA_USE_CASE_STILLS_CAPTURE, OMX_CameraUseCaseStills}, + {MMAL_PARAM_CAMERA_USE_CASE_VIDEO_CAPTURE, OMX_CameraUseCaseVideo}, +}; + +static MMAL_STATUS_T mmalomx_param_mapping_fps_range(MMALOMX_PARAM_MAPPING_DIRECTION dir, + MMAL_PARAMETER_HEADER_T *mmal_param, OMX_PTR omx_param) +{ + OMX_PARAM_BRCMFRAMERATERANGETYPE *omx = (OMX_PARAM_BRCMFRAMERATERANGETYPE *)omx_param; + MMAL_PARAMETER_FPS_RANGE_T *mmal = (MMAL_PARAMETER_FPS_RANGE_T *)mmal_param; + + if (dir == MMALOMX_PARAM_MAPPING_TO_MMAL) + { + mmal->fps_low = mmal_rational_from_fixed_16_16(omx->xFramerateLow); + mmal->fps_high = mmal_rational_from_fixed_16_16(omx->xFramerateLow); + } + else + { + omx->xFramerateLow = mmal_rational_to_fixed_16_16(mmal->fps_low); + omx->xFramerateLow = mmal_rational_to_fixed_16_16(mmal->fps_high); + } + + return MMAL_SUCCESS; +} + +static MMAL_STATUS_T mmalomx_param_mapping_ev_comp(MMALOMX_PARAM_MAPPING_DIRECTION dir, + MMAL_PARAMETER_HEADER_T *mmal_param, OMX_PTR omx_param) +{ + OMX_PARAM_S32TYPE *omx = (OMX_PARAM_S32TYPE *)omx_param; + MMAL_PARAMETER_INT32_T *mmal = (MMAL_PARAMETER_INT32_T *)mmal_param; + + if (dir == MMALOMX_PARAM_MAPPING_TO_MMAL) + mmal->value = (omx->nS32 * 6) >> 16; + else + omx->nS32 = (mmal->value << 16) / 6; + + return MMAL_SUCCESS; +} + +const MMALOMX_PARAM_TRANSLATION_T mmalomx_param_xlator_camera[] = { + MMALOMX_PARAM_PASSTHROUGH(MMAL_PARAMETER_ROTATION, MMAL_PARAMETER_INT32_T, + OMX_IndexConfigCommonRotate, OMX_CONFIG_ROTATIONTYPE), + MMALOMX_PARAM_ENUM(MMAL_PARAMETER_AWB_MODE, MMAL_PARAM_AWBMODE_T, + OMX_IndexConfigCommonWhiteBalance, OMX_CONFIG_WHITEBALCONTROLTYPE, mmalomx_param_enum_awb_mode), + MMALOMX_PARAM_ENUM(MMAL_PARAMETER_IMAGE_EFFECT, MMAL_PARAMETER_IMAGEFX_T, + OMX_IndexConfigCommonImageFilter, OMX_CONFIG_IMAGEFILTERTYPE, mmalomx_param_enum_image_effect), + MMALOMX_PARAM_STRAIGHT_MAPPING(MMAL_PARAMETER_COLOUR_EFFECT, MMAL_PARAMETER_COLOURFX_T, + OMX_IndexConfigCommonColorEnhancement, OMX_CONFIG_COLORENHANCEMENTTYPE, mmalomx_param_mapping_colour_effect), + MMALOMX_PARAM_ENUM(MMAL_PARAMETER_FLICKER_AVOID, MMAL_PARAMETER_FLICKERAVOID_T, + OMX_IndexConfigCommonFlickerCancellation, OMX_CONFIG_FLICKERCANCELTYPE, mmalomx_param_enum_flicker_avoid), + MMALOMX_PARAM_ENUM(MMAL_PARAMETER_FLASH, MMAL_PARAMETER_FLASH_T, + OMX_IndexParamFlashControl, OMX_IMAGE_PARAM_FLASHCONTROLTYPE, mmalomx_param_enum_flash), + MMALOMX_PARAM_ENUM(MMAL_PARAMETER_REDEYE, MMAL_PARAMETER_REDEYE_T, + OMX_IndexConfigCommonRedEyeRemoval, OMX_CONFIG_REDEYEREMOVALTYPE, mmalomx_param_enum_redeye), + MMALOMX_PARAM_STRAIGHT_MAPPING(MMAL_PARAMETER_FOCUS, MMAL_PARAMETER_FOCUS_T, + OMX_IndexConfigFocusControl, OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE, mmalomx_param_mapping_focus), + MMALOMX_PARAM_ENUM(MMAL_PARAMETER_REDEYE, MMAL_PARAMETER_REDEYE_T, + OMX_IndexConfigCommonRedEyeRemoval, OMX_CONFIG_REDEYEREMOVALTYPE, mmalomx_param_enum_flash), + MMALOMX_PARAM_PASSTHROUGH(MMAL_PARAMETER_ZOOM, MMAL_PARAMETER_SCALEFACTOR_T, + OMX_IndexConfigCommonDigitalZoom, OMX_CONFIG_SCALEFACTORTYPE), + MMALOMX_PARAM_ENUM(MMAL_PARAMETER_MIRROR, MMAL_PARAMETER_MIRROR_T, + OMX_IndexConfigCommonMirror, OMX_CONFIG_MIRRORTYPE, mmalomx_param_enum_mirror), + MMALOMX_PARAM_PASSTHROUGH(MMAL_PARAMETER_CAMERA_NUM, MMAL_PARAMETER_UINT32_T, + OMX_IndexParamCameraDeviceNumber, OMX_PARAM_U32TYPE), + MMALOMX_PARAM_BOOLEAN(MMAL_PARAMETER_CAPTURE, + OMX_IndexConfigPortCapturing), + MMALOMX_PARAM_ENUM(MMAL_PARAMETER_EXPOSURE_MODE, MMAL_PARAMETER_EXPOSUREMODE_T, + OMX_IndexConfigCommonExposure, OMX_CONFIG_EXPOSURECONTROLTYPE, mmalomx_param_enum_exposure_mode), + MMALOMX_PARAM_ENUM_PORTLESS(MMAL_PARAMETER_CAPTURE_STATUS, MMAL_PARAMETER_CAPTURE_STATUS_T, + OMX_IndexParamCaptureStatus, OMX_PARAM_CAPTURESTATETYPE, mmalomx_param_enum_capture_status), + MMALOMX_PARAM_STRAIGHT_MAPPING(MMAL_PARAMETER_FACE_TRACK, MMAL_PARAMETER_FACE_TRACK_T, + OMX_IndexConfigCommonFaceDetectionControl, OMX_CONFIG_FACEDETECTIONCONTROLTYPE, mmalomx_param_mapping_face_track), + MMALOMX_PARAM_BOOLEAN_PORTLESS(MMAL_PARAMETER_DRAW_BOX_FACES_AND_FOCUS, + OMX_IndexConfigDrawBoxAroundFaces), + MMALOMX_PARAM_PASSTHROUGH(MMAL_PARAMETER_JPEG_Q_FACTOR, MMAL_PARAMETER_UINT32_T, + OMX_IndexParamQFactor, OMX_IMAGE_PARAM_QFACTORTYPE), + MMALOMX_PARAM_BOOLEAN_PORTLESS(MMAL_PARAMETER_EXIF_DISABLE, + OMX_IndexParamBrcmDisableEXIF), + MMALOMX_PARAM_STRAIGHT_MAPPING_PORTLESS(MMAL_PARAMETER_THUMBNAIL_CONFIGURATION, MMAL_PARAMETER_THUMBNAIL_CONFIG_T, + OMX_IndexParamBrcmThumbnail, OMX_PARAM_BRCMTHUMBNAILTYPE, mmalomx_param_mapping_thumb_cfg), + MMALOMX_PARAM_ENUM(MMAL_PARAMETER_USE_STC, MMAL_PARAMETER_CAMERA_STC_MODE_T, + OMX_IndexParamCommonUseStcTimestamps, OMX_PARAM_TIMESTAMPMODETYPE, mmalomx_param_enum_stc), + MMALOMX_PARAM_PASSTHROUGH(MMAL_PARAMETER_VIDEO_STABILISATION, MMAL_PARAMETER_BOOLEAN_T, + OMX_IndexConfigCommonFrameStabilisation, OMX_CONFIG_FRAMESTABTYPE), + MMALOMX_PARAM_BOOLEAN_PORTLESS(MMAL_PARAMETER_ENABLE_DPF_FILE, + OMX_IndexParamUseDynamicParameterFile), + MMALOMX_PARAM_BOOLEAN_PORTLESS(MMAL_PARAMETER_DPF_FAIL_IS_FATAL, + OMX_IndexParamDynamicParameterFileFailFatal), + MMALOMX_PARAM_ENUM(MMAL_PARAMETER_CAPTURE_MODE, MMAL_PARAMETER_CAPTUREMODE_T, + OMX_IndexParamCameraCaptureMode, OMX_PARAM_CAMERACAPTUREMODETYPE, mmalomx_param_enum_capture_mode), + MMALOMX_PARAM_PASSTHROUGH(MMAL_PARAMETER_INPUT_CROP, MMAL_PARAMETER_INPUT_CROP_T, + OMX_IndexConfigInputCropPercentages, OMX_CONFIG_INPUTCROPTYPE), + MMALOMX_PARAM_STRAIGHT_MAPPING_PORTLESS(MMAL_PARAMETER_SENSOR_INFORMATION, MMAL_PARAMETER_SENSOR_INFORMATION_T, + OMX_IndexConfigCameraInfo, OMX_CONFIG_CAMERAINFOTYPE, mmalomx_param_mapping_sensor_info), + MMALOMX_PARAM_ENUM(MMAL_PARAMETER_FLASH_SELECT, MMAL_PARAMETER_FLASH_SELECT_T, + OMX_IndexParamCameraFlashType, OMX_PARAM_CAMERAFLASHTYPE, mmalomx_param_enum_flash_select), + MMALOMX_PARAM_STRAIGHT_MAPPING(MMAL_PARAMETER_FIELD_OF_VIEW, MMAL_PARAMETER_FIELD_OF_VIEW_T, + OMX_IndexConfigFieldOfView, OMX_CONFIG_BRCMFOVTYPE, mmalomx_param_mapping_fov), + MMALOMX_PARAM_BOOLEAN_PORTLESS(MMAL_PARAMETER_HIGH_DYNAMIC_RANGE, + OMX_IndexConfigBrcmHighDynamicRange), + MMALOMX_PARAM_ENUM_PORTLESS(MMAL_PARAMETER_DYNAMIC_RANGE_COMPRESSION, MMAL_PARAMETER_DRC_T, + OMX_IndexConfigDynamicRangeExpansion, OMX_CONFIG_DYNAMICRANGEEXPANSIONTYPE, mmalomx_param_enum_drc), + MMALOMX_PARAM_STRAIGHT_MAPPING_PORTLESS(MMAL_PARAMETER_ALGORITHM_CONTROL, MMAL_PARAMETER_ALGORITHM_CONTROL_T, + OMX_IndexParamCameraDisableAlgorithm, OMX_PARAM_CAMERADISABLEALGORITHMTYPE, mmalomx_param_mapping_algo_ctrl), + MMALOMX_PARAM_RATIONAL(MMAL_PARAMETER_SHARPNESS, MMAL_PARAMETER_RATIONAL_T, + OMX_IndexConfigCommonSharpness, OMX_CONFIG_SHARPNESSTYPE, 100), + MMALOMX_PARAM_RATIONAL(MMAL_PARAMETER_CONTRAST, MMAL_PARAMETER_RATIONAL_T, + OMX_IndexConfigCommonContrast, OMX_CONFIG_CONTRASTTYPE, 100), + MMALOMX_PARAM_RATIONAL(MMAL_PARAMETER_BRIGHTNESS, MMAL_PARAMETER_RATIONAL_T, + OMX_IndexConfigCommonContrast, OMX_CONFIG_CONTRASTTYPE, 100), + MMALOMX_PARAM_RATIONAL(MMAL_PARAMETER_SATURATION, MMAL_PARAMETER_RATIONAL_T, + OMX_IndexConfigCommonSaturation, OMX_CONFIG_SATURATIONTYPE, 100), + MMALOMX_PARAM_BOOLEAN_PORTLESS(MMAL_PARAMETER_ANTISHAKE, + OMX_IndexConfigStillsAntiShakeEnable), + MMALOMX_PARAM_STRAIGHT_MAPPING(MMAL_PARAMETER_IMAGE_EFFECT_PARAMETERS, MMAL_PARAMETER_IMAGEFX_PARAMETERS_T, + OMX_IndexConfigCommonImageFilterParameters, OMX_CONFIG_IMAGEFILTERPARAMSTYPE, mmalomx_param_mapping_image_effect_params), + MMALOMX_PARAM_BOOLEAN_PORTLESS(MMAL_PARAMETER_CAMERA_BURST_CAPTURE, + OMX_IndexConfigBurstCapture), + MMALOMX_PARAM_PASSTHROUGH(MMAL_PARAMETER_CAMERA_MIN_ISO, MMAL_PARAMETER_UINT32_T, + OMX_IndexConfigCameraIsoReferenceValue, OMX_PARAM_U32TYPE), + MMALOMX_PARAM_ENUM_PORTLESS(MMAL_PARAMETER_CAMERA_USE_CASE, MMAL_PARAMETER_CAMERA_USE_CASE_T, + OMX_IndexConfigCameraUseCase, OMX_CONFIG_CAMERAUSECASETYPE, mmalomx_param_enum_use_case), + MMALOMX_PARAM_BOOLEAN_PORTLESS(MMAL_PARAMETER_CAPTURE_STATS_PASS, + OMX_IndexConfigCameraEnableStatsPass), + MMALOMX_PARAM_PASSTHROUGH(MMAL_PARAMETER_CAMERA_CUSTOM_SENSOR_CONFIG, MMAL_PARAMETER_UINT32_T, + OMX_IndexParamCameraCustomSensorConfig, OMX_PARAM_U32TYPE), + MMALOMX_PARAM_BOOLEAN_PORTLESS(MMAL_PARAMETER_ENABLE_REGISTER_FILE, + OMX_IndexConfigBrcmUseRegisterFile), + MMALOMX_PARAM_BOOLEAN_PORTLESS(MMAL_PARAMETER_REGISTER_FAIL_IS_FATAL, + OMX_IndexConfigBrcmRegisterFileFailFatal), + MMALOMX_PARAM_PASSTHROUGH_PORTLESS(MMAL_PARAMETER_CONFIGFILE_REGISTERS, MMAL_PARAMETER_CONFIGFILE_T, + OMX_IndexParamBrcmConfigFileRegisters, OMX_PARAM_BRCMCONFIGFILETYPE), + MMALOMX_PARAM_PASSTHROUGH_PORTLESS(MMAL_PARAMETER_CONFIGFILE_CHUNK_REGISTERS, MMAL_PARAMETER_CONFIGFILE_CHUNK_T, + OMX_IndexParamBrcmConfigFileChunkRegisters, OMX_PARAM_BRCMCONFIGFILECHUNKTYPE), + MMALOMX_PARAM_BOOLEAN_PORTLESS(MMAL_PARAMETER_JPEG_ATTACH_LOG, + OMX_IndexParamBrcmAttachLog), + MMALOMX_PARAM_PASSTHROUGH_PORTLESS(MMAL_PARAMETER_ZERO_SHUTTER_LAG, MMAL_PARAMETER_ZEROSHUTTERLAG_T, + OMX_IndexParamCameraZeroShutterLag, OMX_CONFIG_ZEROSHUTTERLAGTYPE), + MMALOMX_PARAM_STRAIGHT_MAPPING(MMAL_PARAMETER_FPS_RANGE, MMAL_PARAMETER_FPS_RANGE_T, + OMX_IndexParamBrcmFpsRange, OMX_PARAM_BRCMFRAMERATERANGETYPE, mmalomx_param_mapping_fps_range), + MMALOMX_PARAM_STRAIGHT_MAPPING(MMAL_PARAMETER_CAPTURE_EXPOSURE_COMP, MMAL_PARAMETER_INT32_T, + OMX_IndexParamCaptureExposureCompensation, OMX_PARAM_S32TYPE, mmalomx_param_mapping_ev_comp), + MMALOMX_PARAM_BOOLEAN_PORTLESS(MMAL_PARAMETER_SW_SHARPEN_DISABLE, + OMX_IndexParamSWSharpenDisable), + MMALOMX_PARAM_BOOLEAN_PORTLESS(MMAL_PARAMETER_FLASH_REQUIRED, + OMX_IndexConfigBrcmFlashRequired), + MMALOMX_PARAM_BOOLEAN_PORTLESS(MMAL_PARAMETER_SW_SATURATION_DISABLE, + OMX_IndexParamSWSaturationDisable), + MMALOMX_PARAM_TERMINATE() +}; + +#if 0 /* Conversions which are still left to implement */ +MMALOMX_PARAM_CUSTOM(MMAL_PARAMETER_CAMERA_CONFIG, MMAL_PARAMETER_CAMERA_CONFIG_T, + 0, 0, mmal_ril_param_set_cam_config), +MMALOMX_PARAM_STRAIGHT_MAPPING(MMAL_PARAMETER_EXPOSURE_COMP, MMAL_PARAMETER_INT32_T, + OMX_IndexConfigCommonExposureValue, OMX_CONFIG_EXPOSUREVALUETYPE, 0), +MMALOMX_PARAM_STRAIGHT_MAPPING(MMAL_PARAMETER_EXP_METERING_MODE, MMAL_PARAMETER_EXPOSUREMETERINGMODE_T, + OMX_IndexConfigCommonExposureValue, OMX_CONFIG_EXPOSUREVALUETYPE, 0), +MMALOMX_PARAM_STRAIGHT_MAPPING(MMAL_PARAMETER_ISO, MMAL_PARAMETER_UINT32_T, + OMX_IndexConfigCommonExposureValue, OMX_CONFIG_EXPOSUREVALUETYPE, 0), +MMALOMX_PARAM_STRAIGHT_MAPPING(MMAL_PARAMETER_FOCUS_STATUS, MMAL_PARAMETER_FOCUS_STATUS_T, + OMX_IndexConfigCommonFocusStatus, OMX_PARAM_FOCUSSTATUSTYPE, mmalomx_param_mapping_focus_status), +MMALOMX_PARAM_STRAIGHT_MAPPING(MMAL_PARAMETER_EXIF, MMAL_PARAMETER_EXIF_T, + OMX_IndexConfigMetadataItem, OMX_CONFIG_METADATAITEMTYPE, 0), +MMALOMX_PARAM_STRAIGHT_MAPPING(MMAL_PARAMETER_FACE_TRACK_RESULTS, MMAL_PARAMETER_FACE_TRACK_RESULTS_T, + OMX_IndexConfigCommonFaceDetectionRegion, OMX_CONFIG_FACEDETECTIONREGIONTYPE, 0), +MMALOMX_PARAM_STRAIGHT_MAPPING(MMAL_PARAMETER_ENABLE_RAW_CAPTURE, MMAL_PARAMETER_BOOLEAN_T, + OMX_IndexConfigCaptureRawImageURI, OMX_PARAM_CONTENTURITYPE, 0), +MMALOMX_PARAM_PASSTHROUGH_PORTLESS(MMAL_PARAMETER_DPF_FILE, MMAL_PARAMETER_URI_T, + OMX_IndexParamDynamicParameterFile, OMX_PARAM_CONTENTURITYPE), +MMALOMX_PARAM_PASSTHROUGH_PORTLESS(MMAL_PARAMETER_FOCUS_REGIONS, , + OMX_IndexConfigCommonFocusRegionXY, ), +#endif diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/openmaxil/mmalomx_util_params_common.h b/external_src/raspicam-0.1.3/dependencies/mmal/openmaxil/mmalomx_util_params_common.h new file mode 100644 index 0000000..f0f2f96 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/openmaxil/mmalomx_util_params_common.h @@ -0,0 +1,133 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. +*/ + +/** \file + * OpenMAX IL adaptation layer for MMAL - Parameters related functions + */ + +#include "interface/vmcs_host/khronos/IL/OMX_Broadcom.h" +#include "mmalomx_util_params.h" +#include "util/mmal_util_rational.h" + +/* Sanity check that OMX is defining the right int32 types */ +vcos_static_assert(sizeof(OMX_U32) == 4); + +MMAL_STATUS_T mmalomx_param_enum_generic(MMALOMX_PARAM_MAPPING_DIRECTION dir, + const struct MMALOMX_PARAM_TRANSLATION_T *xlat, + MMAL_PARAMETER_HEADER_T *mmal, OMX_PTR omx, MMAL_PORT_T *mmal_port); +MMAL_STATUS_T mmalomx_param_rational_generic(MMALOMX_PARAM_MAPPING_DIRECTION dir, + const struct MMALOMX_PARAM_TRANSLATION_T *xlat, + MMAL_PARAMETER_HEADER_T *mmal, OMX_PTR omx, MMAL_PORT_T *mmal_port); +MMAL_STATUS_T mmalomx_param_mapping_generic(MMALOMX_PARAM_MAPPING_DIRECTION dir, + const struct MMALOMX_PARAM_TRANSLATION_T *xlat, + MMAL_PARAMETER_HEADER_T *mmal, OMX_PTR omx, MMAL_PORT_T *mmal_port); + +extern const MMALOMX_PARAM_TRANSLATION_T mmalomx_param_xlator_audio[]; +extern const MMALOMX_PARAM_TRANSLATION_T mmalomx_param_xlator_video[]; +extern const MMALOMX_PARAM_TRANSLATION_T mmalomx_param_xlator_camera[]; +extern const MMALOMX_PARAM_TRANSLATION_T mmalomx_param_xlator_misc[]; + +#define MMALOMX_PARAM_ENUM_FIND(TYPE, VAR, TABLE, DIR, MMAL, OMX) \ + const TYPE *VAR = TABLE; \ + const TYPE *VAR##_end = VAR + MMAL_COUNTOF(TABLE); \ + if (DIR == MMALOMX_PARAM_MAPPING_TO_MMAL) \ + while (VAR < VAR##_end && VAR->omx != OMX) VAR++; \ + else \ + while (VAR < VAR##_end && VAR->mmal != MMAL) VAR++; \ + do { if (VAR == VAR##_end) { \ + VAR = 0; \ + if (DIR == MMALOMX_PARAM_MAPPING_TO_MMAL) \ + VCOS_ALERT("omx enum value %u not supported", (unsigned int)OMX); \ + else \ + VCOS_ALERT("mmal enum value %u not supported", (unsigned int)MMAL); \ + } } while(0) + +#define mmalomx_ct_assert(e) (sizeof(char[1 - 2*!(e)])) + +/** List of macros used to define parameters mapping */ +#define MMALOMX_PARAM_PASSTHROUGH(a,b,c,d) \ + {a, (uint32_t)c, sizeof(b), sizeof(d), \ + !(offsetof(d, nPortIndex) | mmalomx_ct_assert(sizeof(b)+4==sizeof(d))), \ + 0, MMALOMX_PARAM_TRANSLATION_TYPE_CUSTOM, {0, mmalomx_param_mapping_generic, 0, 0}, 0, 0, \ + MMAL_TO_STRING(a), MMAL_TO_STRING(c)} +#define MMALOMX_PARAM_BOOLEAN(a, b) \ + MMALOMX_PARAM_PASSTHROUGH(a, MMAL_PARAMETER_BOOLEAN_T, b, OMX_CONFIG_PORTBOOLEANTYPE) +#define MMALOMX_PARAM_PASSTHROUGH_PORTLESS(a,b,c,d) \ + {a, (uint32_t)c, sizeof(b), sizeof(d), \ + !!(mmalomx_ct_assert(sizeof(b)==sizeof(d))), \ + 0, MMALOMX_PARAM_TRANSLATION_TYPE_CUSTOM, {0, mmalomx_param_mapping_generic, 0, 0}, 0, 0, \ + MMAL_TO_STRING(a), MMAL_TO_STRING(c)} +#define MMALOMX_PARAM_BOOLEAN_PORTLESS(a, b) \ + MMALOMX_PARAM_PASSTHROUGH_PORTLESS(a, MMAL_PARAMETER_BOOLEAN_T, b, OMX_CONFIG_BOOLEANTYPE) +#define MMALOMX_PARAM_PASSTHROUGH_PORTLESS_DOUBLE_TRANSLATION(a,b,c,d) \ + {a, (uint32_t)c, sizeof(b), sizeof(d), \ + !!(mmalomx_ct_assert(sizeof(b)==sizeof(d))), \ + 1, MMALOMX_PARAM_TRANSLATION_TYPE_CUSTOM, {0, mmalomx_param_mapping_generic, 0, 0}, 0, 0, \ + MMAL_TO_STRING(a), MMAL_TO_STRING(c)} +#define MMALOMX_PARAM_DIRECT_PORTLESS(a,b,c,d) \ + {a, (uint32_t)c, sizeof(b), sizeof(d), 1, \ + 0, MMALOMX_PARAM_TRANSLATION_TYPE_DIRECT, {0, 0, 0, 0}, 0, 0, \ + MMAL_TO_STRING(a), MMAL_TO_STRING(c)} +#define MMALOMX_PARAM_STRAIGHT_MAPPING(a,b,c,d,e) \ + {a, (uint32_t)c, sizeof(b), sizeof(d), \ + !offsetof(d, nPortIndex), \ + 0, MMALOMX_PARAM_TRANSLATION_TYPE_SIMPLE, {e, 0, 0, 0}, 0, 0, \ + MMAL_TO_STRING(a), MMAL_TO_STRING(c)} +#define MMALOMX_PARAM_STRAIGHT_MAPPING_PORTLESS(a,b,c,d,e) \ + {a, (uint32_t)c, sizeof(b), sizeof(d), 1, \ + 0, MMALOMX_PARAM_TRANSLATION_TYPE_SIMPLE, {e, 0, 0, 0}, 0, 0, \ + MMAL_TO_STRING(a), MMAL_TO_STRING(c)} +#define MMALOMX_PARAM_STRAIGHT_MAPPING_DOUBLE_TRANSLATION(a,b,c,d,e) \ + {a, (uint32_t)c, sizeof(b), sizeof(d), 0, \ + 1, MMALOMX_PARAM_TRANSLATION_TYPE_SIMPLE, {e, 0, 0, 0}, 0, 0, \ + MMAL_TO_STRING(a), MMAL_TO_STRING(c)} +#define MMALOMX_PARAM_ENUM(a,b,c,d,e) \ + {a, (uint32_t)c, sizeof(b), sizeof(d), 0, \ + 0, MMALOMX_PARAM_TRANSLATION_TYPE_CUSTOM, {0, mmalomx_param_enum_generic, 0, 0}, e, MMAL_COUNTOF(e), \ + MMAL_TO_STRING(a), MMAL_TO_STRING(c)} +#define MMALOMX_PARAM_ENUM_PORTLESS(a,b,c,d,e) \ + {a, (uint32_t)c, sizeof(b), sizeof(d), 1, \ + 0, MMALOMX_PARAM_TRANSLATION_TYPE_CUSTOM, {0, mmalomx_param_enum_generic, 0, 0}, e, MMAL_COUNTOF(e), \ + MMAL_TO_STRING(a), MMAL_TO_STRING(c)} +#define MMALOMX_PARAM_RATIONAL(a,b,c,d,e) \ + {a, (uint32_t)c, sizeof(b), sizeof(d), 0, \ + 0, MMALOMX_PARAM_TRANSLATION_TYPE_CUSTOM, {0, mmalomx_param_rational_generic, 0, 0}, 0, e, \ + MMAL_TO_STRING(a), MMAL_TO_STRING(c)} +#define MMALOMX_PARAM_RATIONAL_PORTLESS(a,b,c,d,e) \ + {a, (uint32_t)c, sizeof(b), sizeof(d), 1, \ + 0, MMALOMX_PARAM_TRANSLATION_TYPE_CUSTOM, {0, mmalomx_param_rational_generic, 0, 0}, 0, e, \ + MMAL_TO_STRING(a), MMAL_TO_STRING(c)} +#define MMALOMX_PARAM_CUSTOM(a,b,c,d,e) \ + {a, (uint32_t)c, sizeof(b), sizeof(d), 0, \ + 0, MMALOMX_PARAM_TRANSLATION_TYPE_CUSTOM, {0, e, 0, 0}, 0, 0, \ + MMAL_TO_STRING(a), MMAL_TO_STRING(c)} +#define MMALOMX_PARAM_LIST(a,b,c,d,e,f) \ + {a, (uint32_t)c, sizeof(b), sizeof(d), 0, \ + 0, MMALOMX_PARAM_TRANSLATION_TYPE_CUSTOM, {0, 0, f, 0}, 0, offsetof(d,e), \ + MMAL_TO_STRING(a), MMAL_TO_STRING(c)} +#define MMALOMX_PARAM_TERMINATE() \ + {MMAL_PARAMETER_UNUSED, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, 0, 0, 0, 0} diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/openmaxil/mmalomx_util_params_misc.c b/external_src/raspicam-0.1.3/dependencies/mmal/openmaxil/mmalomx_util_params_misc.c new file mode 100644 index 0000000..e364033 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/openmaxil/mmalomx_util_params_misc.c @@ -0,0 +1,157 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 "mmalomx.h" +#include "mmalomx_util_params_common.h" +#include "mmalomx_logging.h" + +static MMAL_STATUS_T mmalomx_param_mapping_event_request(MMALOMX_PARAM_MAPPING_DIRECTION dir, + MMAL_PARAMETER_HEADER_T *mmal_param, OMX_PTR omx_param) +{ + OMX_CONFIG_REQUESTCALLBACKTYPE *omx = (OMX_CONFIG_REQUESTCALLBACKTYPE *)omx_param; + MMAL_PARAMETER_CHANGE_EVENT_REQUEST_T *mmal = (MMAL_PARAMETER_CHANGE_EVENT_REQUEST_T *)mmal_param; + const MMALOMX_PARAM_TRANSLATION_T *change_xlat; + + if (dir == MMALOMX_PARAM_MAPPING_TO_MMAL) + { + change_xlat = mmalomx_find_parameter_from_omx_id(omx->nIndex); + if (!change_xlat) + { + VCOS_ALERT("ommalomx_param_mapping_event_request: omx parameter " + "0x%08x not recognised", omx->nIndex); + return MMAL_EINVAL; + } + + mmal->change_id = change_xlat->mmal_id; + mmal->enable = omx->bEnable; + } + else + { + change_xlat = mmalomx_find_parameter_from_mmal_id(mmal->change_id); + if (!change_xlat) + { + VCOS_ALERT("mmalomx_param_mapping_event_request: mmal parameter " + "0x%08x not recognised", mmal->change_id); + return MMAL_EINVAL; + } + + omx->nIndex = change_xlat->omx_id; + omx->bEnable = mmal->enable; + } + + return MMAL_SUCCESS; +} + +static MMAL_STATUS_T mmalomx_param_mapping_statistics(MMALOMX_PARAM_MAPPING_DIRECTION dir, + MMAL_PARAMETER_HEADER_T *mmal_param, OMX_PTR omx_param) +{ + OMX_CONFIG_BRCMPORTSTATSTYPE *omx = (OMX_CONFIG_BRCMPORTSTATSTYPE *)omx_param; + MMAL_PARAMETER_STATISTICS_T *mmal = (MMAL_PARAMETER_STATISTICS_T *)mmal_param; + + if (dir == MMALOMX_PARAM_MAPPING_TO_MMAL) + { + mmal->buffer_count = omx->nBufferCount; + mmal->frame_count = omx->nImageCount + omx->nFrameCount; + mmal->frames_skipped = omx->nFrameSkips; + mmal->frames_discarded = omx->nDiscards; + mmal->eos_seen = omx->nEOS; + mmal->maximum_frame_bytes = omx->nMaxFrameSize; + mmal->total_bytes = omx_ticks_to_s64(omx->nByteCount); + mmal->corrupt_macroblocks = omx->nCorruptMBs; + } + else + { + omx->nBufferCount = mmal->buffer_count; + omx->nFrameCount = mmal->frame_count; + omx->nImageCount = 0; + omx->nFrameSkips = mmal->frames_skipped; + omx->nDiscards = mmal->frames_discarded; + omx->nEOS = mmal->eos_seen; + omx->nMaxFrameSize = mmal->maximum_frame_bytes; + omx->nByteCount = omx_ticks_from_s64(mmal->total_bytes); + omx->nCorruptMBs = mmal->corrupt_macroblocks; + } + + return MMAL_SUCCESS; +} + +static MMAL_STATUS_T mmalomx_param_mapping_buffer_flags(MMALOMX_PARAM_MAPPING_DIRECTION dir, + MMAL_PARAMETER_HEADER_T *mmal_param, OMX_PTR omx_param) +{ + OMX_PARAM_U32TYPE *omx = (OMX_PARAM_U32TYPE *)omx_param; + MMAL_PARAMETER_UINT32_T *mmal = (MMAL_PARAMETER_UINT32_T *)mmal_param; + + if (dir == MMALOMX_PARAM_MAPPING_TO_MMAL) + mmal->value = mmalil_buffer_flags_to_mmal(omx->nU32); + else + omx->nU32 = mmalil_buffer_flags_to_omx(mmal->value); + + return MMAL_SUCCESS; +} + +static MMAL_STATUS_T mmalomx_param_mapping_time(MMALOMX_PARAM_MAPPING_DIRECTION dir, + MMAL_PARAMETER_HEADER_T *mmal_param, OMX_PTR omx_param) +{ + OMX_TIME_CONFIG_TIMESTAMPTYPE *omx = (OMX_TIME_CONFIG_TIMESTAMPTYPE *)omx_param; + MMAL_PARAMETER_INT64_T *mmal = (MMAL_PARAMETER_INT64_T *)mmal_param; + + if (dir == MMALOMX_PARAM_MAPPING_TO_MMAL) + mmal->value = omx_ticks_to_s64(omx->nTimestamp); + else + omx->nTimestamp = omx_ticks_from_s64(mmal->value); + + return MMAL_SUCCESS; +} + +const MMALOMX_PARAM_TRANSLATION_T mmalomx_param_xlator_misc[] = { + MMALOMX_PARAM_STRAIGHT_MAPPING_DOUBLE_TRANSLATION(MMAL_PARAMETER_CHANGE_EVENT_REQUEST, MMAL_PARAMETER_CHANGE_EVENT_REQUEST_T, + OMX_IndexConfigRequestCallback, OMX_CONFIG_REQUESTCALLBACKTYPE, + mmalomx_param_mapping_event_request), + MMALOMX_PARAM_STRAIGHT_MAPPING(MMAL_PARAMETER_STATISTICS, MMAL_PARAMETER_STATISTICS_T, + OMX_IndexConfigBrcmPortStats, OMX_CONFIG_BRCMPORTSTATSTYPE, + mmalomx_param_mapping_statistics), + MMALOMX_PARAM_PASSTHROUGH(MMAL_PARAMETER_MEM_USAGE, MMAL_PARAMETER_MEM_USAGE_T, + OMX_IndexConfigBrcmPoolMemAllocSize, OMX_PARAM_U32TYPE), + MMALOMX_PARAM_STRAIGHT_MAPPING(MMAL_PARAMETER_BUFFER_FLAG_FILTER, MMAL_PARAMETER_UINT32_T, + OMX_IndexConfigBrcmBufferFlagFilter, OMX_PARAM_U32TYPE, + mmalomx_param_mapping_buffer_flags), + MMALOMX_PARAM_BOOLEAN(MMAL_PARAMETER_ZERO_COPY, + OMX_IndexParamBrcmZeroCopy), + MMALOMX_PARAM_BOOLEAN(MMAL_PARAMETER_LOCKSTEP_ENABLE, + OMX_IndexParamBrcmLockStepEnable), + MMALOMX_PARAM_BOOLEAN_PORTLESS(MMAL_PARAMETER_POWERMON_ENABLE, + OMX_IndexConfigBrcmPowerMonitor), + MMALOMX_PARAM_STRAIGHT_MAPPING(MMAL_PARAMETER_CLOCK_TIME, MMAL_PARAMETER_INT64_T, + OMX_IndexConfigTimeCurrentMediaTime, OMX_TIME_CONFIG_TIMESTAMPTYPE, + mmalomx_param_mapping_time), + MMALOMX_PARAM_TERMINATE() +}; + +#if 0 +/* Conversions which are not done here. Should part of the core. */ +MMAL_PARAMETER_SUPPORTED_ENCODINGS +#endif diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/openmaxil/mmalomx_util_params_video.c b/external_src/raspicam-0.1.3/dependencies/mmal/openmaxil/mmalomx_util_params_video.c new file mode 100644 index 0000000..f088296 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/openmaxil/mmalomx_util_params_video.c @@ -0,0 +1,277 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 "mmalomx.h" +#include "mmalomx_util_params_common.h" +#include "mmalomx_logging.h" + +static void rect_to_omx(OMX_DISPLAYRECTTYPE *dst, const MMAL_RECT_T *src) +{ + dst->x_offset = src->x; + dst->y_offset = src->y; + dst->width = src->width; + dst->height = src->height; +} + +static void rect_to_mmal(MMAL_RECT_T *dst, const OMX_DISPLAYRECTTYPE *src) +{ + dst->x = src->x_offset; + dst->y = src->y_offset; + dst->width = src->width; + dst->height = src->height; +} + +static MMAL_STATUS_T mmalomx_param_mapping_displayregion(MMALOMX_PARAM_MAPPING_DIRECTION dir, + MMAL_PARAMETER_HEADER_T *mmal_param, OMX_PTR omx_param) +{ + OMX_CONFIG_DISPLAYREGIONTYPE *omx = (OMX_CONFIG_DISPLAYREGIONTYPE *)omx_param; + MMAL_DISPLAYREGION_T *mmal = (MMAL_DISPLAYREGION_T *)mmal_param; + + if (dir == MMALOMX_PARAM_MAPPING_TO_MMAL) + { + mmal->set = omx->set; + mmal->display_num = omx->num; + mmal->fullscreen = omx->fullscreen; + mmal->transform = omx->transform; + rect_to_mmal(&mmal->dest_rect, &omx->dest_rect); + rect_to_mmal(&mmal->src_rect, &omx->src_rect); + mmal->noaspect = omx->noaspect; + mmal->mode = omx->mode; + mmal->pixel_x = omx->pixel_x; + mmal->pixel_y = omx->pixel_y; + mmal->layer = omx->layer; + mmal->copyprotect_required = omx->copyprotect_required; + mmal->alpha = omx->alpha; + } + else + { + omx->set = mmal->set; + omx->num = mmal->display_num; + omx->fullscreen = mmal->fullscreen; + omx->transform = mmal->transform; + rect_to_omx(&omx->dest_rect, &mmal->dest_rect); + rect_to_omx(&omx->src_rect, &mmal->src_rect); + omx->noaspect = mmal->noaspect; + omx->mode = mmal->mode; + omx->pixel_x = mmal->pixel_x; + omx->pixel_y = mmal->pixel_y; + omx->layer = mmal->layer; + omx->copyprotect_required = mmal->copyprotect_required; + omx->alpha = mmal->alpha; + } + + return MMAL_SUCCESS; +} + +static MMAL_STATUS_T mmalomx_param_list_supported_profiles(MMALOMX_PARAM_MAPPING_DIRECTION dir, + const MMALOMX_PARAM_TRANSLATION_T *xlat, unsigned int index, + MMAL_PARAMETER_HEADER_T *mmal_param, OMX_PTR omx_param, MMAL_PORT_T *mmal_port) +{ + OMX_VIDEO_PARAM_PROFILELEVELTYPE *omx = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)omx_param; + MMAL_PARAMETER_VIDEO_PROFILE_T *mmal = (MMAL_PARAMETER_VIDEO_PROFILE_T *)mmal_param; + MMAL_PARAM_UNUSED(xlat); + + if (dir == MMALOMX_PARAM_MAPPING_TO_MMAL) + { + OMX_VIDEO_CODINGTYPE coding = mmalil_encoding_to_omx_video_coding(mmal_port->format->encoding); + mmal->profile[index].profile = mmalil_omx_video_profile_to_mmal(omx->eProfile, coding); + mmal->profile[index].level = mmalil_omx_video_level_to_mmal(omx->eLevel, coding); + } + else + { + omx->eProfile = mmalil_video_profile_to_omx(mmal->profile[index].profile); + omx->eLevel = mmalil_video_level_to_omx(mmal->profile[index].level); + } + + return MMAL_SUCCESS; +} + +static MMAL_STATUS_T mmalomx_param_custom_profile(MMALOMX_PARAM_MAPPING_DIRECTION dir, + const MMALOMX_PARAM_TRANSLATION_T *xlat, + MMAL_PARAMETER_HEADER_T *mmal_param, OMX_PTR omx_param, MMAL_PORT_T *mmal_port) +{ + OMX_VIDEO_PARAM_PROFILELEVELTYPE *omx = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)omx_param; + MMAL_PARAMETER_VIDEO_PROFILE_T *mmal = (MMAL_PARAMETER_VIDEO_PROFILE_T *)mmal_param; + MMAL_PARAM_UNUSED(xlat); + + if (dir == MMALOMX_PARAM_MAPPING_TO_MMAL) + { + OMX_VIDEO_CODINGTYPE coding = mmalil_encoding_to_omx_video_coding(mmal_port->format->encoding); + mmal->profile[0].profile = mmalil_omx_video_profile_to_mmal(omx->eProfile, coding); + mmal->profile[0].level = mmalil_omx_video_level_to_mmal(omx->eLevel, coding); + } + else + { + omx->eProfile = mmalil_video_profile_to_omx(mmal->profile[0].profile); + omx->eLevel = mmalil_video_level_to_omx(mmal->profile[0].level); + } + + return MMAL_SUCCESS; +} + +static MMAL_STATUS_T mmalomx_param_custom_ratecontrol(MMALOMX_PARAM_MAPPING_DIRECTION dir, + const MMALOMX_PARAM_TRANSLATION_T *xlat, + MMAL_PARAMETER_HEADER_T *mmal_param, OMX_PTR omx_param, MMAL_PORT_T *mmal_port) +{ + OMX_VIDEO_PARAM_BITRATETYPE *omx = (OMX_VIDEO_PARAM_BITRATETYPE *)omx_param; + MMAL_PARAMETER_VIDEO_RATECONTROL_T *mmal = (MMAL_PARAMETER_VIDEO_RATECONTROL_T *)mmal_param; + MMAL_PARAM_UNUSED(xlat); + + if (dir == MMALOMX_PARAM_MAPPING_TO_MMAL) + { + mmal->control = mmalil_omx_video_ratecontrol_to_mmal(omx->eControlRate); + /* This does not apply nTargetBitrate but should not be necessary */ + } + else + { + omx->eControlRate = mmalil_video_ratecontrol_to_omx(mmal->control); + omx->nTargetBitrate = mmal_port->format->bitrate; /* Should not really be necessary */ + } + + return MMAL_SUCCESS; +} + +static const MMALOMX_PARAM_ENUM_TRANSLATE_T mmalomx_param_enum_nalunitformat[] = { + {MMAL_VIDEO_NALUNITFORMAT_STARTCODES, OMX_NaluFormatStartCodes}, + {MMAL_VIDEO_NALUNITFORMAT_NALUNITPERBUFFER, OMX_NaluFormatOneNaluPerBuffer}, + {MMAL_VIDEO_NALUNITFORMAT_ONEBYTEINTERLEAVELENGTH, OMX_NaluFormatOneByteInterleaveLength}, + {MMAL_VIDEO_NALUNITFORMAT_TWOBYTEINTERLEAVELENGTH, OMX_NaluFormatTwoByteInterleaveLength}, + {MMAL_VIDEO_NALUNITFORMAT_FOURBYTEINTERLEAVELENGTH, OMX_NaluFormatFourByteInterleaveLength}, +}; + +static MMAL_STATUS_T mmalomx_param_mapping_frame_rate(MMALOMX_PARAM_MAPPING_DIRECTION dir, + MMAL_PARAMETER_HEADER_T *mmal_param, OMX_PTR omx_param) +{ + OMX_CONFIG_FRAMERATETYPE *omx = (OMX_CONFIG_FRAMERATETYPE *)omx_param; + MMAL_PARAMETER_FRAME_RATE_T *mmal = (MMAL_PARAMETER_FRAME_RATE_T *)mmal_param; + + if (dir == MMALOMX_PARAM_MAPPING_TO_MMAL) + { + mmal->frame_rate.num = omx->xEncodeFramerate; + mmal->frame_rate.den = (1<<16); + } + else + { + omx->xEncodeFramerate = 0; + if (mmal->frame_rate.den) + omx->xEncodeFramerate = (((int64_t)mmal->frame_rate.num)<<16)/mmal->frame_rate.den; + } + + return MMAL_SUCCESS; +} + +const MMALOMX_PARAM_TRANSLATION_T mmalomx_param_xlator_video[] = { + MMALOMX_PARAM_STRAIGHT_MAPPING(MMAL_PARAMETER_DISPLAYREGION, MMAL_DISPLAYREGION_T, + OMX_IndexConfigDisplayRegion, OMX_CONFIG_DISPLAYREGIONTYPE, + mmalomx_param_mapping_displayregion), + MMALOMX_PARAM_LIST(MMAL_PARAMETER_SUPPORTED_PROFILES, MMAL_PARAMETER_VIDEO_PROFILE_T, + OMX_IndexParamVideoProfileLevelQuerySupported, OMX_VIDEO_PARAM_PROFILELEVELTYPE, + nProfileIndex, mmalomx_param_list_supported_profiles), + MMALOMX_PARAM_CUSTOM(MMAL_PARAMETER_PROFILE, MMAL_PARAMETER_VIDEO_PROFILE_T, + OMX_IndexParamVideoProfileLevelCurrent, OMX_VIDEO_PARAM_PROFILELEVELTYPE, + mmalomx_param_custom_profile), + MMALOMX_PARAM_PASSTHROUGH(MMAL_PARAMETER_INTRAPERIOD, MMAL_PARAMETER_UINT32_T, + OMX_IndexConfigBrcmVideoIntraPeriod, OMX_PARAM_U32TYPE), + MMALOMX_PARAM_CUSTOM(MMAL_PARAMETER_RATECONTROL, MMAL_PARAMETER_VIDEO_RATECONTROL_T, + OMX_IndexParamVideoBitrate, OMX_VIDEO_PARAM_BITRATETYPE, + mmalomx_param_custom_ratecontrol), + MMALOMX_PARAM_ENUM(MMAL_PARAMETER_NALUNITFORMAT, MMAL_PARAMETER_VIDEO_NALUNITFORMAT_T, + OMX_IndexParamNalStreamFormatSelect, OMX_NALSTREAMFORMATTYPE, mmalomx_param_enum_nalunitformat), + MMALOMX_PARAM_BOOLEAN_PORTLESS(MMAL_PARAMETER_MINIMISE_FRAGMENTATION, + OMX_IndexConfigMinimiseFragmentation), + MMALOMX_PARAM_PASSTHROUGH(MMAL_PARAMETER_MB_ROWS_PER_SLICE, MMAL_PARAMETER_UINT32_T, + OMX_IndexConfigBrcmVideoEncoderMBRowsPerSlice, OMX_PARAM_U32TYPE), + MMALOMX_PARAM_PASSTHROUGH(MMAL_PARAMETER_VIDEO_LEVEL_EXTENSION, MMAL_PARAMETER_VIDEO_LEVEL_EXTENSION_T, + OMX_IndexConfigEncLevelExtension, OMX_VIDEO_CONFIG_LEVEL_EXTEND), + MMALOMX_PARAM_PASSTHROUGH(MMAL_PARAMETER_VIDEO_INTRA_REFRESH, MMAL_PARAMETER_VIDEO_INTRA_REFRESH_T, + OMX_IndexConfigBrcmVideoIntraRefresh, OMX_VIDEO_PARAM_INTRAREFRESHTYPE), + MMALOMX_PARAM_PASSTHROUGH(MMAL_PARAMETER_VIDEO_INTRA_REFRESH, MMAL_PARAMETER_VIDEO_INTRA_REFRESH_T, + OMX_IndexParamVideoIntraRefresh, OMX_VIDEO_PARAM_INTRAREFRESHTYPE), + MMALOMX_PARAM_PASSTHROUGH(MMAL_PARAMETER_VIDEO_EEDE_ENABLE, MMAL_PARAMETER_VIDEO_EEDE_ENABLE_T, + OMX_IndexParamBrcmEEDEEnable, OMX_VIDEO_EEDE_ENABLE), + MMALOMX_PARAM_PASSTHROUGH(MMAL_PARAMETER_VIDEO_EEDE_LOSSRATE, MMAL_PARAMETER_VIDEO_EEDE_LOSSRATE_T, + OMX_IndexParamBrcmEEDELossRate, OMX_VIDEO_EEDE_LOSSRATE), + MMALOMX_PARAM_BOOLEAN_PORTLESS(MMAL_PARAMETER_VIDEO_REQUEST_I_FRAME, + OMX_IndexConfigBrcmVideoRequestIFrame), + MMALOMX_PARAM_BOOLEAN_PORTLESS(MMAL_PARAMETER_VIDEO_IMMUTABLE_INPUT, + OMX_IndexParamBrcmImmutableInput), + MMALOMX_PARAM_PASSTHROUGH(MMAL_PARAMETER_VIDEO_BIT_RATE, MMAL_PARAMETER_UINT32_T, + OMX_IndexConfigVideoBitrate, OMX_VIDEO_CONFIG_BITRATETYPE), + MMALOMX_PARAM_STRAIGHT_MAPPING(MMAL_PARAMETER_VIDEO_FRAME_RATE, MMAL_PARAMETER_FRAME_RATE_T, + OMX_IndexConfigVideoFramerate, OMX_CONFIG_FRAMERATETYPE, mmalomx_param_mapping_frame_rate), + MMALOMX_PARAM_STRAIGHT_MAPPING(MMAL_PARAMETER_FRAME_RATE, MMAL_PARAMETER_FRAME_RATE_T, + OMX_IndexConfigVideoFramerate, OMX_CONFIG_FRAMERATETYPE, mmalomx_param_mapping_frame_rate), + MMALOMX_PARAM_PASSTHROUGH(MMAL_PARAMETER_VIDEO_ENCODE_MIN_QUANT, MMAL_PARAMETER_UINT32_T, + OMX_IndexParamBrcmVideoEncodeMinQuant, OMX_PARAM_U32TYPE), + MMALOMX_PARAM_PASSTHROUGH(MMAL_PARAMETER_VIDEO_ENCODE_MAX_QUANT, MMAL_PARAMETER_UINT32_T, + OMX_IndexParamBrcmVideoEncodeMaxQuant, OMX_PARAM_U32TYPE), + MMALOMX_PARAM_PASSTHROUGH(MMAL_PARAMETER_VIDEO_ENCODE_RC_MODEL, MMAL_PARAMETER_VIDEO_ENCODE_RC_MODEL_T, + OMX_IndexParamRateControlModel, OMX_PARAM_U32TYPE), + MMALOMX_PARAM_PASSTHROUGH(MMAL_PARAMETER_EXTRA_BUFFERS, MMAL_PARAMETER_UINT32_T, + OMX_IndexParamBrcmExtraBuffers, OMX_PARAM_U32TYPE), + MMALOMX_PARAM_PASSTHROUGH(MMAL_PARAMETER_VIDEO_ALIGN_HORIZ, MMAL_PARAMETER_UINT32_T, + OMX_IndexParamBrcmAlignHoriz, OMX_PARAM_U32TYPE), + MMALOMX_PARAM_PASSTHROUGH(MMAL_PARAMETER_VIDEO_ALIGN_VERT, MMAL_PARAMETER_UINT32_T, + OMX_IndexParamBrcmAlignVert, OMX_PARAM_U32TYPE), + MMALOMX_PARAM_BOOLEAN_PORTLESS(MMAL_PARAMETER_VIDEO_DROPPABLE_PFRAMES, + OMX_IndexParamBrcmDroppablePFrames), + MMALOMX_PARAM_PASSTHROUGH(MMAL_PARAMETER_VIDEO_ENCODE_INITIAL_QUANT, MMAL_PARAMETER_UINT32_T, + OMX_IndexParamBrcmVideoInitialQuant, OMX_PARAM_U32TYPE), + MMALOMX_PARAM_PASSTHROUGH(MMAL_PARAMETER_VIDEO_ENCODE_QP_P, MMAL_PARAMETER_UINT32_T, + OMX_IndexParamBrcmVideoInitialQuant, OMX_PARAM_U32TYPE), + MMALOMX_PARAM_PASSTHROUGH(MMAL_PARAMETER_VIDEO_ENCODE_RC_SLICE_DQUANT, MMAL_PARAMETER_UINT32_T, + OMX_IndexParamBrcmVideoRCSliceDQuant, OMX_PARAM_U32TYPE), + MMALOMX_PARAM_PASSTHROUGH(MMAL_PARAMETER_VIDEO_ENCODE_FRAME_LIMIT_BITS, MMAL_PARAMETER_UINT32_T, + OMX_IndexParamBrcmVideoFrameLimitBits, OMX_PARAM_U32TYPE), + MMALOMX_PARAM_PASSTHROUGH(MMAL_PARAMETER_VIDEO_ENCODE_PEAK_RATE, MMAL_PARAMETER_UINT32_T, + OMX_IndexParamBrcmVideoPeakRate, OMX_PARAM_U32TYPE), + MMALOMX_PARAM_BOOLEAN_PORTLESS(MMAL_PARAMETER_VIDEO_ENCODE_H264_DISABLE_CABAC, + OMX_IndexConfigBrcmVideoH264DisableCABAC), + MMALOMX_PARAM_BOOLEAN_PORTLESS(MMAL_PARAMETER_VIDEO_ENCODE_H264_LOW_LATENCY, + OMX_IndexConfigBrcmVideoH264LowLatency), + MMALOMX_PARAM_BOOLEAN_PORTLESS(MMAL_PARAMETER_VIDEO_ENCODE_H264_AU_DELIMITERS, + OMX_IndexConfigBrcmVideoH264AUDelimiters), + MMALOMX_PARAM_PASSTHROUGH(MMAL_PARAMETER_VIDEO_ENCODE_H264_DEBLOCK_IDC, MMAL_PARAMETER_UINT32_T, + OMX_IndexConfigBrcmVideoH264DeblockIDC, OMX_PARAM_U32TYPE), + MMALOMX_PARAM_PASSTHROUGH(MMAL_PARAMETER_VIDEO_ENCODE_H264_MB_INTRA_MODE, MMAL_PARAMETER_VIDEO_ENCODER_H264_MB_INTRA_MODES_T, + OMX_IndexConfigBrcmVideoH264IntraMBMode, OMX_PARAM_U32TYPE), + MMALOMX_PARAM_BOOLEAN_PORTLESS(MMAL_PARAMETER_VIDEO_ENCODE_HEADER_ON_OPEN, + OMX_IndexParamBrcmHeaderOnOpen), + MMALOMX_PARAM_BOOLEAN_PORTLESS(MMAL_PARAMETER_VIDEO_ENCODE_PRECODE_FOR_QP, + OMX_IndexParamBrcmVideoPrecodeForQP), + MMALOMX_PARAM_BOOLEAN_PORTLESS(MMAL_PARAMETER_VIDEO_TIMESTAMP_FIFO, + OMX_IndexParamBrcmVideoTimestampFifo), + MMALOMX_PARAM_BOOLEAN_PORTLESS(MMAL_PARAMETER_VIDEO_DECODE_ERROR_CONCEALMENT, + OMX_IndexParamBrcmVideoDecodeErrorConcealment), + MMALOMX_PARAM_PASSTHROUGH_PORTLESS_DOUBLE_TRANSLATION(MMAL_PARAMETER_VIDEO_DRM_PROTECT_BUFFER, MMAL_PARAMETER_VIDEO_DRM_PROTECT_BUFFER_T, + OMX_IndexParamBrcmVideoDrmProtectBuffer, OMX_PARAM_BRCMVIDEODRMPROTECTBUFFERTYPE), + MMALOMX_PARAM_PASSTHROUGH_PORTLESS(MMAL_PARAMETER_VIDEO_DECODE_CONFIG_VD3, MMAL_PARAMETER_BYTES_T, + OMX_IndexParamBrcmVideoDecodeConfigVD3, OMX_PARAM_BRCMVIDEODECODECONFIGVD3TYPE), + MMALOMX_PARAM_BOOLEAN(MMAL_PARAMETER_VIDEO_ENCODE_INLINE_HEADER, + OMX_IndexParamBrcmVideoAVCInlineHeaderEnable), + MMALOMX_PARAM_TERMINATE() +}; diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/test/CMakeLists.txt b/external_src/raspicam-0.1.3/dependencies/mmal/test/CMakeLists.txt new file mode 100644 index 0000000..10ec113 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/test/CMakeLists.txt @@ -0,0 +1,26 @@ +SET( MMAL_TOP ../../.. ) +SET( MMALPLAY_TOP ${MMAL_TOP}/host_applications/vmcs/test_apps/mmalplay ) +add_executable(mmalplay ${MMALPLAY_TOP}/playback.c ${MMALPLAY_TOP}/mmalplay.c) +target_link_libraries(mmalplay mmal_core mmal_util) +target_link_libraries(mmalplay -Wl,--whole-archive mmal_components containers -Wl,--no-whole-archive mmal_core) +target_link_libraries(mmalplay vcos) + +SET( MMALCAM_TOP ${MMAL_TOP}/host_applications/vmcs/test_apps/mmalcam ) +add_executable(mmalcam ${MMALCAM_TOP}/viewfinder.c ${MMALCAM_TOP}/mmalcam.c) +target_link_libraries(mmalcam mmal_core mmal_util) +target_link_libraries(mmalcam -Wl,--whole-archive mmal_components -Wl,--no-whole-archive mmal_core) +target_link_libraries(mmalcam vcos) + +SET( MMALEXAMPLES_TOP ${MMAL_TOP}/interface/mmal/test/examples ) +add_executable(mmal_example_connections ${MMALEXAMPLES_TOP}/example_connections.c) +target_link_libraries(mmal_example_connections mmal_core mmal_util) +target_link_libraries(mmal_example_connections -Wl,--whole-archive mmal_components -Wl,--no-whole-archive mmal_core) +add_executable(mmal_example_graph ${MMALEXAMPLES_TOP}/example_graph.c) +target_link_libraries(mmal_example_graph mmal_core mmal_util) +target_link_libraries(mmal_example_graph -Wl,--whole-archive mmal_components -Wl,--no-whole-archive mmal_core) +add_executable(mmal_example_basic_1 ${MMALEXAMPLES_TOP}/example_basic_1.c) +target_link_libraries(mmal_example_basic_1 mmal_core mmal_util) +target_link_libraries(mmal_example_basic_1 -Wl,--whole-archive mmal_components -Wl,--no-whole-archive mmal_core) +add_executable(mmal_example_basic_2 ${MMALEXAMPLES_TOP}/example_basic_2.c) +target_link_libraries(mmal_example_basic_2 mmal_core mmal_util) +target_link_libraries(mmal_example_basic_2 -Wl,--whole-archive mmal_components -Wl,--no-whole-archive mmal_core) diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/test/examples/example_basic_1.c b/external_src/raspicam-0.1.3/dependencies/mmal/test/examples/example_basic_1.c new file mode 100644 index 0000000..2265b37 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/test/examples/example_basic_1.c @@ -0,0 +1,238 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 "mmal.h" +#include "util/mmal_default_components.h" +#include "interface/vcos/vcos.h" +#include + +#define CHECK_STATUS(status, msg) if (status != MMAL_SUCCESS) { fprintf(stderr, msg"\n"); goto error; } + +static uint8_t codec_header_bytes[512]; +static unsigned int codec_header_bytes_size = sizeof(codec_header_bytes); + +static FILE *source_file; + +/* Macros abstracting the I/O, just to make the example code clearer */ +#define SOURCE_OPEN(uri) \ + source_file = fopen(uri, "rb"); if (!source_file) goto error; +#define SOURCE_READ_CODEC_CONFIG_DATA(bytes, size) \ + size = fread(bytes, 1, size, source_file); rewind(source_file) +#define SOURCE_READ_DATA_INTO_BUFFER(a) \ + a->length = fread(a->data, 1, a->alloc_size - 128, source_file); \ + a->offset = 0; a->pts = a->dts = MMAL_TIME_UNKNOWN +#define SOURCE_CLOSE() \ + if (source_file) fclose(source_file) + +/** Context for our application */ +static struct CONTEXT_T { + VCOS_SEMAPHORE_T semaphore; + MMAL_QUEUE_T *queue; +} context; + +/** Callback from the input port. + * Buffer has been consumed and is available to be used again. */ +static void input_callback(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) +{ + struct CONTEXT_T *ctx = (struct CONTEXT_T *)port->userdata; + + /* The decoder is done with the data, just recycle the buffer header into its pool */ + mmal_buffer_header_release(buffer); + + /* Kick the processing thread */ + vcos_semaphore_post(&ctx->semaphore); +} + +/** Callback from the output port. + * Buffer has been produced by the port and is available for processing. */ +static void output_callback(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) +{ + struct CONTEXT_T *ctx = (struct CONTEXT_T *)port->userdata; + + /* Queue the decoded video frame */ + mmal_queue_put(ctx->queue, buffer); + + /* Kick the processing thread */ + vcos_semaphore_post(&ctx->semaphore); +} + +int main(int argc, char **argv) +{ + MMAL_STATUS_T status = MMAL_EINVAL; + MMAL_COMPONENT_T *decoder = 0; + MMAL_POOL_T *pool_in = 0, *pool_out = 0; + unsigned int count; + + if (argc < 2) + { + fprintf(stderr, "invalid arguments\n"); + return -1; + } + + vcos_semaphore_create(&context.semaphore, "example", 1); + + SOURCE_OPEN(argv[1]); + + /* Create the decoder component. + * This specific component exposes 2 ports (1 input and 1 output). Like most components + * its expects the format of its input port to be set by the client in order for it to + * know what kind of data it will be fed. */ + status = mmal_component_create(MMAL_COMPONENT_DEFAULT_VIDEO_DECODER, &decoder); + CHECK_STATUS(status, "failed to create decoder"); + + /* Set format of video decoder input port */ + MMAL_ES_FORMAT_T *format_in = decoder->input[0]->format; + format_in->type = MMAL_ES_TYPE_VIDEO; + format_in->encoding = MMAL_ENCODING_H264; + format_in->es->video.width = 1280; + format_in->es->video.height = 720; + format_in->es->video.frame_rate.num = 30; + format_in->es->video.frame_rate.den = 1; + format_in->es->video.par.num = 1; + format_in->es->video.par.den = 1; + /* If the data is known to be framed then the following flag should be set: + * format_in->flags |= MMAL_ES_FORMAT_FLAG_FRAMED; */ + + SOURCE_READ_CODEC_CONFIG_DATA(codec_header_bytes, codec_header_bytes_size); + status = mmal_format_extradata_alloc(format_in, codec_header_bytes_size); + CHECK_STATUS(status, "failed to allocate extradata"); + format_in->extradata_size = codec_header_bytes_size; + if (format_in->extradata_size) + memcpy(format_in->extradata, codec_header_bytes, format_in->extradata_size); + + status = mmal_port_format_commit(decoder->input[0]); + CHECK_STATUS(status, "failed to commit format"); + + /* Display the output port format */ + MMAL_ES_FORMAT_T *format_out = decoder->output[0]->format; + fprintf(stderr, "%s\n", decoder->output[0]->name); + fprintf(stderr, " type: %i, fourcc: %4.4s\n", format_out->type, (char *)&format_out->encoding); + fprintf(stderr, " bitrate: %i, framed: %i\n", format_out->bitrate, + !!(format_out->flags & MMAL_ES_FORMAT_FLAG_FRAMED)); + fprintf(stderr, " extra data: %i, %p\n", format_out->extradata_size, format_out->extradata); + fprintf(stderr, " width: %i, height: %i, (%i,%i,%i,%i)\n", + format_out->es->video.width, format_out->es->video.height, + format_out->es->video.crop.x, format_out->es->video.crop.y, + format_out->es->video.crop.width, format_out->es->video.crop.height); + + /* The format of both ports is now set so we can get their buffer requirements and create + * our buffer headers. We use the buffer pool API to create these. */ + decoder->input[0]->buffer_num = decoder->input[0]->buffer_num_min; + decoder->input[0]->buffer_size = decoder->input[0]->buffer_size_min; + decoder->output[0]->buffer_num = decoder->output[0]->buffer_num_min; + decoder->output[0]->buffer_size = decoder->output[0]->buffer_size_min; + pool_in = mmal_pool_create(decoder->input[0]->buffer_num, + decoder->input[0]->buffer_size); + pool_out = mmal_pool_create(decoder->output[0]->buffer_num, + decoder->output[0]->buffer_size); + + /* Create a queue to store our decoded video frames. The callback we will get when + * a frame has been decoded will put the frame into this queue. */ + context.queue = mmal_queue_create(); + + /* Store a reference to our context in each port (will be used during callbacks) */ + decoder->input[0]->userdata = (void *)&context; + decoder->output[0]->userdata = (void *)&context; + + /* Enable all the input port and the output port. + * The callback specified here is the function which will be called when the buffer header + * we sent to the component has been processed. */ + status = mmal_port_enable(decoder->input[0], input_callback); + CHECK_STATUS(status, "failed to enable input port"); + status = mmal_port_enable(decoder->output[0], output_callback); + CHECK_STATUS(status, "failed to enable output port"); + + /* Component won't start processing data until it is enabled. */ + status = mmal_component_enable(decoder); + CHECK_STATUS(status, "failed to enable component"); + + /* Start decoding */ + fprintf(stderr, "start decoding\n"); + + /* This is the main processing loop */ + for (count = 0; count < 500; count++) + { + MMAL_BUFFER_HEADER_T *buffer; + + /* Wait for buffer headers to be available on either of the decoder ports */ + vcos_semaphore_wait(&context.semaphore); + + /* Send data to decode to the input port of the video decoder */ + if ((buffer = mmal_queue_get(pool_in->queue)) != NULL) + { + SOURCE_READ_DATA_INTO_BUFFER(buffer); + if (!buffer->length) + break; + + fprintf(stderr, "sending %i bytes\n", (int)buffer->length); + status = mmal_port_send_buffer(decoder->input[0], buffer); + CHECK_STATUS(status, "failed to send buffer"); + } + + /* Get our decoded frames */ + while ((buffer = mmal_queue_get(context.queue)) != NULL) + { + /* We have a frame, do something with it (why not display it for instance?). + * Once we're done with it, we release it. It will automatically go back + * to its original pool so it can be reused for a new video frame. + */ + fprintf(stderr, "decoded frame\n"); + mmal_buffer_header_release(buffer); + } + + /* Send empty buffers to the output port of the decoder */ + while ((buffer = mmal_queue_get(pool_out->queue)) != NULL) + { + status = mmal_port_send_buffer(decoder->output[0], buffer); + CHECK_STATUS(status, "failed to send buffer"); + } + } + + /* Stop decoding */ + fprintf(stderr, "stop decoding\n"); + + /* Stop everything. Not strictly necessary since mmal_component_destroy() + * will do that anyway */ + mmal_port_disable(decoder->input[0]); + mmal_port_disable(decoder->output[0]); + mmal_component_disable(decoder); + + error: + /* Cleanup everything */ + if (decoder) + mmal_component_destroy(decoder); + if (pool_in) + mmal_pool_destroy(pool_in); + if (pool_out) + mmal_pool_destroy(pool_out); + if (context.queue) + mmal_queue_destroy(context.queue); + + SOURCE_CLOSE(); + vcos_semaphore_delete(&context.semaphore); + return status == MMAL_SUCCESS ? 0 : -1; +} diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/test/examples/example_basic_2.c b/external_src/raspicam-0.1.3/dependencies/mmal/test/examples/example_basic_2.c new file mode 100644 index 0000000..aa02d8f --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/test/examples/example_basic_2.c @@ -0,0 +1,304 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 "mmal.h" +#include "util/mmal_default_components.h" +#include "util/mmal_util_params.h" +#include "interface/vcos/vcos.h" +#include + +#define CHECK_STATUS(status, msg) if (status != MMAL_SUCCESS) { fprintf(stderr, msg"\n"); goto error; } + +static uint8_t codec_header_bytes[512]; +static unsigned int codec_header_bytes_size = sizeof(codec_header_bytes); + +static FILE *source_file; + +/* Macros abstracting the I/O, just to make the example code clearer */ +#define SOURCE_OPEN(uri) \ + source_file = fopen(uri, "rb"); if (!source_file) goto error; +#define SOURCE_READ_CODEC_CONFIG_DATA(bytes, size) \ + size = fread(bytes, 1, size, source_file); rewind(source_file) +#define SOURCE_READ_DATA_INTO_BUFFER(a) \ + a->length = fread(a->data, 1, a->alloc_size - 128, source_file); \ + a->offset = 0 +#define SOURCE_CLOSE() \ + if (source_file) fclose(source_file) + +/** Context for our application */ +static struct CONTEXT_T { + VCOS_SEMAPHORE_T semaphore; + MMAL_QUEUE_T *queue; + MMAL_STATUS_T status; +} context; + +/** Callback from the control port. + * Component is sending us an event. */ +static void control_callback(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) +{ + struct CONTEXT_T *ctx = (struct CONTEXT_T *)port->userdata; + + switch (buffer->cmd) + { + case MMAL_EVENT_EOS: + /* Only sink component generate EOS events */ + break; + case MMAL_EVENT_ERROR: + /* Something went wrong. Signal this to the application */ + ctx->status = *(MMAL_STATUS_T *)buffer->data; + break; + default: + break; + } + + /* Done with the event, recycle it */ + mmal_buffer_header_release(buffer); + + /* Kick the processing thread */ + vcos_semaphore_post(&ctx->semaphore); +} + +/** Callback from the input port. + * Buffer has been consumed and is available to be used again. */ +static void input_callback(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) +{ + struct CONTEXT_T *ctx = (struct CONTEXT_T *)port->userdata; + + /* The decoder is done with the data, just recycle the buffer header into its pool */ + mmal_buffer_header_release(buffer); + + /* Kick the processing thread */ + vcos_semaphore_post(&ctx->semaphore); +} + +/** Callback from the output port. + * Buffer has been produced by the port and is available for processing. */ +static void output_callback(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) +{ + struct CONTEXT_T *ctx = (struct CONTEXT_T *)port->userdata; + + /* Queue the decoded video frame */ + mmal_queue_put(ctx->queue, buffer); + + /* Kick the processing thread */ + vcos_semaphore_post(&ctx->semaphore); +} + +int main(int argc, char **argv) +{ + MMAL_STATUS_T status = MMAL_EINVAL; + MMAL_COMPONENT_T *decoder = 0; + MMAL_POOL_T *pool_in = 0, *pool_out = 0; + MMAL_BOOL_T eos_sent = MMAL_FALSE, eos_received = MMAL_FALSE; + unsigned int count; + + if (argc < 2) + { + fprintf(stderr, "invalid arguments\n"); + return -1; + } + + vcos_semaphore_create(&context.semaphore, "example", 1); + + SOURCE_OPEN(argv[1]); + + /* Create the decoder component. + * This specific component exposes 2 ports (1 input and 1 output). Like most components + * its expects the format of its input port to be set by the client in order for it to + * know what kind of data it will be fed. */ + status = mmal_component_create(MMAL_COMPONENT_DEFAULT_VIDEO_DECODER, &decoder); + CHECK_STATUS(status, "failed to create decoder"); + + /* Enable control port so we can receive events from the component */ + decoder->control->userdata = (void *)&context; + status = mmal_port_enable(decoder->control, control_callback); + CHECK_STATUS(status, "failed to enable control port"); + + /* Get statistics on the input port */ + MMAL_PARAMETER_CORE_STATISTICS_T stats = {{0}}; + stats.hdr.id = MMAL_PARAMETER_CORE_STATISTICS; + stats.hdr.size = sizeof(MMAL_PARAMETER_CORE_STATISTICS_T); + status = mmal_port_parameter_get(decoder->input[0], &stats.hdr); + CHECK_STATUS(status, "failed to get stats"); + fprintf(stderr, "stats: %i, %i", stats.stats.buffer_count, stats.stats.max_delay); + + /* Set the zero-copy parameter on the input port */ + MMAL_PARAMETER_BOOLEAN_T zc = {{MMAL_PARAMETER_ZERO_COPY, sizeof(zc)}, MMAL_TRUE}; + status = mmal_port_parameter_set(decoder->input[0], &zc.hdr); + fprintf(stderr, "status: %i\n", status); + + /* Set the zero-copy parameter on the output port */ + status = mmal_port_parameter_set_boolean(decoder->output[0], MMAL_PARAMETER_ZERO_COPY, MMAL_TRUE); + fprintf(stderr, "status: %i\n", status); + + /* Set format of video decoder input port */ + MMAL_ES_FORMAT_T *format_in = decoder->input[0]->format; + format_in->type = MMAL_ES_TYPE_VIDEO; + format_in->encoding = MMAL_ENCODING_H264; + format_in->es->video.width = 1280; + format_in->es->video.height = 720; + format_in->es->video.frame_rate.num = 30; + format_in->es->video.frame_rate.den = 1; + format_in->es->video.par.num = 1; + format_in->es->video.par.den = 1; + /* If the data is known to be framed then the following flag should be set: + * format_in->flags |= MMAL_ES_FORMAT_FLAG_FRAMED; */ + + SOURCE_READ_CODEC_CONFIG_DATA(codec_header_bytes, codec_header_bytes_size); + status = mmal_format_extradata_alloc(format_in, codec_header_bytes_size); + CHECK_STATUS(status, "failed to allocate extradata"); + format_in->extradata_size = codec_header_bytes_size; + if (format_in->extradata_size) + memcpy(format_in->extradata, codec_header_bytes, format_in->extradata_size); + + status = mmal_port_format_commit(decoder->input[0]); + CHECK_STATUS(status, "failed to commit format"); + + /* Our decoder can do internal colour conversion, ask for a conversion to RGB565 */ + MMAL_ES_FORMAT_T *format_out = decoder->output[0]->format; + format_out->encoding = MMAL_ENCODING_RGB16; + status = mmal_port_format_commit(decoder->output[0]); + CHECK_STATUS(status, "failed to commit format"); + + /* Display the output port format */ + fprintf(stderr, "%s\n", decoder->output[0]->name); + fprintf(stderr, " type: %i, fourcc: %4.4s\n", format_out->type, (char *)&format_out->encoding); + fprintf(stderr, " bitrate: %i, framed: %i\n", format_out->bitrate, + !!(format_out->flags & MMAL_ES_FORMAT_FLAG_FRAMED)); + fprintf(stderr, " extra data: %i, %p\n", format_out->extradata_size, format_out->extradata); + fprintf(stderr, " width: %i, height: %i, (%i,%i,%i,%i)\n", + format_out->es->video.width, format_out->es->video.height, + format_out->es->video.crop.x, format_out->es->video.crop.y, + format_out->es->video.crop.width, format_out->es->video.crop.height); + + /* The format of both ports is now set so we can get their buffer requirements and create + * our buffer headers. We use the buffer pool API to create these. */ + decoder->input[0]->buffer_num = decoder->input[0]->buffer_num_min; + decoder->input[0]->buffer_size = decoder->input[0]->buffer_size_min; + decoder->output[0]->buffer_num = decoder->output[0]->buffer_num_min; + decoder->output[0]->buffer_size = decoder->output[0]->buffer_size_min; + pool_in = mmal_pool_create(decoder->input[0]->buffer_num, + decoder->input[0]->buffer_size); + pool_out = mmal_pool_create(decoder->output[0]->buffer_num, + decoder->output[0]->buffer_size); + + /* Create a queue to store our decoded video frames. The callback we will get when + * a frame has been decoded will put the frame into this queue. */ + context.queue = mmal_queue_create(); + + /* Store a reference to our context in each port (will be used during callbacks) */ + decoder->input[0]->userdata = (void *)&context; + decoder->output[0]->userdata = (void *)&context; + + /* Enable all the input port and the output port. + * The callback specified here is the function which will be called when the buffer header + * we sent to the component has been processed. */ + status = mmal_port_enable(decoder->input[0], input_callback); + CHECK_STATUS(status, "failed to enable input port"); + status = mmal_port_enable(decoder->output[0], output_callback); + CHECK_STATUS(status, "failed to enable output port"); + + /* Component won't start processing data until it is enabled. */ + status = mmal_component_enable(decoder); + CHECK_STATUS(status, "failed to enable component"); + + /* Start decoding */ + fprintf(stderr, "start decoding\n"); + + /* This is the main processing loop */ + for (count = 0; !eos_received && count < 500; count++) + { + MMAL_BUFFER_HEADER_T *buffer; + + /* Wait for buffer headers to be available on either of the decoder ports */ + vcos_semaphore_wait(&context.semaphore); + + /* Check for errors */ + if (context.status != MMAL_SUCCESS) + break; + + /* Send data to decode to the input port of the video decoder */ + if (!eos_sent && (buffer = mmal_queue_get(pool_in->queue)) != NULL) + { + SOURCE_READ_DATA_INTO_BUFFER(buffer); + if(!buffer->length) eos_sent = MMAL_TRUE; + + buffer->flags = buffer->length ? 0 : MMAL_BUFFER_HEADER_FLAG_EOS; + buffer->pts = buffer->dts = MMAL_TIME_UNKNOWN; + fprintf(stderr, "sending %i bytes\n", (int)buffer->length); + status = mmal_port_send_buffer(decoder->input[0], buffer); + CHECK_STATUS(status, "failed to send buffer"); + } + + /* Get our decoded frames */ + while ((buffer = mmal_queue_get(context.queue)) != NULL) + { + /* We have a frame, do something with it (why not display it for instance?). + * Once we're done with it, we release it. It will automatically go back + * to its original pool so it can be reused for a new video frame. + */ + eos_received = buffer->flags & MMAL_BUFFER_HEADER_FLAG_EOS; + + if (buffer->cmd) + fprintf(stderr, "received event %4.4s", (char *)&buffer->cmd); + else + fprintf(stderr, "decoded frame (flags %x)\n", buffer->flags); + mmal_buffer_header_release(buffer); + } + + /* Send empty buffers to the output port of the decoder */ + while ((buffer = mmal_queue_get(pool_out->queue)) != NULL) + { + status = mmal_port_send_buffer(decoder->output[0], buffer); + CHECK_STATUS(status, "failed to send buffer"); + } +} + + /* Stop decoding */ + fprintf(stderr, "stop decoding\n"); + + /* Stop everything. Not strictly necessary since mmal_component_destroy() + * will do that anyway */ + mmal_port_disable(decoder->input[0]); + mmal_port_disable(decoder->output[0]); + mmal_component_disable(decoder); + + error: + /* Cleanup everything */ + if (decoder) + mmal_component_destroy(decoder); + if (pool_in) + mmal_pool_destroy(pool_in); + if (pool_out) + mmal_pool_destroy(pool_out); + if (context.queue) + mmal_queue_destroy(context.queue); + + SOURCE_CLOSE(); + vcos_semaphore_delete(&context.semaphore); + return status == MMAL_SUCCESS ? 0 : -1; +} diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/test/examples/example_connections.c b/external_src/raspicam-0.1.3/dependencies/mmal/test/examples/example_connections.c new file mode 100644 index 0000000..463c11e --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/test/examples/example_connections.c @@ -0,0 +1,192 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 "mmal.h" +#include "util/mmal_connection.h" +#include "util/mmal_default_components.h" +#include "util/mmal_util_params.h" +#include "interface/vcos/vcos.h" +#include + +#define CHECK_STATUS(status, msg) if (status != MMAL_SUCCESS) { fprintf(stderr, msg"\n"); goto error; } + +/** Context for our application */ +static struct CONTEXT_T { + VCOS_SEMAPHORE_T semaphore; + MMAL_STATUS_T status; + MMAL_BOOL_T eos; +} context; + +/** Callback from a control port. Error and EOS events stop playback. */ +static void control_callback(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) +{ + struct CONTEXT_T *ctx = (struct CONTEXT_T *)port->userdata; + + if (buffer->cmd == MMAL_EVENT_ERROR) + ctx->status = *(MMAL_STATUS_T *)buffer->data; + else if (buffer->cmd == MMAL_EVENT_EOS) + ctx->eos = MMAL_TRUE; + + mmal_buffer_header_release(buffer); + + /* The processing is done in our main thread */ + vcos_semaphore_post(&ctx->semaphore); +} + +/** Callback from the connection. Buffer is available. */ +static void connection_callback(MMAL_CONNECTION_T *connection) +{ + struct CONTEXT_T *ctx = (struct CONTEXT_T *)connection->user_data; + + /* The processing is done in our main thread */ + vcos_semaphore_post(&ctx->semaphore); +} + +int main(int argc, char **argv) +{ + MMAL_STATUS_T status; + MMAL_COMPONENT_T *reader = 0, *decoder = 0, *renderer = 0; + MMAL_CONNECTION_T *connection[2] = {0}; + unsigned int i, count, connection_num = vcos_countof(connection); + + if (argc < 2) + { + fprintf(stderr, "invalid arguments\n"); + return -1; + } + + vcos_semaphore_create(&context.semaphore, "example", 1); + + /* Create the components */ + status = mmal_component_create(MMAL_COMPONENT_DEFAULT_CONTAINER_READER, &reader); + CHECK_STATUS(status, "failed to create reader"); + reader->control->userdata = (void *)&context; + status = mmal_port_enable(reader->control, control_callback); + CHECK_STATUS(status, "failed to enable control port"); + status = mmal_component_enable(reader); + CHECK_STATUS(status, "failed to enable component"); + + status = mmal_component_create(MMAL_COMPONENT_DEFAULT_VIDEO_DECODER, &decoder); + CHECK_STATUS(status, "failed to create decoder"); + decoder->control->userdata = (void *)&context; + status = mmal_port_enable(decoder->control, control_callback); + CHECK_STATUS(status, "failed to enable control port"); + status = mmal_component_enable(decoder); + CHECK_STATUS(status, "failed to enable component"); + + status = mmal_component_create(MMAL_COMPONENT_DEFAULT_VIDEO_RENDERER, &renderer); + CHECK_STATUS(status, "failed to create renderer"); + renderer->control->userdata = (void *)&context; + status = mmal_port_enable(renderer->control, control_callback); + CHECK_STATUS(status, "failed to enable control port"); + status = mmal_component_enable(renderer); + CHECK_STATUS(status, "failed to enable component"); + + /* Configure the reader using the given URI */ + status = mmal_util_port_set_uri(reader->control, argv[1]); + CHECK_STATUS(status, "failed to set uri"); + + /* Create the connections between the components */ + status = mmal_connection_create(&connection[0], reader->output[0], decoder->input[0], 0); + CHECK_STATUS(status, "failed to create connection between reader / decoder"); + connection[0]->user_data = &context; + connection[0]->callback = connection_callback; + status = mmal_connection_create(&connection[1], decoder->output[0], renderer->input[0], 0); + CHECK_STATUS(status, "failed to create connection between decoder / renderer"); + connection[1]->user_data = &context; + connection[1]->callback = connection_callback; + + /* Enable all our connections */ + for (i = connection_num; i; i--) + { + status = mmal_connection_enable(connection[i-1]); + CHECK_STATUS(status, "failed to enable connection"); + } + + /* Start playback */ + fprintf(stderr, "start playback\n"); + + /* This is the main processing loop */ + for (count = 0; count < 500; count++) + { + MMAL_BUFFER_HEADER_T *buffer; + vcos_semaphore_wait(&context.semaphore); + + /* Check for errors */ + status = context.status; + CHECK_STATUS(status, "error during playback"); + + /* Check for end of stream */ + if (context.eos) + break; + + /* Handle buffers for all our connections */ + for (i = 0; i < connection_num; i++) + { + if (connection[i]->flags & MMAL_CONNECTION_FLAG_TUNNELLING) + continue; /* Nothing else to do in tunnelling mode */ + + /* Send empty buffers to the output port of the connection */ + while ((buffer = mmal_queue_get(connection[i]->pool->queue)) != NULL) + { + status = mmal_port_send_buffer(connection[i]->out, buffer); + CHECK_STATUS(status, "failed to send buffer"); + } + + /* Send any queued buffer to the next component */ + while ((buffer = mmal_queue_get(connection[i]->queue)) != NULL) + { + status = mmal_port_send_buffer(connection[i]->in, buffer); + CHECK_STATUS(status, "failed to send buffer"); + } + } + } + + /* Stop everything */ + fprintf(stderr, "stop playback\n"); + for (i = 0; i < connection_num; i++) + { + mmal_connection_disable(connection[i]); + } + + error: + /* Cleanup everything */ + for (i = 0; i < connection_num; i++) + { + if (connection[i]) + mmal_connection_destroy(connection[i]); + } + if (reader) + mmal_component_destroy(reader); + if (decoder) + mmal_component_destroy(decoder); + if (renderer) + mmal_component_destroy(renderer); + + vcos_semaphore_delete(&context.semaphore); + return status == MMAL_SUCCESS ? 0 : -1; +} diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/test/examples/example_graph.c b/external_src/raspicam-0.1.3/dependencies/mmal/test/examples/example_graph.c new file mode 100644 index 0000000..eba6838 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/test/examples/example_graph.c @@ -0,0 +1,95 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 "mmal.h" +#include "util/mmal_graph.h" +#include "util/mmal_default_components.h" +#include "util/mmal_util_params.h" +#include + +#define CHECK_STATUS(status, msg) if (status != MMAL_SUCCESS) { fprintf(stderr, msg"\n"); goto error; } + +int main(int argc, char **argv) +{ + MMAL_STATUS_T status; + MMAL_GRAPH_T *graph = 0; + MMAL_COMPONENT_T *reader = 0, *decoder = 0, *renderer = 0; + + if (argc < 2) + { + fprintf(stderr, "invalid arguments\n"); + return -1; + } + + /* Create the graph */ + status = mmal_graph_create(&graph, 0); + CHECK_STATUS(status, "failed to create graph"); + + /* Add the components */ + status = mmal_graph_new_component(graph, MMAL_COMPONENT_DEFAULT_CONTAINER_READER, &reader); + CHECK_STATUS(status, "failed to create reader"); + + status = mmal_graph_new_component(graph, MMAL_COMPONENT_DEFAULT_VIDEO_DECODER, &decoder); + CHECK_STATUS(status, "failed to create decoder"); + + status = mmal_graph_new_component(graph, MMAL_COMPONENT_DEFAULT_VIDEO_RENDERER, &renderer); + CHECK_STATUS(status, "failed to create renderer"); + + /* Configure the reader using the given URI */ + status = mmal_util_port_set_uri(reader->control, argv[1]); + CHECK_STATUS(status, "failed to set uri"); + + /* connect them up - this propagates port settings from outputs to inputs */ + status = mmal_graph_new_connection(graph, reader->output[0], decoder->input[0], 0, NULL); + CHECK_STATUS(status, "failed to connect reader to decoder"); + status = mmal_graph_new_connection(graph, decoder->output[0], renderer->input[0], 0, NULL); + CHECK_STATUS(status, "failed to connect decoder to renderer"); + + /* Start playback */ + fprintf(stderr, "start playback\n"); + status = mmal_graph_enable(graph, NULL, NULL); + CHECK_STATUS(status, "failed to enable graph"); + + sleep(5); + + /* Stop everything */ + fprintf(stderr, "stop playback\n"); + mmal_graph_disable(graph); + + error: + /* Cleanup everything */ + if (reader) + mmal_component_release(reader); + if (decoder) + mmal_component_release(decoder); + if (renderer) + mmal_component_release(renderer); + if (graph) + mmal_graph_destroy(graph); + + return status == MMAL_SUCCESS ? 0 : -1; +} diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/util/CMakeLists.txt b/external_src/raspicam-0.1.3/dependencies/mmal/util/CMakeLists.txt new file mode 100644 index 0000000..b2a6858 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/util/CMakeLists.txt @@ -0,0 +1,28 @@ +add_library (mmal_util ${LIBRARY_TYPE} + mmal_il.c + mmal_util.c + mmal_connection.c + mmal_graph.c + mmal_list.c + mmal_param_convert.c + mmal_util_params.c + mmal_component_wrapper.c + mmal_util_rational.c +) + +target_link_libraries (mmal_util vcos) + +install(TARGETS mmal_util DESTINATION lib) +install(FILES + mmal_component_wrapper.h + mmal_connection.h + mmal_default_components.h + mmal_graph.h + mmal_il.h + mmal_list.h + mmal_param_convert.h + mmal_util.h + mmal_util_params.h + mmal_util_rational.h + DESTINATION include/interface/mmal/util +) diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/util/mmal_component_wrapper.c b/external_src/raspicam-0.1.3/dependencies/mmal/util/mmal_component_wrapper.c new file mode 100644 index 0000000..8548aca --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/util/mmal_component_wrapper.c @@ -0,0 +1,368 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 "mmal.h" +#include "util/mmal_util.h" +#include "util/mmal_component_wrapper.h" +#include "mmal_logging.h" +#include + +typedef struct +{ + MMAL_WRAPPER_T wrapper; /**< Must be the first member! */ + + VCOS_SEMAPHORE_T sema; + +} MMAL_WRAPPER_PRIVATE_T; + +/** Callback from a control port. Error events will be received there. */ +static void mmal_wrapper_control_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) +{ + MMAL_WRAPPER_PRIVATE_T *private = (MMAL_WRAPPER_PRIVATE_T *)port->userdata; + LOG_TRACE("%s(%p),%p,%4.4s", port->name, port, buffer, (char *)&buffer->cmd); + + if (buffer->cmd == MMAL_EVENT_ERROR) + { + private->wrapper.status = *(MMAL_STATUS_T *)buffer->data; + mmal_buffer_header_release(buffer); + + vcos_semaphore_post(&private->sema); + + if (private->wrapper.callback) + private->wrapper.callback(&private->wrapper); + return; + } + + mmal_buffer_header_release(buffer); +} + +/** Callback from an input port. Buffer is released. */ +static void mmal_wrapper_bh_in_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) +{ + MMAL_PARAM_UNUSED(port); + LOG_TRACE("(%s)%p,%p,%p,%i", port->name, port, buffer, buffer->data, (int)buffer->length); + + /* We're done with the buffer, just recycle it */ + mmal_buffer_header_release(buffer); +} + +/** Callback from an output port. Buffer is queued for the next component. */ +static void mmal_wrapper_bh_out_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) +{ + MMAL_WRAPPER_PRIVATE_T *private = (MMAL_WRAPPER_PRIVATE_T *)port->userdata; + LOG_TRACE("(%s)%p,%p,%p,%i", port->name, port, buffer, buffer->data, (int)buffer->length); + + /* Queue the buffer produced by the output port */ + mmal_queue_put(private->wrapper.output_queue[port->index], buffer); + vcos_semaphore_post(&private->sema); + + if (private->wrapper.callback) + private->wrapper.callback(&private->wrapper); +} + +/** Callback from the pool. Buffer is available. */ +static MMAL_BOOL_T mmal_wrapper_bh_release_cb(MMAL_POOL_T *pool, MMAL_BUFFER_HEADER_T *buffer, + void *userdata) +{ + MMAL_WRAPPER_PRIVATE_T *private = (MMAL_WRAPPER_PRIVATE_T *)userdata; + + mmal_queue_put(pool->queue, buffer); + vcos_semaphore_post(&private->sema); + + if (private->wrapper.callback) + private->wrapper.callback(&private->wrapper); + + return 0; +} + +/*****************************************************************************/ +MMAL_STATUS_T mmal_wrapper_destroy(MMAL_WRAPPER_T *wrapper) +{ + MMAL_WRAPPER_PRIVATE_T *private = (MMAL_WRAPPER_PRIVATE_T *)wrapper; + unsigned int i; + + LOG_TRACE("%p, %s", wrapper, wrapper->component->name); + + /* Cleanup resources */ + mmal_component_destroy(wrapper->component); + + for (i = 0; i < wrapper->input_num; i++) + { + if (wrapper->input_pool[i]) + mmal_pool_destroy(wrapper->input_pool[i]); + } + + for (i = 0; i < wrapper->output_num; i++) + { + if (wrapper->output_pool[i]) + mmal_pool_destroy(wrapper->output_pool[i]); + if (wrapper->output_queue[i]) + mmal_queue_destroy(wrapper->output_queue[i]); + } + + vcos_semaphore_delete(&private->sema); + vcos_free(private); + return MMAL_SUCCESS; +} + +/*****************************************************************************/ +MMAL_STATUS_T mmal_wrapper_create(MMAL_WRAPPER_T **ctx, const char *name) +{ + MMAL_STATUS_T status; + MMAL_COMPONENT_T *component; + MMAL_WRAPPER_PRIVATE_T *private; + MMAL_WRAPPER_T *wrapper; + int64_t start_time; + unsigned int i, extra_size; + + LOG_TRACE("wrapper %p, name %s", ctx, name); + + /* Sanity checking */ + if (!ctx || !name) + return MMAL_EINVAL; + + start_time = vcos_getmicrosecs(); + + status = mmal_component_create(name, &component); + if (status != MMAL_SUCCESS) + return status; + + extra_size = (component->input_num + component->output_num) * 2; + private = vcos_calloc(1, sizeof(*private) + extra_size, "mmal wrapper"); + if (!private) + { + mmal_component_destroy(component); + return MMAL_ENOMEM; + } + + if (vcos_semaphore_create(&private->sema, "mmal wrapper", 0) != VCOS_SUCCESS) + { + mmal_component_destroy(component); + vcos_free(private); + return MMAL_ENOMEM; + } + + wrapper = &private->wrapper; + wrapper->component = component; + wrapper->control = component->control; + wrapper->input_num = component->input_num; + wrapper->input = component->input; + wrapper->output_num = component->output_num; + wrapper->output = component->output; + wrapper->input_pool = (MMAL_POOL_T **)&private[1]; + wrapper->output_pool = (MMAL_POOL_T **)&wrapper->input_pool[component->input_num]; + wrapper->output_queue = (MMAL_QUEUE_T **)&wrapper->output_pool[component->output_num]; + + /* Create our pools and queues */ + for (i = 0; i < wrapper->input_num; i++) + { + wrapper->input_pool[i] = mmal_port_pool_create(wrapper->input[i], 0, 0); + if (!wrapper->input_pool[i]) + goto error; + mmal_pool_callback_set(wrapper->input_pool[i], mmal_wrapper_bh_release_cb, (void *)wrapper); + + wrapper->input[i]->userdata = (void *)wrapper; + } + for (i = 0; i < wrapper->output_num; i++) + { + wrapper->output_pool[i] = mmal_port_pool_create(wrapper->output[i], 0, 0); + wrapper->output_queue[i] = mmal_queue_create(); + if (!wrapper->output_pool[i] || !wrapper->output_queue[i]) + goto error; + mmal_pool_callback_set(wrapper->output_pool[i], mmal_wrapper_bh_release_cb, (void *)wrapper); + + wrapper->output[i]->userdata = (void *)wrapper; + } + + /* Setup control port */ + wrapper->control->userdata = (void *)wrapper; + status = mmal_port_enable(wrapper->control, mmal_wrapper_control_cb); + if (status != MMAL_SUCCESS) + goto error; + + wrapper->time_setup = vcos_getmicrosecs() - start_time; + *ctx = wrapper; + return MMAL_SUCCESS; + + error: + mmal_wrapper_destroy(wrapper); + return status == MMAL_SUCCESS ? MMAL_ENOMEM : status; +} + +/*****************************************************************************/ +MMAL_STATUS_T mmal_wrapper_port_enable(MMAL_PORT_T *port, uint32_t flags) +{ + MMAL_WRAPPER_PRIVATE_T *private = (MMAL_WRAPPER_PRIVATE_T *)port->userdata; + MMAL_WRAPPER_T *wrapper = &private->wrapper; + int64_t start_time = vcos_getmicrosecs(); + uint32_t buffer_size; + MMAL_STATUS_T status; + MMAL_POOL_T *pool; + + LOG_TRACE("%p, %s", wrapper, port->name); + + if (port->type != MMAL_PORT_TYPE_INPUT && port->type != MMAL_PORT_TYPE_OUTPUT) + return MMAL_EINVAL; + + if (port->is_enabled) + return MMAL_SUCCESS; + + pool = port->type == MMAL_PORT_TYPE_INPUT ? + wrapper->input_pool[port->index] : wrapper->output_pool[port->index]; + buffer_size = (flags & MMAL_WRAPPER_FLAG_PAYLOAD_ALLOCATE) ? port->buffer_size : 0; + + /* FIXME: we don't support switching between shared and non-shared memory. + * We would need to save the flag and force a pool resize when switching. */ + if (flags & MMAL_WRAPPER_FLAG_PAYLOAD_USE_SHARED_MEMORY) + { + MMAL_PARAMETER_BOOLEAN_T param_zc = + {{MMAL_PARAMETER_ZERO_COPY, sizeof(MMAL_PARAMETER_BOOLEAN_T)}, 1}; + status = mmal_port_parameter_set(port, ¶m_zc.hdr); + if (status != MMAL_SUCCESS && status != MMAL_ENOSYS) + { + LOG_ERROR("failed to set zero copy on %s", port->name); + return status; + } + } + + /* Resize the pool */ + status = mmal_pool_resize(pool, port->buffer_num, buffer_size); + if (status != MMAL_SUCCESS) + { + LOG_ERROR("could not resize pool (%i/%i)", (int)port->buffer_num, (int)buffer_size); + return status; + } + + /* Enable port. The callback specified here is the function which + * will be called when a buffer header comes back to the port. */ + status = mmal_port_enable(port, port->type == MMAL_PORT_TYPE_INPUT ? + mmal_wrapper_bh_in_cb : mmal_wrapper_bh_out_cb); + if (status != MMAL_SUCCESS) + { + LOG_ERROR("could not enable port"); + return status; + } + + wrapper->time_enable += vcos_getmicrosecs() - start_time; + return MMAL_SUCCESS; +} + +/*****************************************************************************/ +MMAL_STATUS_T mmal_wrapper_port_disable(MMAL_PORT_T *port) +{ + MMAL_WRAPPER_PRIVATE_T *private = (MMAL_WRAPPER_PRIVATE_T *)port->userdata; + MMAL_WRAPPER_T *wrapper = &private->wrapper; + int64_t start_time = vcos_getmicrosecs(); + MMAL_STATUS_T status; + + LOG_TRACE("%p, %s", wrapper, port->name); + + if (port->type != MMAL_PORT_TYPE_INPUT && port->type != MMAL_PORT_TYPE_OUTPUT) + return MMAL_EINVAL; + + if (!port->is_enabled) + return MMAL_SUCCESS; + + /* Disable port */ + status = mmal_port_disable(port); + if (status != MMAL_SUCCESS) + { + LOG_ERROR("could not disable port"); + return status; + } + + /* Flush the queue */ + if (port->type == MMAL_PORT_TYPE_OUTPUT) + { + MMAL_POOL_T *pool = wrapper->output_pool[port->index]; + MMAL_QUEUE_T *queue = wrapper->output_queue[port->index]; + MMAL_BUFFER_HEADER_T *buffer; + + while ((buffer = mmal_queue_get(queue)) != NULL) + mmal_buffer_header_release(buffer); + + if ( !vcos_verify(mmal_queue_length(pool->queue) == pool->headers_num) ) + { + LOG_ERROR("coul dnot release all buffers"); + } + } + + wrapper->time_disable = vcos_getmicrosecs() - start_time; + return status; +} + +/** Wait for an empty buffer to be available on a port */ +MMAL_STATUS_T mmal_wrapper_buffer_get_empty(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T **buffer, + uint32_t flags) +{ + MMAL_WRAPPER_PRIVATE_T *private = (MMAL_WRAPPER_PRIVATE_T *)port->userdata; + MMAL_WRAPPER_T *wrapper = &private->wrapper; + MMAL_POOL_T *pool; + + LOG_TRACE("%p, %s", wrapper, port->name); + + if (!buffer || (port->type != MMAL_PORT_TYPE_INPUT && port->type != MMAL_PORT_TYPE_OUTPUT)) + return MMAL_EINVAL; + + pool = port->type == MMAL_PORT_TYPE_INPUT ? + wrapper->input_pool[port->index] : wrapper->output_pool[port->index]; + + while (wrapper->status == MMAL_SUCCESS && + (*buffer = mmal_queue_get(pool->queue)) == NULL) + { + if (!(flags & MMAL_WRAPPER_FLAG_WAIT)) + break; + vcos_semaphore_wait(&private->sema); + } + + return wrapper->status == MMAL_SUCCESS && !*buffer ? MMAL_EAGAIN : wrapper->status; +} + +/** Wait for a full buffer to be available on a port */ +MMAL_STATUS_T mmal_wrapper_buffer_get_full(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T **buffer, + uint32_t flags) +{ + MMAL_WRAPPER_PRIVATE_T *private = (MMAL_WRAPPER_PRIVATE_T *)port->userdata; + MMAL_WRAPPER_T *wrapper = &private->wrapper; + MMAL_QUEUE_T *queue; + + LOG_TRACE("%p, %s", wrapper, port->name); + + if (!buffer || port->type != MMAL_PORT_TYPE_OUTPUT) + return MMAL_EINVAL; + queue = wrapper->output_queue[port->index]; + + while (wrapper->status == MMAL_SUCCESS && + (*buffer = mmal_queue_get(queue)) == NULL) + { + if (!(flags & MMAL_WRAPPER_FLAG_WAIT)) + break; + vcos_semaphore_wait(&private->sema); + } + + return wrapper->status == MMAL_SUCCESS && !*buffer ? MMAL_EAGAIN : wrapper->status; +} diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/util/mmal_component_wrapper.h b/external_src/raspicam-0.1.3/dependencies/mmal/util/mmal_component_wrapper.h new file mode 100644 index 0000000..ce29ae6 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/util/mmal_component_wrapper.h @@ -0,0 +1,157 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 MMAL_WRAPPER_H +#define MMAL_WRAPPER_H + +/** \defgroup MmalComponentWrapper utility + * \ingroup MmalUtilities + * The component wrapper utility functions can be used in place of common sequences + * of calls to the MMAL API in order to control a standalone component. It hides some + * of the complexity in using standalone components behind a fully synchronous + * interface. + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** Forward type definition for a wrapper */ +typedef struct MMAL_WRAPPER_T MMAL_WRAPPER_T; + +/** Definition of the callback used by a wrapper to signal back to the client + * that a buffer header is available either in the pool or in the output queue. + * + * @param wrapper Pointer to the wrapper + */ +typedef void (*MMAL_WRAPPER_CALLBACK_T)(MMAL_WRAPPER_T *wrapper); + +/** Structure describing a wrapper around a component */ +struct MMAL_WRAPPER_T { + + void *user_data; /**< Field reserved for use by the client. */ + MMAL_WRAPPER_CALLBACK_T callback; /**< Callback set by the client. */ + MMAL_COMPONENT_T *component; + MMAL_STATUS_T status; + + MMAL_PORT_T *control; /**< Control port (Read Only). */ + + uint32_t input_num; /**< Number of input ports (Read Only). */ + MMAL_PORT_T **input; /**< Array of input ports (Read Only). */ + MMAL_POOL_T **input_pool; /**< Array of input pools (Read Only). */ + + uint32_t output_num; /**< Number of output ports (Read Only). */ + MMAL_PORT_T **output; /**< Array of output ports (Read Only). */ + MMAL_POOL_T **output_pool; /**< Array of output pools (Read Only). */ + MMAL_QUEUE_T **output_queue; /**< Array of output queues (Read Only). */ + + /* Used for debug / statistics */ + int64_t time_setup; /**< Time in microseconds taken to setup the connection. */ + int64_t time_enable; /**< Time in microseconds taken to enable the connection. */ + int64_t time_disable; /**< Time in microseconds taken to disable the connection. */ + +}; + +/** Create a wrapper around a component. + * The wrapper shall include a pool of buffer headers for each port. The pools will be suitable + * for the current format of its associated port. + * + * @param wrapper The address of a wrapper pointer that will be set to point to the created + * wrapper. + * @param name The name of the component to create. + * @return MMAL_SUCCESS on success. + */ +MMAL_STATUS_T mmal_wrapper_create(MMAL_WRAPPER_T **wrapper, const char *name); + +/** \name MMAL wrapper flags + * \anchor wrapperflags + */ +/* @{ */ +/** The operation should be blocking */ +#define MMAL_WRAPPER_FLAG_WAIT 1 +/** The pool for the port should allocate memory for the payloads */ +#define MMAL_WRAPPER_FLAG_PAYLOAD_ALLOCATE 2 +/** The port will use shared memory payloads */ +#define MMAL_WRAPPER_FLAG_PAYLOAD_USE_SHARED_MEMORY 4 +/* @} */ + +/** Enable a port on a component wrapper. + * + * @param port port to enable + * @param flags used to specify payload allocation flags for the pool + * @return MMAL_SUCCESS on success. + */ +MMAL_STATUS_T mmal_wrapper_port_enable(MMAL_PORT_T *port, uint32_t flags); + +/** Disable a port on a component wrapper. + * + * @param port port to disable + * @return MMAL_SUCCESS on success. + */ +MMAL_STATUS_T mmal_wrapper_port_disable(MMAL_PORT_T *port); + +/** Wait for an empty buffer to be available on a port. + * + * @param port port to get an empty buffer from + * @param buffer points to the retreived buffer on return + * @param flags specify MMAL_WRAPPER_FLAG_WAIT for a blocking operation + * @return MMAL_SUCCESS on success. + */ +MMAL_STATUS_T mmal_wrapper_buffer_get_empty(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T **buffer, uint32_t flags); + +/** Wait for a full buffer to be available on a port. + * + * @param port port to get a full buffer from + * @param buffer points to the retreived buffer on return + * @param flags specify MMAL_WRAPPER_FLAG_WAIT for a blocking operation + * @return MMAL_SUCCESS on success. + */ +MMAL_STATUS_T mmal_wrapper_buffer_get_full(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T **buffer, uint32_t flags); + +/** Cancel any ongoing blocking operation on a component wrapper. + * + * @param wrapper The wrapper on which to cancel operations. + * @return MMAL_SUCCESS on success. + */ +MMAL_STATUS_T mmal_wrapper_cancel(MMAL_WRAPPER_T *wrapper); + +/** Destroy a wrapper. + * Destroys a component wrapper and any resources it owns. + * + * @param wrapper The wrapper to be destroyed. + * @return MMAL_SUCCESS on success. + */ +MMAL_STATUS_T mmal_wrapper_destroy(MMAL_WRAPPER_T *wrapper); + +#ifdef __cplusplus +} +#endif + +/** @} */ + +#endif /* MMAL_WRAPPER_H */ diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/util/mmal_connection.c b/external_src/raspicam-0.1.3/dependencies/mmal/util/mmal_connection.c new file mode 100644 index 0000000..2e88315 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/util/mmal_connection.c @@ -0,0 +1,513 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 "mmal.h" +#include "util/mmal_util.h" +#include "util/mmal_connection.h" +#include "mmal_logging.h" +#include + +#define CONNECTION_NAME_FORMAT "%s:%.2222s:%i/%s:%.2222s:%i" + +typedef struct +{ + MMAL_CONNECTION_T connection; /**< Must be the first member! */ + MMAL_PORT_T *pool_port; /**< Port used to create the pool */ + + /** Reference counting */ + int refcount; + +} MMAL_CONNECTION_PRIVATE_T; + +/** Callback from an input port. Buffer is released. */ +static void mmal_connection_bh_in_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) +{ + MMAL_PARAM_UNUSED(port); + LOG_TRACE("(%s)%p,%p,%p,%i", port->name, port, buffer, buffer->data, (int)buffer->length); + + /* FIXME: Clock ports are bi-directional and a buffer coming from an + * "input" clock port can potentially have valid payload data, in + * which case it should be queued and not released, however this + * callback doesn't have access to the pool queue. */ + if (port->type == MMAL_PORT_TYPE_CLOCK && buffer->length) + { + LOG_ERROR("clock ports not supported"); + } + + /* We're done with the buffer, just recycle it */ + mmal_buffer_header_release(buffer); +} + +/** Callback from an output port. Buffer is queued for the next component. */ +static void mmal_connection_bh_out_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) +{ + MMAL_CONNECTION_T *connection = (MMAL_CONNECTION_T *)port->userdata; + MMAL_PARAM_UNUSED(port); + LOG_TRACE("(%s)%p,%p,%p,%i", port->name, port, buffer, buffer->data, (int)buffer->length); + + /* Queue the buffer produced by the output port */ + mmal_queue_put(connection->queue, buffer); + + if (connection->callback) + connection->callback(connection); +} + +/** Callback from the pool. Buffer is available. */ +static MMAL_BOOL_T mmal_connection_bh_release_cb(MMAL_POOL_T *pool, MMAL_BUFFER_HEADER_T *buffer, + void *userdata) +{ + MMAL_CONNECTION_T *connection = (MMAL_CONNECTION_T *)userdata; + MMAL_PARAM_UNUSED(pool); + + /* Queue the buffer produced by the output port */ + mmal_queue_put(pool->queue, buffer); + + if (connection->callback) + connection->callback(connection); + + return 0; +} + +/*****************************************************************************/ +static MMAL_STATUS_T mmal_connection_destroy_internal(MMAL_CONNECTION_T *connection) +{ + MMAL_STATUS_T status; + + if (connection->is_enabled) + { + status = mmal_connection_disable(connection); + if (status != MMAL_SUCCESS) + return status; + } + + /* Special case for tunnelling */ + if (connection->flags & MMAL_CONNECTION_FLAG_TUNNELLING) + { + status = mmal_port_disconnect(connection->out); + if (status != MMAL_SUCCESS) + LOG_ERROR("connection %s could not be cleared", connection->name); + } + + /* Cleanup resources */ + if (connection->pool) + mmal_pool_destroy(connection->pool); + if (connection->queue) + mmal_queue_destroy(connection->queue); + + vcos_free(connection); + return MMAL_SUCCESS; +} + +/*****************************************************************************/ +MMAL_STATUS_T mmal_connection_destroy(MMAL_CONNECTION_T *connection) +{ + MMAL_CONNECTION_PRIVATE_T *private = (MMAL_CONNECTION_PRIVATE_T *)connection; + + LOG_TRACE("%p, %s", connection, connection->name); + + if (--private->refcount) + { + LOG_DEBUG("delaying destruction of %s (refount %i)", connection->name, + private->refcount); + return MMAL_SUCCESS; + } + + return mmal_connection_destroy_internal(connection); +} + +/*****************************************************************************/ +MMAL_STATUS_T mmal_connection_create(MMAL_CONNECTION_T **cx, + MMAL_PORT_T *out, MMAL_PORT_T *in, uint32_t flags) +{ + MMAL_STATUS_T status = MMAL_ENOMEM; + unsigned int name_size = strlen(out->component->name) + strlen(in->component->name) + sizeof(CONNECTION_NAME_FORMAT); + unsigned int size = sizeof(MMAL_CONNECTION_PRIVATE_T) + name_size; + MMAL_CONNECTION_PRIVATE_T *private; + MMAL_CONNECTION_T *connection; + char *name; + + /* Sanity checking */ + if (!cx) + return MMAL_EINVAL; + + private = vcos_malloc(size, "mmal connection"); + if (!private) + return MMAL_ENOMEM; + memset(private, 0, size); + connection = &private->connection; + private->refcount = 1; + name = (char *)&private[1]; + + vcos_snprintf(name, name_size - 1, CONNECTION_NAME_FORMAT, + out->component->name, + mmal_port_type_to_string(out->type), (int)out->index, + in->component->name, + mmal_port_type_to_string(in->type), (int)in->index); + + LOG_TRACE("out %p, in %p, flags %x, %s", out, in, flags, name); + + connection->out = out; + connection->in = in; + connection->flags = flags; + connection->name = name; + + connection->time_setup = vcos_getmicrosecs(); + + /* Set the format of the input port to match the output one */ + status = mmal_format_full_copy(in->format, out->format); + if (status == MMAL_SUCCESS) + status = mmal_port_format_commit(in); + if (status != MMAL_SUCCESS) + { + LOG_ERROR("format not set on input port"); + goto error; + } + + /* In pass-through mode we need to propagate the buffer requirements of the + * connected input port */ + if (out->capabilities & MMAL_PORT_CAPABILITY_PASSTHROUGH) + { + MMAL_PARAMETER_BUFFER_REQUIREMENTS_T param = + {{MMAL_PARAMETER_BUFFER_REQUIREMENTS, sizeof(MMAL_PARAMETER_BUFFER_REQUIREMENTS_T)}, + in->buffer_num_min, in->buffer_size_min, in->buffer_alignment_min, + in->buffer_num_recommended, in->buffer_size_recommended}; + status = mmal_port_parameter_set(out, ¶m.hdr); + if (status != MMAL_SUCCESS && status != MMAL_ENOSYS) + { + LOG_ERROR("failed to propagate buffer requirements"); + goto error; + } + status = MMAL_SUCCESS; + } + + /* Special case for tunnelling */ + if (connection->flags & MMAL_CONNECTION_FLAG_TUNNELLING) + { + status = mmal_port_connect(out, in); + if (status != MMAL_SUCCESS) + LOG_ERROR("connection could not be made"); + goto done; + } + + /* Create empty pool of buffer headers for now (will be resized later on) */ + private->pool_port = (in->capabilities & MMAL_PORT_CAPABILITY_ALLOCATION) ? in : out; + if (flags & MMAL_CONNECTION_FLAG_ALLOCATION_ON_INPUT) + private->pool_port = in; + if (flags & MMAL_CONNECTION_FLAG_ALLOCATION_ON_OUTPUT) + private->pool_port = out; + connection->pool = mmal_port_pool_create(private->pool_port, 0, 0); + if (!connection->pool) + goto error; + mmal_pool_callback_set(connection->pool, mmal_connection_bh_release_cb, (void *)connection); + + /* Create a queue to store the buffers from the output port */ + connection->queue = mmal_queue_create(); + if (!connection->queue) + goto error; + + done: + out->userdata = (void *)connection; + in->userdata = (void *)connection; + connection->time_setup = vcos_getmicrosecs() - connection->time_setup; + *cx = connection; + return status; + + error: + /* coverity[var_deref_model] mmal_connection_destroy_internal will check connection->pool correctly */ + mmal_connection_destroy_internal(connection); + return status == MMAL_SUCCESS ? MMAL_ENOMEM : status; +} + +/*****************************************************************************/ +void mmal_connection_acquire(MMAL_CONNECTION_T *connection) +{ + MMAL_CONNECTION_PRIVATE_T *private = (MMAL_CONNECTION_PRIVATE_T *)connection; + LOG_TRACE("connection %s(%p), refcount %i", connection->name, connection, + private->refcount); + private->refcount++; +} + +/*****************************************************************************/ +MMAL_STATUS_T mmal_connection_release(MMAL_CONNECTION_T *connection) +{ + MMAL_CONNECTION_PRIVATE_T *private = (MMAL_CONNECTION_PRIVATE_T *)connection; + LOG_TRACE("connection %s(%p), refcount %i", connection->name, connection, + private->refcount); + + if (--private->refcount) + return MMAL_SUCCESS; + + LOG_TRACE("destroying connection %s(%p)", connection->name, connection); + return mmal_connection_destroy_internal(connection); +} + +/*****************************************************************************/ +MMAL_STATUS_T mmal_connection_enable(MMAL_CONNECTION_T *connection) +{ + MMAL_PORT_T *in = connection->in, *out = connection->out; + uint32_t buffer_num, buffer_size; + MMAL_STATUS_T status; + + LOG_TRACE("%p, %s", connection, connection->name); + + if (connection->is_enabled) + return MMAL_SUCCESS; + + connection->time_enable = vcos_getmicrosecs(); + + /* Override the buffer values with the recommended ones (the port probably knows best) */ + if (!(connection->flags & MMAL_CONNECTION_FLAG_KEEP_BUFFER_REQUIREMENTS)) + { + if (out->buffer_num_recommended) + out->buffer_num = out->buffer_num_recommended; + if (out->buffer_size_recommended) + out->buffer_size = out->buffer_size_recommended; + if (in->buffer_num_recommended) + in->buffer_num = in->buffer_num_recommended; + if (in->buffer_size_recommended) + in->buffer_size = in->buffer_size_recommended; + } + + /* Special case for tunnelling */ + if (connection->flags & MMAL_CONNECTION_FLAG_TUNNELLING) + { + /* Enable port. No callback because the port is connected. Other end of the connection + * will be enabled automatically. */ + status = mmal_port_enable(out, NULL); + if (status) + LOG_ERROR("output port couldn't be enabled"); + goto done; + } + + /* Set the buffering properties on both ports */ + buffer_num = MMAL_MAX(out->buffer_num, in->buffer_num); + buffer_size = MMAL_MAX(out->buffer_size, in->buffer_size); + out->buffer_num = in->buffer_num = buffer_num; + out->buffer_size = in->buffer_size = buffer_size; + + /* In pass-through mode there isn't any need to allocate memory */ + if (out->capabilities & MMAL_PORT_CAPABILITY_PASSTHROUGH) + buffer_size = 0; + + /* Resize the output pool */ + status = mmal_pool_resize(connection->pool, buffer_num, buffer_size); + if (status != MMAL_SUCCESS) + { + LOG_ERROR("couldn't resize pool"); + goto done; + } + + /* Enable output port. The callback specified here is the function which + * will be called when an empty buffer header comes back to the port. */ + status = mmal_port_enable(out, mmal_connection_bh_out_cb); + if(status) + { + LOG_ERROR("output port couldn't be enabled"); + goto done; + } + + /* Enable input port. The callback specified here is the function which + * will be called when an empty buffer header comes back to the port. */ + status = mmal_port_enable(in, mmal_connection_bh_in_cb); + if(status) + { + LOG_ERROR("input port couldn't be enabled"); + mmal_port_disable(out); + goto done; + } + + /* Clock ports need buffers to send clock updates, so + * populate both connected clock ports */ + if ((out->type == MMAL_PORT_TYPE_CLOCK) && (in->type == MMAL_PORT_TYPE_CLOCK)) + { + MMAL_BUFFER_HEADER_T *buffer = mmal_queue_get(connection->pool->queue); + while (buffer) + { + mmal_port_send_buffer(out, buffer); + buffer = mmal_queue_get(connection->pool->queue); + if (buffer) + { + mmal_port_send_buffer(in, buffer); + buffer = mmal_queue_get(connection->pool->queue); + } + } + } + + done: + connection->time_enable = vcos_getmicrosecs() - connection->time_enable; + connection->is_enabled = status == MMAL_SUCCESS; + return status; +} + +/*****************************************************************************/ +MMAL_STATUS_T mmal_connection_disable(MMAL_CONNECTION_T *connection) +{ + MMAL_STATUS_T status; + MMAL_BUFFER_HEADER_T *buffer; + + LOG_TRACE("%p, %s", connection, connection->name); + + if (!connection->is_enabled) + return MMAL_SUCCESS; + + connection->time_disable = vcos_getmicrosecs(); + + /* Special case for tunnelling */ + if (connection->flags & MMAL_CONNECTION_FLAG_TUNNELLING) + { + /* Disable port. Other end of the connection will be disabled automatically. */ + status = mmal_port_disable(connection->out); + if (status) + LOG_ERROR("output port couldn't be disabled"); + goto done; + } + + /* Disable input port. */ + status = mmal_port_disable(connection->in); + if(status) + { + LOG_ERROR("input port couldn't be disabled"); + goto done; + } + + /* Disable output port */ + status = mmal_port_disable(connection->out); + if(status) + { + LOG_ERROR("output port couldn't be disabled"); + goto done; + } + + /* Flush the queue */ + buffer = mmal_queue_get(connection->queue); + while (buffer) + { + mmal_buffer_header_release(buffer); + buffer = mmal_queue_get(connection->queue); + } + vcos_assert(mmal_queue_length(connection->pool->queue) == connection->pool->headers_num); + + done: + connection->time_disable = vcos_getmicrosecs() - connection->time_disable; + connection->is_enabled = !(status == MMAL_SUCCESS); + return status; +} + +/*****************************************************************************/ +static MMAL_STATUS_T mmal_connection_reconfigure(MMAL_CONNECTION_T *connection, MMAL_ES_FORMAT_T *format) +{ + MMAL_STATUS_T status; + LOG_TRACE("%p, %s", connection, connection->name); + + status = mmal_connection_disable(connection); + if (status != MMAL_SUCCESS) + { + LOG_ERROR("connection couldn't be disabled"); + return status; + } + + /* Set the new format for the output port */ + status = mmal_format_full_copy(connection->out->format, format); + if (status == MMAL_SUCCESS) + status = mmal_port_format_commit(connection->out); + if (status != MMAL_SUCCESS) + { + LOG_ERROR("commit failed on port %s(%p) (%i)", + connection->out->name, connection->out, status); + return status; + } + + /* Set the new format for the input port */ + status = mmal_format_full_copy(connection->in->format, connection->out->format); + if (status == MMAL_SUCCESS) + status = mmal_port_format_commit(connection->in); + if (status != MMAL_SUCCESS) + { + LOG_ERROR("commit failed on port %s(%p) (%i)", + connection->in->name, connection->in, status); + return status; + } + + /* Enable ports */ + status = mmal_connection_enable(connection); + if (status) + { + LOG_ERROR("connection couldn't be enabled"); + return status; + } + + return MMAL_SUCCESS; +} + +/*****************************************************************************/ +MMAL_STATUS_T mmal_connection_event_format_changed(MMAL_CONNECTION_T *connection, + MMAL_BUFFER_HEADER_T *buffer) +{ + MMAL_EVENT_FORMAT_CHANGED_T *event; + MMAL_STATUS_T status; + + LOG_TRACE("%p, %s", connection, connection->name); + + if (buffer->cmd != MMAL_EVENT_FORMAT_CHANGED) + return MMAL_EINVAL; + + event = mmal_event_format_changed_get(buffer); + if (!event) + return MMAL_EINVAL; + + /* If we don't need to recreate our buffers then we can just forward the event + * to the next component (so it gets configured properly) */ + if ((connection->in->capabilities & MMAL_PORT_CAPABILITY_SUPPORTS_EVENT_FORMAT_CHANGE) && + event->buffer_size_min <= connection->out->buffer_size && + event->buffer_num_min <= connection->out->buffer_num) + { + status = mmal_format_full_copy(connection->out->format, event->format); + if (status == MMAL_SUCCESS) + status = mmal_port_format_commit(connection->out); + if (status != MMAL_SUCCESS) + { + LOG_ERROR("format commit failed on port %s(%p) (%i)", + connection->out->name, connection->out, status); + return status; + } + + mmal_buffer_header_acquire(buffer); + status = mmal_port_send_buffer(connection->in, buffer); + if (status != MMAL_SUCCESS) + { + LOG_ERROR("buffer send failed on port %s(%p) (%i)", + connection->in->name, connection->in, status); + mmal_buffer_header_release(buffer); + return status; + } + + return MMAL_SUCCESS; + } + + /* Otherwise we have to reconfigure our pipeline */ + return mmal_connection_reconfigure(connection, event->format); +} diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/util/mmal_connection.h b/external_src/raspicam-0.1.3/dependencies/mmal/util/mmal_connection.h new file mode 100644 index 0000000..d2a02b1 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/util/mmal_connection.h @@ -0,0 +1,230 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 MMAL_CONNECTION_H +#define MMAL_CONNECTION_H + +/** \defgroup MmalConnectionUtility Port connection utility + * \ingroup MmalUtilities + * The port connection utility functions can be used in place of common sequences + * of calls to the MMAL API in order to process buffers being passed between two + * ports. + * + * \section ProcessingConnectionBufferHeaders Processing connection buffer headers + * Either in response to the client callback function being called, or simply on a + * timer, the client will need to process the buffer headers of the connection + * (unless tunneling is used). + * + * Buffer headers that are in the pool queue will need to be sent to the output port, + * while buffer headers in the connection queue are sent to the input port. The + * buffer headers in the connection queue may contain pixel data (the cmd field is + * zero) or an event (the cmd field is non-zero). In general, pixel data buffer + * headers need to be passed on, while event buffer headers are released. In the + * case of the format changed event, mmal_connection_event_format_changed() can be + * called before the event is released. + * + * Other, specialized use cases may also be implemented, such as getting and + * immediately releasing buffer headers from the connection queue in order to + * prevent their propagation. This could be used to drop out video, for example. + * + * \section TunnellingConnections Tunnelling connections + * If the \ref MMAL_CONNECTION_FLAG_TUNNELLING flag is set when the connection is + * created, MMAL tunneling will be used. This automates the passing of the buffer + * headers between the output port and input port, and back again. It will also do + * this as efficiently as possible, avoiding trips between the ARM and the VideoCore + * if both components are implemented on the VideoCore. The consequence of this is + * that there is no client callback made as buffer headers get transferred. + * + * The client can still monitor the control port of a component (usually a sink + * component, such as video_render) for the end of stream, in order to know when to + * dismantle the connection. + * + * \section ConnectionClientCallback Client callback + * When not using tunnelling, the client callback function is called each time a + * buffer arrives from a port (either input or output). + * + * \note The callback is made on a different thread from the one used by the + * client to set up the connection, so care must be taken with thread safety. + * One option is to raise a signal to the main client thread that queue processing + * needs to be done, another is for the callback to perform the queue processing + * itself. + * + * The client can also store an opaque pointer in the connection object, which is + * never used by the MMAL code and is only meaningful to the client. + * + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** \name Connection flags + * \anchor connectionflags + * The following flags describe the properties of the connection. */ +/* @{ */ +/** The connection is tunnelled. Buffer headers do not transit via the client but + * directly from the output port to the input port. */ +#define MMAL_CONNECTION_FLAG_TUNNELLING 0x1 +/** Force the pool of buffer headers used by the connection to be allocated on the input port. */ +#define MMAL_CONNECTION_FLAG_ALLOCATION_ON_INPUT 0x2 +/** Force the pool of buffer headers used by the connection to be allocated on the output port. */ +#define MMAL_CONNECTION_FLAG_ALLOCATION_ON_OUTPUT 0x4 +/** Specify that the connection should not modify the buffer requirements. */ +#define MMAL_CONNECTION_FLAG_KEEP_BUFFER_REQUIREMENTS 0x8 +/** The connection is flagged as direct. This doesn't change the behaviour of + * the connection itself but is used by the the graph utility to specify that + * the buffer should be sent to the input port from with the port callback. */ +#define MMAL_CONNECTION_FLAG_DIRECT 0x10 +/* @} */ + +/** Forward type definition for a connection */ +typedef struct MMAL_CONNECTION_T MMAL_CONNECTION_T; + +/** Definition of the callback used by a connection to signal back to the client + * that a buffer header is available either in the pool or in the output queue. + * + * @param connection Pointer to the connection + */ +typedef void (*MMAL_CONNECTION_CALLBACK_T)(MMAL_CONNECTION_T *connection); + +/** Structure describing a connection between 2 ports (1 output and 1 input port) */ +struct MMAL_CONNECTION_T { + + void *user_data; /**< Field reserved for use by the client. */ + MMAL_CONNECTION_CALLBACK_T callback; /**< Callback set by the client. */ + + uint32_t is_enabled; /**< Specifies whether the connection is enabled or not (Read Only). */ + + uint32_t flags; /**< Flags passed during the create call (Read Only). A bitwise + * combination of \ref connectionflags "Connection flags" values. + */ + MMAL_PORT_T *in; /**< Input port used for the connection (Read Only). */ + MMAL_PORT_T *out; /**< Output port used for the connection (Read Only). */ + + MMAL_POOL_T *pool; /**< Pool of buffer headers used by the output port (Read Only). */ + MMAL_QUEUE_T *queue; /**< Queue for the buffer headers produced by the output port (Read Only). */ + + const char *name; /**< Connection name (Read Only). Used for debugging purposes. */ + + /* Used for debug / statistics */ + int64_t time_setup; /**< Time in microseconds taken to setup the connection. */ + int64_t time_enable; /**< Time in microseconds taken to enable the connection. */ + int64_t time_disable; /**< Time in microseconds taken to disable the connection. */ +}; + +/** 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); + +/** 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); + +/** 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); + +/** 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); + +/** 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); + +/** 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); + +/** 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); + +#ifdef __cplusplus +} +#endif + +/** @} */ + +#endif /* MMAL_CONNECTION_H */ diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/util/mmal_default_components.h b/external_src/raspicam-0.1.3/dependencies/mmal/util/mmal_default_components.h new file mode 100644 index 0000000..ddfd69d --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/util/mmal_default_components.h @@ -0,0 +1,90 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 MMAL_DEFAULT_COMPONENTS_H +#define MMAL_DEFAULT_COMPONENTS_H + +/** \defgroup MmalDefaultComponents List of default components + * This provides a list of default components on a per platform basis. + * @{ + */ + +#define MMAL_COMPONENT_DEFAULT_CONTAINER_READER "container_reader" +#define MMAL_COMPONENT_DEFAULT_CONTAINER_WRITER "container_writer" + +#if defined(ENABLE_MMAL_STANDALONE) +# define MMAL_COMPONENT_DEFAULT_VIDEO_DECODER "avcodec.video_decode" +# define MMAL_COMPONENT_DEFAULT_VIDEO_ENCODER "avcodec.video_encode" +# define MMAL_COMPONENT_DEFAULT_VIDEO_RENDERER "sdl.video_render" +# define MMAL_COMPONENT_DEFAULT_IMAGE_DECODER "avcodec.video_decode" +# define MMAL_COMPONENT_DEFAULT_IMAGE_ENCODER "avcodec.video_encode" +# define MMAL_COMPONENT_DEFAULT_CAMERA "artificial_camera" +# define MMAL_COMPONENT_DEFAULT_VIDEO_CONVERTER "avcodec.video_convert" +# define MMAL_COMPONENT_DEFAULT_SPLITTER "splitter" +# define MMAL_COMPONENT_DEFAULT_SCHEDULER "scheduler" +# define MMAL_COMPONENT_DEFAULT_VIDEO_INJECTER "video_inject" +# define MMAL_COMPONENT_DEFAULT_AUDIO_DECODER "avcodec.audio_decode" +# define MMAL_COMPONENT_DEFAULT_AUDIO_RENDERER "sdl.audio_render" +# define MMAL_COMPONENT_DEFAULT_MIRACAST "miracast" +# define MMAL_COMPONENT_DEFAULT_CLOCK "clock" +#elif defined(__VIDEOCORE__) +# define MMAL_COMPONENT_DEFAULT_VIDEO_DECODER "ril.video_decode" +# define MMAL_COMPONENT_DEFAULT_VIDEO_ENCODER "ril.video_encode" +# define MMAL_COMPONENT_DEFAULT_VIDEO_RENDERER "ril.video_render" +# define MMAL_COMPONENT_DEFAULT_IMAGE_DECODER "ril.image_decode" +# define MMAL_COMPONENT_DEFAULT_IMAGE_ENCODER "ril.image_encode" +# define MMAL_COMPONENT_DEFAULT_CAMERA "ril.camera" +# define MMAL_COMPONENT_DEFAULT_VIDEO_CONVERTER "video_convert" +# define MMAL_COMPONENT_DEFAULT_SPLITTER "splitter" +# define MMAL_COMPONENT_DEFAULT_SCHEDULER "scheduler" +# define MMAL_COMPONENT_DEFAULT_VIDEO_INJECTER "video_inject" +# define MMAL_COMPONENT_DEFAULT_VIDEO_SPLITTER "ril.video_splitter" +# define MMAL_COMPONENT_DEFAULT_AUDIO_DECODER "none" +# define MMAL_COMPONENT_DEFAULT_AUDIO_RENDERER "ril.audio_render" +# define MMAL_COMPONENT_DEFAULT_MIRACAST "miracast" +# define MMAL_COMPONENT_DEFAULT_CLOCK "clock" +#else +# define MMAL_COMPONENT_DEFAULT_VIDEO_DECODER "vc.ril.video_decode" +# define MMAL_COMPONENT_DEFAULT_VIDEO_ENCODER "vc.ril.video_encode" +# define MMAL_COMPONENT_DEFAULT_VIDEO_RENDERER "vc.ril.video_render" +# define MMAL_COMPONENT_DEFAULT_IMAGE_DECODER "vc.ril.image_decode" +# define MMAL_COMPONENT_DEFAULT_IMAGE_ENCODER "vc.ril.image_encode" +# define MMAL_COMPONENT_DEFAULT_CAMERA "vc.ril.camera" +# define MMAL_COMPONENT_DEFAULT_VIDEO_CONVERTER "vc.video_convert" +# define MMAL_COMPONENT_DEFAULT_SPLITTER "vc.splitter" +# define MMAL_COMPONENT_DEFAULT_SCHEDULER "vc.scheduler" +# define MMAL_COMPONENT_DEFAULT_VIDEO_INJECTER "vc.video_inject" +# define MMAL_COMPONENT_DEFAULT_VIDEO_SPLITTER "vc.ril.video_splitter" +# define MMAL_COMPONENT_DEFAULT_AUDIO_DECODER "none" +# define MMAL_COMPONENT_DEFAULT_AUDIO_RENDERER "vc.ril.audio_render" +# define MMAL_COMPONENT_DEFAULT_MIRACAST "vc.miracast" +# define MMAL_COMPONENT_DEFAULT_CLOCK "vc.clock" +#endif + +/** @} */ + +#endif /* MMAL_DEFAULT_COMPONENTS_H */ diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/util/mmal_graph.c b/external_src/raspicam-0.1.3/dependencies/mmal/util/mmal_graph.c new file mode 100644 index 0000000..b84d575 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/util/mmal_graph.c @@ -0,0 +1,1479 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 "mmal.h" +#include "util/mmal_util.h" +#include "util/mmal_graph.h" +#include "core/mmal_component_private.h" +#include "core/mmal_port_private.h" +#include "mmal_logging.h" + +#define GRAPH_CONNECTIONS_MAX 16 +#define PROCESSING_TIME_MAX 20000 + +/*****************************************************************************/ + +/** Private context for our graph. + * This also acts as a MMAL_COMPONENT_MODULE_T for when components are instantiated from graphs */ +typedef struct MMAL_COMPONENT_MODULE_T +{ + MMAL_GRAPH_T graph; /**< Must be the first member! */ + + MMAL_COMPONENT_T *component[GRAPH_CONNECTIONS_MAX]; + MMAL_GRAPH_TOPOLOGY_T topology[GRAPH_CONNECTIONS_MAX]; + unsigned int component_num; + + MMAL_CONNECTION_T *connection[GRAPH_CONNECTIONS_MAX]; + unsigned int connection_num; + unsigned int connection_current; + + MMAL_PORT_T *input[GRAPH_CONNECTIONS_MAX]; + unsigned int input_num; + MMAL_PORT_T *output[GRAPH_CONNECTIONS_MAX]; + unsigned int output_num; + + MMAL_COMPONENT_T *graph_component; + + MMAL_BOOL_T stop_thread; /**< informs the worker thread to exit */ + VCOS_THREAD_T thread; /**< worker thread which processes all internal connections */ + VCOS_SEMAPHORE_T sema; /**< informs the worker thread that buffers are available */ + + MMAL_GRAPH_EVENT_CB event_cb; /**< callback for sending control port events to the client */ + void *event_cb_data; /**< callback data supplied by the client */ + +} MMAL_GRAPH_PRIVATE_T; + +typedef MMAL_GRAPH_PRIVATE_T MMAL_COMPONENT_MODULE_T; + +/*****************************************************************************/ +static MMAL_STATUS_T mmal_component_create_from_graph(const char *name, MMAL_COMPONENT_T *component); +static MMAL_BOOL_T graph_do_processing(MMAL_GRAPH_PRIVATE_T *graph); +static void graph_process_buffer(MMAL_GRAPH_PRIVATE_T *graph_private, + MMAL_CONNECTION_T *connection, MMAL_BUFFER_HEADER_T *buffer); + +/*****************************************************************************/ +static void graph_control_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) +{ + MMAL_GRAPH_PRIVATE_T *graph = (MMAL_GRAPH_PRIVATE_T *)port->userdata; + + LOG_TRACE("port: %s(%p), buffer: %p, event: %4.4s", port->name, port, + buffer, (char *)&buffer->cmd); + + if (graph->event_cb) + { + graph->event_cb((MMAL_GRAPH_T *)graph, port, buffer, graph->event_cb_data); + } + else + { + LOG_ERROR("event lost on port %i,%i (event callback not defined)", + (int)port->type, (int)port->index); + mmal_buffer_header_release(buffer); + } +} + +/*****************************************************************************/ +static void graph_connection_cb(MMAL_CONNECTION_T *connection) +{ + MMAL_GRAPH_PRIVATE_T *graph = (MMAL_GRAPH_PRIVATE_T *)connection->user_data; + MMAL_BUFFER_HEADER_T *buffer; + + if (connection->flags == MMAL_CONNECTION_FLAG_DIRECT && + (buffer = mmal_queue_get(connection->queue)) != NULL) + { + graph_process_buffer(graph, connection, buffer); + return; + } + + vcos_semaphore_post(&graph->sema); +} + +/*****************************************************************************/ +static void* graph_worker_thread(void* ctx) +{ + MMAL_GRAPH_PRIVATE_T *graph = (MMAL_GRAPH_PRIVATE_T *)ctx; + + while (1) + { + vcos_semaphore_wait(&graph->sema); + if (graph->stop_thread) + break; + while(graph_do_processing(graph)); + } + + LOG_TRACE("worker thread exit %p", graph); + + return 0; +} + +/*****************************************************************************/ +static void graph_stop_worker_thread(MMAL_GRAPH_PRIVATE_T *graph) +{ + graph->stop_thread = MMAL_TRUE; + vcos_semaphore_post(&graph->sema); + vcos_thread_join(&graph->thread, NULL); +} + +/*****************************************************************************/ +MMAL_STATUS_T mmal_graph_create(MMAL_GRAPH_T **graph, unsigned int userdata_size) +{ + MMAL_GRAPH_PRIVATE_T *private; + + LOG_TRACE("graph %p, userdata_size %u", graph, userdata_size); + + /* Sanity checking */ + if (!graph) + return MMAL_EINVAL; + + private = vcos_calloc(1, sizeof(MMAL_GRAPH_PRIVATE_T) + userdata_size, "mmal connection graph"); + if (!private) + return MMAL_ENOMEM; + *graph = &private->graph; + if (userdata_size) + (*graph)->userdata = (struct MMAL_GRAPH_USERDATA_T *)&private[1]; + + if (vcos_semaphore_create(&private->sema, "mmal graph sema", 0) != VCOS_SUCCESS) + { + LOG_ERROR("failed to create semaphore %p", graph); + vcos_free(private); + return MMAL_ENOSPC; + } + + return MMAL_SUCCESS; +} + +/*****************************************************************************/ +MMAL_STATUS_T mmal_graph_destroy(MMAL_GRAPH_T *graph) +{ + unsigned i; + MMAL_GRAPH_PRIVATE_T *private = (MMAL_GRAPH_PRIVATE_T *)graph; + + if (!graph) + return MMAL_EINVAL; + + LOG_TRACE("%p", graph); + + /* Notify client of destruction */ + if (graph->pf_destroy) + graph->pf_destroy(graph); + + for (i = 0; i < private->connection_num; i++) + mmal_connection_release(private->connection[i]); + + for (i = 0; i < private->component_num; i++) + mmal_component_release(private->component[i]); + + vcos_semaphore_delete(&private->sema); + + vcos_free(graph); + return MMAL_SUCCESS; +} + +/*****************************************************************************/ +MMAL_STATUS_T mmal_graph_add_component(MMAL_GRAPH_T *graph, MMAL_COMPONENT_T *component) +{ + MMAL_GRAPH_PRIVATE_T *private = (MMAL_GRAPH_PRIVATE_T *)graph; + + LOG_TRACE("graph: %p, component: %s(%p)", graph, component ? component->name: 0, component); + + if (!component) + return MMAL_EINVAL; + + if (private->component_num >= GRAPH_CONNECTIONS_MAX) + { + LOG_ERROR("no space for component %s", component->name); + return MMAL_ENOSPC; + } + + mmal_component_acquire(component); + private->component[private->component_num++] = component; + + return MMAL_SUCCESS; +} + +/*****************************************************************************/ +MMAL_STATUS_T mmal_graph_component_topology(MMAL_GRAPH_T *graph, MMAL_COMPONENT_T *component, + MMAL_GRAPH_TOPOLOGY_T topology, int8_t *input, unsigned int input_num, + int8_t *output, unsigned int output_num) +{ + MMAL_GRAPH_PRIVATE_T *private = (MMAL_GRAPH_PRIVATE_T *)graph; + MMAL_PARAM_UNUSED(input); MMAL_PARAM_UNUSED(input_num); + MMAL_PARAM_UNUSED(output); MMAL_PARAM_UNUSED(output_num); + unsigned int i; + + LOG_TRACE("graph: %p, component: %s(%p)", graph, component ? component->name: 0, component); + + if (!component) + return MMAL_EINVAL; + + for (i = 0; i < private->component_num; i++) + if (component == private->component[i]) + break; + + if (i == private->component_num) + return MMAL_EINVAL; /* Component not found */ + + if (topology > MMAL_GRAPH_TOPOLOGY_STRAIGHT) + return MMAL_ENOSYS; /* Currently not supported */ + + private->topology[i] = topology; + + return MMAL_SUCCESS; +} + +/*****************************************************************************/ +MMAL_STATUS_T mmal_graph_add_connection(MMAL_GRAPH_T *graph, MMAL_CONNECTION_T *cx) +{ + MMAL_GRAPH_PRIVATE_T *private = (MMAL_GRAPH_PRIVATE_T *)graph; + + LOG_TRACE("graph: %p, connection: %s(%p)", graph, cx ? cx->name: 0, cx); + + if (!cx) + return MMAL_EINVAL; + + if (private->connection_num >= GRAPH_CONNECTIONS_MAX) + { + LOG_ERROR("no space for connection %s", cx->name); + return MMAL_ENOSPC; + } + + mmal_connection_acquire(cx); + private->connection[private->connection_num++] = cx; + return MMAL_SUCCESS; +} + +/*****************************************************************************/ +MMAL_STATUS_T mmal_graph_add_port(MMAL_GRAPH_T *graph, MMAL_PORT_T *port) +{ + MMAL_GRAPH_PRIVATE_T *private = (MMAL_GRAPH_PRIVATE_T *)graph; + MMAL_PORT_T **list; + unsigned int *list_num; + + LOG_TRACE("graph: %p, port: %s(%p)", graph, port ? port->name: 0, port); + + if (!port || (port->type != MMAL_PORT_TYPE_INPUT && port->type != MMAL_PORT_TYPE_OUTPUT)) + return MMAL_EINVAL; + + list = port->type == MMAL_PORT_TYPE_INPUT ? private->input : private->output; + list_num = port->type == MMAL_PORT_TYPE_INPUT ? &private->input_num : &private->output_num; + if (*list_num >= GRAPH_CONNECTIONS_MAX) + { + LOG_ERROR("no space for port %s", port->name); + return MMAL_ENOSPC; + } + + list[(*list_num)++] = port; + return MMAL_SUCCESS; +} + +/*****************************************************************************/ +MMAL_STATUS_T mmal_graph_new_component(MMAL_GRAPH_T *graph, const char *name, + MMAL_COMPONENT_T **component) +{ + MMAL_GRAPH_PRIVATE_T *private = (MMAL_GRAPH_PRIVATE_T *)graph; + MMAL_COMPONENT_T *comp; + MMAL_STATUS_T status; + + LOG_TRACE("graph: %p, name: %s, component: %p", graph, name, component); + + if (private->component_num >= GRAPH_CONNECTIONS_MAX) + { + LOG_ERROR("no space for component %s", name); + return MMAL_ENOSPC; + } + + status = mmal_component_create(name, &comp); + if (status != MMAL_SUCCESS) + { + LOG_ERROR("could not create component %s (%i)", name, status); + return status; + } + + private->component[private->component_num++] = comp; + if (component) + { + mmal_component_acquire(comp); + *component = comp; + } + + return MMAL_SUCCESS; +} + +/*****************************************************************************/ +MMAL_STATUS_T mmal_graph_new_connection(MMAL_GRAPH_T *graph, MMAL_PORT_T *out, MMAL_PORT_T *in, + uint32_t flags, MMAL_CONNECTION_T **connection) +{ + MMAL_GRAPH_PRIVATE_T *private = (MMAL_GRAPH_PRIVATE_T *)graph; + MMAL_CONNECTION_T *cx; + MMAL_STATUS_T status; + + if (!out || !in) + return MMAL_EINVAL; + if (out->type == MMAL_PORT_TYPE_CLOCK && in->type != MMAL_PORT_TYPE_CLOCK) + return MMAL_EINVAL; + if (out->type != MMAL_PORT_TYPE_CLOCK && + (out->type != MMAL_PORT_TYPE_OUTPUT || in->type != MMAL_PORT_TYPE_INPUT)) + return MMAL_EINVAL; + + LOG_TRACE("graph: %p, out: %s(%p), in: %s(%p), flags %x, connection: %p", + graph, out->name, out, in->name, in, (int)flags, connection); + + if (private->connection_num >= GRAPH_CONNECTIONS_MAX) + { + LOG_ERROR("no space for connection %s/%s", out->name, in->name); + return MMAL_ENOSPC; + } + + status = mmal_connection_create(&cx, out, in, flags); + if (status != MMAL_SUCCESS) + return status; + + private->connection[private->connection_num++] = cx; + if (connection) + { + mmal_connection_acquire(cx); + *connection = cx; + } + + return MMAL_SUCCESS; +} + +/*****************************************************************************/ +MMAL_STATUS_T mmal_graph_enable(MMAL_GRAPH_T *graph, MMAL_GRAPH_EVENT_CB cb, void *cb_data) +{ + MMAL_GRAPH_PRIVATE_T *private = (MMAL_GRAPH_PRIVATE_T *)graph; + MMAL_STATUS_T status = MMAL_SUCCESS; + unsigned int i; + + LOG_TRACE("graph: %p", graph); + + if (vcos_thread_create(&private->thread, "mmal graph thread", NULL, + graph_worker_thread, private) != VCOS_SUCCESS) + { + LOG_ERROR("failed to create worker thread %p", graph); + return MMAL_ENOSPC; + } + + private->event_cb = cb; + private->event_cb_data = cb_data; + + /* Enable all control ports */ + for (i = 0; i < private->component_num; i++) + { + private->component[i]->control->userdata = (void *)private; + status = mmal_port_enable(private->component[i]->control, graph_control_cb); + if (status != MMAL_SUCCESS) + LOG_ERROR("could not enable port %s", private->component[i]->control->name); + } + + /* Enable all our connections */ + for (i = 0; i < private->connection_num; i++) + { + MMAL_CONNECTION_T *cx = private->connection[i]; + + cx->callback = graph_connection_cb; + cx->user_data = private; + + status = mmal_connection_enable(cx); + if (status != MMAL_SUCCESS) + goto error; + } + + /* Trigger the worker thread to populate the output ports with empty buffers */ + vcos_semaphore_post(&private->sema); + return status; + + error: + graph_stop_worker_thread(private); + return status; +} + +/*****************************************************************************/ +MMAL_STATUS_T mmal_graph_disable(MMAL_GRAPH_T *graph) +{ + MMAL_GRAPH_PRIVATE_T *private = (MMAL_GRAPH_PRIVATE_T *)graph; + MMAL_STATUS_T status = MMAL_SUCCESS; + unsigned int i; + + LOG_TRACE("graph: %p", graph); + + graph_stop_worker_thread(private); + + /* Disable all our connections */ + for (i = 0; i < private->connection_num; i++) + { + status = mmal_connection_disable(private->connection[i]); + if (status != MMAL_SUCCESS) + break; + } + + return status; +} + +/*****************************************************************************/ +MMAL_STATUS_T mmal_graph_build(MMAL_GRAPH_T *graph, + const char *name, MMAL_COMPONENT_T **component) +{ + LOG_TRACE("graph: %p, name: %s, component: %p", graph, name, component); + return mmal_component_create_with_constructor(name, mmal_component_create_from_graph, + (MMAL_GRAPH_PRIVATE_T *)graph, component); +} + +/*****************************************************************************/ +MMAL_STATUS_T mmal_graph_component_constructor(const char *name, + MMAL_COMPONENT_T *component) +{ + LOG_TRACE("name: %s, component: %p", name, component); + return mmal_component_create_from_graph(name, component); +} + +/*****************************************************************************/ +static void graph_component_control_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) +{ + MMAL_COMPONENT_T *graph_component = (MMAL_COMPONENT_T *)port->userdata; + MMAL_GRAPH_PRIVATE_T *graph_private = graph_component->priv->module; + MMAL_STATUS_T status; + + LOG_TRACE("%s(%p),%p,%4.4s", port->name, port, buffer, (char *)&buffer->cmd); + + /* Call user defined function first */ + if (graph_private->graph.pf_control_callback) + { + status = graph_private->graph.pf_control_callback(&graph_private->graph, + port, buffer); + if (status != MMAL_ENOSYS) + return; + } + + /* Forward the event on the graph control port */ + mmal_port_event_send(graph_component->control, buffer); +} + +/*****************************************************************************/ +static void graph_component_connection_cb(MMAL_CONNECTION_T *connection) +{ + MMAL_COMPONENT_T *component = (MMAL_COMPONENT_T *)connection->user_data; + MMAL_BUFFER_HEADER_T *buffer; + + if (connection->flags == MMAL_CONNECTION_FLAG_DIRECT && + (buffer = mmal_queue_get(connection->queue)) != NULL) + { + graph_process_buffer((MMAL_GRAPH_PRIVATE_T *)component->priv->module, + connection, buffer); + return; + } + + mmal_component_action_trigger(component); +} + +/*****************************************************************************/ +static void graph_port_event_handler(MMAL_CONNECTION_T *connection, + MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) +{ + MMAL_STATUS_T status; + + LOG_TRACE("port: %s(%p), buffer: %p, event: %4.4s", port->name, port, + buffer, (char *)&buffer->cmd); + + if (buffer->cmd == MMAL_EVENT_FORMAT_CHANGED && port->type == MMAL_PORT_TYPE_OUTPUT) + { + MMAL_EVENT_FORMAT_CHANGED_T *event = mmal_event_format_changed_get(buffer); + if (event) + { + LOG_DEBUG("----------Port format changed----------"); + mmal_log_dump_port(port); + LOG_DEBUG("-----------------to---------------------"); + mmal_log_dump_format(event->format); + LOG_DEBUG(" buffers num (opt %i, min %i), size (opt %i, min: %i)", + event->buffer_num_recommended, event->buffer_num_min, + event->buffer_size_recommended, event->buffer_size_min); + LOG_DEBUG("----------------------------------------"); + } + + status = mmal_connection_event_format_changed(connection, buffer); + } + + else + status = MMAL_SUCCESS; /* FIXME: ignore any other event for now */ + + mmal_buffer_header_release(buffer); + + if (status != MMAL_SUCCESS) + mmal_event_error_send(port->component, status); +} + +/*****************************************************************************/ +static void graph_process_buffer(MMAL_GRAPH_PRIVATE_T *graph_private, + MMAL_CONNECTION_T *connection, MMAL_BUFFER_HEADER_T *buffer) +{ + MMAL_STATUS_T status; + + /* Call user defined function first */ + if (graph_private->graph.pf_connection_buffer) + { + status = graph_private->graph.pf_connection_buffer(&graph_private->graph, connection, buffer); + if (status != MMAL_ENOSYS) + return; + } + + if (buffer->cmd) + { + graph_port_event_handler(connection, connection->out, buffer); + return; + } + + status = mmal_port_send_buffer(connection->in, buffer); + if (status != MMAL_SUCCESS) + { + LOG_ERROR("%s(%p) could not send buffer to %s(%p) (%s)", + connection->out->name, connection->out, + connection->in->name, connection->in, + mmal_status_to_string(status)); + mmal_buffer_header_release(buffer); + mmal_event_error_send(connection->out->component, status); + } +} + +/*****************************************************************************/ +static MMAL_BOOL_T graph_do_processing(MMAL_GRAPH_PRIVATE_T *graph_private) +{ + MMAL_BUFFER_HEADER_T *buffer; + MMAL_BOOL_T run_again = 0; + MMAL_STATUS_T status; + unsigned int i, j; + + /* Process all the empty buffers first */ + for (i = 0, j = graph_private->connection_current; + i < graph_private->connection_num; i++, j++) + { + MMAL_CONNECTION_T *connection = + graph_private->connection[j%graph_private->connection_num]; + + if ((connection->flags & MMAL_CONNECTION_FLAG_TUNNELLING) || + !connection->pool) + continue; /* Nothing else to do in tunnelling mode */ + + /* Send empty buffers to the output port of the connection */ + while ((buffer = mmal_queue_get(connection->pool->queue)) != NULL) + { + run_again = 1; + + status = mmal_port_send_buffer(connection->out, buffer); + if (status != MMAL_SUCCESS) + { + LOG_ERROR("mmal_port_send_buffer failed (%i)", status); + mmal_queue_put_back(connection->pool->queue, buffer); + run_again = 0; + // FIXME: send error ? + break; + } + } + } + + /* Loop through all the connections */ + for (i = 0, j = graph_private->connection_current++; + i < graph_private->connection_num; i++, j++) + { + MMAL_CONNECTION_T *connection = + graph_private->connection[j%graph_private->connection_num]; + int64_t duration = vcos_getmicrosecs64(); + + if (connection->flags & MMAL_CONNECTION_FLAG_TUNNELLING) + continue; /* Nothing else to do in tunnelling mode */ + if (connection->flags & MMAL_CONNECTION_FLAG_DIRECT) + continue; /* Nothing else to do in direct mode */ + + /* Send any queued buffer to the next component. + * We also make sure no connection can starve the others by + * having a timeout. */ + while (vcos_getmicrosecs64() - duration < PROCESSING_TIME_MAX && + (buffer = mmal_queue_get(connection->queue)) != NULL) + { + run_again = 1; + + graph_process_buffer(graph_private, connection, buffer); + } + } + + return run_again; +} + +/*****************************************************************************/ +static void graph_do_processing_loop(MMAL_COMPONENT_T *component) +{ + while (graph_do_processing((MMAL_GRAPH_PRIVATE_T *)component->priv->module)); +} + +/*****************************************************************************/ +static MMAL_PORT_T *find_port_from_graph(MMAL_GRAPH_PRIVATE_T *graph, MMAL_PORT_T *port) +{ + MMAL_PORT_T **list; + unsigned int *list_num; + + if (port->type != MMAL_PORT_TYPE_INPUT && port->type != MMAL_PORT_TYPE_OUTPUT) + return 0; + + list = port->type == MMAL_PORT_TYPE_INPUT ? graph->input : graph->output; + list_num = port->type == MMAL_PORT_TYPE_INPUT ? &graph->input_num : &graph->output_num; + if (port->index > *list_num) + return 0; + + return list[port->index]; +} + +static MMAL_PORT_T *find_port_to_graph(MMAL_GRAPH_PRIVATE_T *graph, MMAL_PORT_T *port) +{ + MMAL_COMPONENT_T *component = graph->graph_component; + MMAL_PORT_T **list; + unsigned int i, *list_num; + + if (port->type != MMAL_PORT_TYPE_INPUT && port->type != MMAL_PORT_TYPE_OUTPUT) + return 0; + + list = port->type == MMAL_PORT_TYPE_INPUT ? graph->input : graph->output; + list_num = port->type == MMAL_PORT_TYPE_INPUT ? &graph->input_num : &graph->output_num; + + for (i = 0; i < *list_num; i++) + if (list[i] == port) + break; + + if (i == *list_num) + return 0; + return port->type == MMAL_PORT_TYPE_INPUT ? component->input[i] : component->output[i]; +} + +static MMAL_STATUS_T graph_port_update(MMAL_GRAPH_PRIVATE_T *graph, + MMAL_PORT_T *graph_port, MMAL_BOOL_T init) +{ + MMAL_STATUS_T status; + MMAL_PORT_T *port; + + port = find_port_from_graph(graph, graph_port); + if (!port) + { + LOG_ERROR("could not find matching port for %p", graph_port); + return MMAL_EINVAL; + } + + status = mmal_format_full_copy(graph_port->format, port->format); + if (status != MMAL_SUCCESS) + { + LOG_ERROR("format copy failed on port %s", port->name); + return status; + } + + graph_port->buffer_num_min = port->buffer_num_min; + graph_port->buffer_num_recommended = port->buffer_num_recommended; + graph_port->buffer_size_min = port->buffer_size_min; + graph_port->buffer_size_recommended = port->buffer_size_recommended; + graph_port->buffer_alignment_min = port->buffer_alignment_min; + graph_port->capabilities = port->capabilities; + if (init) + { + graph_port->buffer_num = port->buffer_num; + graph_port->buffer_size = port->buffer_size; + } + return MMAL_SUCCESS; +} + +static MMAL_STATUS_T graph_port_update_requirements(MMAL_GRAPH_PRIVATE_T *graph, + MMAL_PORT_T *graph_port) +{ + MMAL_PORT_T *port; + + port = find_port_from_graph(graph, graph_port); + if (!port) + { + LOG_ERROR("could not find matching port for %p", graph_port); + return MMAL_EINVAL; + } + + graph_port->buffer_num_min = port->buffer_num_min; + graph_port->buffer_num_recommended = port->buffer_num_recommended; + graph_port->buffer_size_min = port->buffer_size_min; + graph_port->buffer_size_recommended = port->buffer_size_recommended; + graph_port->buffer_alignment_min = port->buffer_alignment_min; + return MMAL_SUCCESS; +} + +/** Destroy a previously created component */ +static MMAL_STATUS_T graph_component_destroy(MMAL_COMPONENT_T *component) +{ + MMAL_COMPONENT_MODULE_T *graph = component->priv->module; + + /* Notify client of destruction */ + if (graph->graph.pf_destroy) + graph->graph.pf_destroy(&graph->graph); + graph->graph.pf_destroy = NULL; + + if (component->input_num) + mmal_ports_free(component->input, component->input_num); + + if (component->output_num) + mmal_ports_free(component->output, component->output_num); + + /* coverity[address_free] Freeing the first item in the structure is safe */ + mmal_graph_destroy(&graph->graph); + return MMAL_SUCCESS; +} + +/** Enable processing on a component */ +static MMAL_STATUS_T graph_component_enable(MMAL_COMPONENT_T *component) +{ + MMAL_GRAPH_PRIVATE_T *graph_private = component->priv->module; + MMAL_STATUS_T status = MMAL_ENOSYS; + + /* Call user defined function first */ + if (graph_private->graph.pf_graph_enable) + status = graph_private->graph.pf_graph_enable(&graph_private->graph, MMAL_TRUE); + + return status; +} + +/** Disable processing on a component */ +static MMAL_STATUS_T graph_component_disable(MMAL_COMPONENT_T *component) +{ + MMAL_GRAPH_PRIVATE_T *graph_private = component->priv->module; + MMAL_STATUS_T status = MMAL_ENOSYS; + + /* Call user defined function first */ + if (graph_private->graph.pf_graph_enable) + status = graph_private->graph.pf_graph_enable(&graph_private->graph, MMAL_FALSE); + + return status; +} + +/** Callback given to mmal_port_enable() */ +static void graph_port_enable_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) +{ + MMAL_GRAPH_PRIVATE_T *graph_private = (MMAL_GRAPH_PRIVATE_T *)port->userdata; + MMAL_PORT_T *graph_port; + MMAL_STATUS_T status; + + graph_port = find_port_to_graph(graph_private, port); + if (!graph_port) + { + vcos_assert(0); + mmal_buffer_header_release(buffer); + return; + } + + /* Call user defined function first */ + if (graph_private->graph.pf_return_buffer) + { + status = graph_private->graph.pf_return_buffer(&graph_private->graph, graph_port, buffer); + if (status != MMAL_ENOSYS) + return; + } + + /* Forward the callback */ + if (buffer->cmd) + mmal_port_event_send(graph_port, buffer); + else + mmal_port_buffer_header_callback(graph_port, buffer); +} + +/** Check whether 2 ports of a component are linked */ +static MMAL_BOOL_T graph_component_topology_ports_linked(MMAL_GRAPH_PRIVATE_T *graph, + MMAL_PORT_T *port1, MMAL_PORT_T *port2) +{ + MMAL_COMPONENT_T *component = port1->component; + unsigned int i; + + for (i = 0; i < graph->component_num; i++) + if (component == graph->component[i]) + break; + + if (i == graph->component_num) + return MMAL_FALSE; /* Component not found */ + + if (graph->topology[i] == MMAL_GRAPH_TOPOLOGY_STRAIGHT) + return port1->index == port2->index; + + return MMAL_TRUE; +} + +/** Propagate a port enable */ +static MMAL_STATUS_T graph_port_state_propagate(MMAL_GRAPH_PRIVATE_T *graph, + MMAL_PORT_T *port, MMAL_BOOL_T enable) +{ + MMAL_COMPONENT_T *component = port->component; + MMAL_STATUS_T status = MMAL_SUCCESS; + MMAL_PORT_TYPE_T type = port->type; + unsigned int i, j; + + LOG_TRACE("graph: %p, port %s(%p)", graph, port->name, port); + + if (port->type == MMAL_PORT_TYPE_OUTPUT) + type = MMAL_PORT_TYPE_INPUT; + if (port->type == MMAL_PORT_TYPE_INPUT) + type = MMAL_PORT_TYPE_OUTPUT; + + /* Loop through all the output ports of the component and if they are not enabled and + * match one of the connections we maintain, then we need to propagate the port enable. */ + for (i = 0; i < component->port_num; i++) + { + if (component->port[i]->type != type) + continue; + + if ((component->port[i]->is_enabled && enable) || + (!component->port[i]->is_enabled && !enable)) + continue; + + /* Find the matching connection */ + for (j = 0; j < graph->connection_num; j++) + if (graph->connection[j]->out == component->port[i] || + graph->connection[j]->in == component->port[i]) + break; + + if (j == graph->connection_num) + continue; /* No match */ + + if (!graph_component_topology_ports_linked(graph, port, component->port[i])) + continue; /* Ports are independent */ + + if (enable) + { + status = mmal_connection_enable(graph->connection[j]); + if (status != MMAL_SUCCESS) + break; + + mmal_log_dump_port(graph->connection[j]->out); + mmal_log_dump_port(graph->connection[j]->in); + } + + status = graph_port_state_propagate(graph, graph->connection[j]->in == component->port[i] ? + graph->connection[j]->out : graph->connection[j]->in, enable); + if (status != MMAL_SUCCESS) + break; + + if (!enable) + { + status = mmal_connection_disable(graph->connection[j]); + if (status != MMAL_SUCCESS) + break; + } + } + + return status; +} + +/** Enable processing on a port */ +static MMAL_STATUS_T graph_port_enable(MMAL_PORT_T *graph_port, MMAL_PORT_BH_CB_T cb) +{ + MMAL_GRAPH_PRIVATE_T *graph_private = graph_port->component->priv->module; + MMAL_PORT_T *port; + MMAL_STATUS_T status; + MMAL_PARAM_UNUSED(cb); + + port = find_port_from_graph(graph_private, graph_port); + if (!port) + return MMAL_EINVAL; + + /* Update the buffer requirements */ + port->buffer_num = graph_port->buffer_num; + port->buffer_size = graph_port->buffer_size; + + /* Call user defined function first */ + if (graph_private->graph.pf_enable) + { + status = graph_private->graph.pf_enable(&graph_private->graph, graph_port); + if (status != MMAL_ENOSYS) + return status; + } + + /* We'll intercept the callback */ + port->userdata = (void *)graph_private; + status = mmal_port_enable(port, graph_port_enable_cb); + if (status != MMAL_SUCCESS) + return status; + + /* We need to enable all the connected connections */ + status = graph_port_state_propagate(graph_private, port, 1); + + mmal_component_action_trigger(graph_port->component); + return status; +} + +/** Disable processing on a port */ +static MMAL_STATUS_T graph_port_disable(MMAL_PORT_T *graph_port) +{ + MMAL_GRAPH_PRIVATE_T *graph_private = graph_port->component->priv->module; + MMAL_STATUS_T status; + MMAL_PORT_T *port; + + port = find_port_from_graph(graph_port->component->priv->module, graph_port); + if (!port) + return MMAL_EINVAL; + + /* Call user defined function first */ + if (graph_private->graph.pf_disable) + { + status = graph_private->graph.pf_disable(&graph_private->graph, graph_port); + if (status != MMAL_ENOSYS) + return status; + } + + /* We need to disable all the connected connections. + * Since disable does an implicit flush, we only want to do that if + * we're acting on an input port or we risk discarding buffers along + * the way. */ + if (!graph_private->input_num || port->type == MMAL_PORT_TYPE_INPUT) + { + MMAL_STATUS_T status = graph_port_state_propagate(graph_private, port, 0); + if (status != MMAL_SUCCESS) + return status; + } + + /* Forward the call */ + return mmal_port_disable(port); +} + +/** Propagate a port flush */ +static MMAL_STATUS_T graph_port_flush_propagate(MMAL_GRAPH_PRIVATE_T *graph, + MMAL_PORT_T *port) +{ + MMAL_COMPONENT_T *component = port->component; + MMAL_STATUS_T status; + unsigned int i, j; + + LOG_TRACE("graph: %p, port %s(%p)", graph, port->name, port); + + status = mmal_port_flush(port); + if (status != MMAL_SUCCESS) + return status; + + if (port->type == MMAL_PORT_TYPE_OUTPUT) + return MMAL_SUCCESS; + + /* Loop through all the output ports of the component and if they match one + * of the connections we maintain, then we need to propagate the flush. */ + for (i = 0; i < component->port_num; i++) + { + if (component->port[i]->type != MMAL_PORT_TYPE_OUTPUT) + continue; + if (!component->port[i]->is_enabled) + continue; + + /* Find the matching connection */ + for (j = 0; j < graph->connection_num; j++) + if (graph->connection[j]->out == component->port[i]) + break; + + if (j == graph->connection_num) + continue; /* No match */ + + if (!graph_component_topology_ports_linked(graph, port, component->port[i])) + continue; /* Ports are independent */ + + /* Flush any buffer waiting in the connection queue */ + if (graph->connection[j]->queue) + { + MMAL_BUFFER_HEADER_T *buffer = mmal_queue_get(graph->connection[j]->queue); + while(buffer) + { + mmal_buffer_header_release(buffer); + buffer = mmal_queue_get(graph->connection[j]->queue); + } + } + + status = graph_port_flush_propagate(graph, graph->connection[j]->in); + if (status != MMAL_SUCCESS) + break; + } + + return status; +} + +/** Flush a port */ +static MMAL_STATUS_T graph_port_flush(MMAL_PORT_T *graph_port) +{ + MMAL_GRAPH_PRIVATE_T *graph_private = graph_port->component->priv->module; + MMAL_STATUS_T status; + MMAL_PORT_T *port; + + port = find_port_from_graph(graph_private, graph_port); + if (!port) + return MMAL_EINVAL; + + /* Call user defined function first */ + if (graph_private->graph.pf_flush) + { + status = graph_private->graph.pf_flush(&graph_private->graph, graph_port); + if (status != MMAL_ENOSYS) + return status; + } + + /* Forward the call */ + return graph_port_flush_propagate(graph_private, port); +} + +/** Send a buffer header to a port */ +static MMAL_STATUS_T graph_port_send(MMAL_PORT_T *graph_port, MMAL_BUFFER_HEADER_T *buffer) +{ + MMAL_GRAPH_PRIVATE_T *graph_private = graph_port->component->priv->module; + MMAL_STATUS_T status; + MMAL_PORT_T *port; + + port = find_port_from_graph(graph_port->component->priv->module, graph_port); + if (!port) + return MMAL_EINVAL; + + /* Call user defined function first */ + if (graph_private->graph.pf_send_buffer) + { + status = graph_private->graph.pf_send_buffer(&graph_private->graph, graph_port, buffer); + if (status != MMAL_ENOSYS) + return status; + } + + /* Forward the call */ + return mmal_port_send_buffer(port, buffer); +} + +/** Propagate a format change */ +static MMAL_STATUS_T graph_port_format_commit_propagate(MMAL_GRAPH_PRIVATE_T *graph, + MMAL_PORT_T *port) +{ + MMAL_COMPONENT_T *component = port->component; + MMAL_STATUS_T status = MMAL_SUCCESS; + unsigned int i, j; + + LOG_TRACE("graph: %p, port %s(%p)", graph, port->name, port); + + if (port->type == MMAL_PORT_TYPE_OUTPUT) + return MMAL_SUCCESS; /* Nothing to do */ + + /* Loop through all the output ports of the component and if they are not enabled and + * match one of the connections we maintain, then we need to propagate the format change. */ + for (i = 0; i < component->output_num; i++) + { + MMAL_PORT_T *in, *out; + + if (component->output[i]->is_enabled) + continue; + + /* Find the matching connection */ + for (j = 0; j < graph->connection_num; j++) + if (graph->connection[j]->out == component->output[i]) + break; + + if (j == graph->connection_num) + continue; /* No match */ + + if (!graph_component_topology_ports_linked(graph, port, component->output[i])) + continue; /* Ports are independent */ + + in = graph->connection[j]->in; + out = graph->connection[j]->out; + + /* Apply the format to the input port */ + status = mmal_format_full_copy(in->format, out->format); + if (status != MMAL_SUCCESS) + break; + status = mmal_port_format_commit(in); + if (status != MMAL_SUCCESS) + break; + + mmal_log_dump_port(out); + mmal_log_dump_port(in); + + status = graph_port_format_commit_propagate(graph, in); + if (status != MMAL_SUCCESS) + break; + } + + return status; +} + +/** Set format on a port */ +static MMAL_STATUS_T graph_port_format_commit(MMAL_PORT_T *graph_port) +{ + MMAL_GRAPH_PRIVATE_T *graph_private = graph_port->component->priv->module; + MMAL_STATUS_T status; + MMAL_PORT_T *port; + unsigned int i; + + /* Call user defined function first */ + if (graph_private->graph.pf_format_commit) + { + status = graph_private->graph.pf_format_commit(&graph_private->graph, graph_port); + if (status == MMAL_SUCCESS) + goto end; + if (status != MMAL_ENOSYS) + return status; + } + + port = find_port_from_graph(graph_private, graph_port); + if (!port) + return MMAL_EINVAL; + + /* Update actual port */ + status = mmal_format_full_copy(port->format, graph_port->format); + if (status != MMAL_SUCCESS) + return status; + port->buffer_num = graph_port->buffer_num; + port->buffer_size = graph_port->buffer_size; + + /* Forward the call */ + status = mmal_port_format_commit(port); + if (status != MMAL_SUCCESS) + return status; + + /* Propagate format changes to the connections */ + status = graph_port_format_commit_propagate(graph_private, port); + if (status != MMAL_SUCCESS) + { + LOG_ERROR("couldn't propagate format commit of port %s(%p)", port->name, port); + return status; + } + + end: + /* Read the values back */ + status = graph_port_update(graph_private, graph_port, MMAL_FALSE); + if (status != MMAL_SUCCESS) + return status; + + /* Get the settings for the output ports in case they have changed */ + if (graph_port->type == MMAL_PORT_TYPE_INPUT) + { + for (i = 0; i < graph_private->output_num; i++) + { + status = graph_port_update(graph_private, graph_port->component->output[i], MMAL_FALSE); + if (status != MMAL_SUCCESS) + return status; + } + } + + return MMAL_SUCCESS; +} + +static MMAL_STATUS_T graph_port_control_parameter_get(MMAL_PORT_T *graph_port, + MMAL_PARAMETER_HEADER_T *param) +{ + MMAL_GRAPH_PRIVATE_T *graph_private = graph_port->component->priv->module; + MMAL_STATUS_T status = MMAL_ENOSYS; + unsigned int i; + + /* Call user defined function first */ + if (graph_private->graph.pf_parameter_get) + { + status = graph_private->graph.pf_parameter_get(&graph_private->graph, graph_port, param); + if (status != MMAL_ENOSYS) + return status; + } + + /* By default we do a get parameter on each component until one succeeds */ + for (i = 0; i < graph_private->component_num && status != MMAL_SUCCESS; i++) + status = mmal_port_parameter_get(graph_private->component[i]->control, param); + + return status; +} + +static MMAL_STATUS_T graph_port_parameter_get(MMAL_PORT_T *graph_port, + MMAL_PARAMETER_HEADER_T *param) +{ + MMAL_GRAPH_PRIVATE_T *graph_private = graph_port->component->priv->module; + MMAL_STATUS_T status; + MMAL_PORT_T *port; + + /* Call user defined function first */ + if (graph_private->graph.pf_parameter_get) + { + status = graph_private->graph.pf_parameter_get(&graph_private->graph, graph_port, param); + if (status != MMAL_ENOSYS) + return status; + } + + port = find_port_from_graph(graph_private, graph_port); + if (!port) + return MMAL_EINVAL; + + /* Forward the call */ + return mmal_port_parameter_get(port, param); +} + +static MMAL_STATUS_T graph_port_control_parameter_set(MMAL_PORT_T *graph_port, + const MMAL_PARAMETER_HEADER_T *param) +{ + MMAL_GRAPH_PRIVATE_T *graph_private = graph_port->component->priv->module; + MMAL_STATUS_T status = MMAL_ENOSYS; + unsigned int i; + + /* Call user defined function first */ + if (graph_private->graph.pf_parameter_set) + { + status = graph_private->graph.pf_parameter_set(&graph_private->graph, graph_port, param); + if (status != MMAL_ENOSYS) + return status; + } + + /* By default we do a set parameter on each component until one succeeds */ + for (i = 0; i < graph_private->component_num && status != MMAL_SUCCESS; i++) + status = mmal_port_parameter_set(graph_private->component[i]->control, param); + + return status; +} + +static MMAL_STATUS_T graph_port_parameter_set(MMAL_PORT_T *graph_port, + const MMAL_PARAMETER_HEADER_T *param) +{ + MMAL_GRAPH_PRIVATE_T *graph_private = graph_port->component->priv->module; + MMAL_STATUS_T status; + MMAL_PORT_T *port; + + /* Call user defined function first */ + if (graph_private->graph.pf_parameter_set) + { + status = graph_private->graph.pf_parameter_set(&graph_private->graph, graph_port, param); + if (status != MMAL_ENOSYS) + return status; + } + + port = find_port_from_graph(graph_private, graph_port); + if (!port) + return MMAL_EINVAL; + + /* Forward the call */ + status = mmal_port_parameter_set(port, param); + if (status != MMAL_SUCCESS) + goto end; + + if (param->id == MMAL_PARAMETER_BUFFER_REQUIREMENTS) + { + /* This might have changed the buffer requirements of other ports so fetch them all */ + MMAL_COMPONENT_T *component = graph_port->component; + unsigned int i; + for (i = 0; status == MMAL_SUCCESS && i < component->input_num; i++) + status = graph_port_update_requirements(graph_private, component->input[i]); + for (i = 0; status == MMAL_SUCCESS && i < component->output_num; i++) + status = graph_port_update_requirements(graph_private, component->output[i]); + } + + end: + return status; +} + +static MMAL_STATUS_T graph_port_connect(MMAL_PORT_T *graph_port, MMAL_PORT_T *other_port) +{ + MMAL_PORT_T *port; + + LOG_TRACE("%s(%p) %s(%p)", graph_port->name, graph_port, other_port->name, other_port); + + port = find_port_from_graph(graph_port->component->priv->module, graph_port); + if (!port) + return MMAL_EINVAL; + + /* Forward the call */ + return other_port ? mmal_port_connect(port, other_port) : mmal_port_disconnect(port); +} + +static uint8_t *graph_port_payload_alloc(MMAL_PORT_T *graph_port, uint32_t payload_size) +{ + MMAL_GRAPH_PRIVATE_T *graph_private = graph_port->component->priv->module; + MMAL_STATUS_T status; + MMAL_PORT_T *port; + uint8_t *payload; + + port = find_port_from_graph(graph_port->component->priv->module, graph_port); + if (!port) + return 0; + + /* Call user defined function first */ + if (graph_private->graph.pf_payload_alloc) + { + status = graph_private->graph.pf_payload_alloc(&graph_private->graph, graph_port, + payload_size, &payload); + if (status != MMAL_ENOSYS) + return status == MMAL_SUCCESS ? payload : NULL; + } + + /* Forward the call */ + return mmal_port_payload_alloc(port, payload_size); +} + +static void graph_port_payload_free(MMAL_PORT_T *graph_port, uint8_t *payload) +{ + MMAL_GRAPH_PRIVATE_T *graph_private = graph_port->component->priv->module; + MMAL_STATUS_T status; + MMAL_PORT_T *port; + + port = find_port_from_graph(graph_port->component->priv->module, graph_port); + if (!port) + return; + + /* Call user defined function first */ + if (graph_private->graph.pf_payload_free) + { + status = graph_private->graph.pf_payload_free(&graph_private->graph, graph_port, payload); + if (status == MMAL_SUCCESS) + return; + } + + /* Forward the call */ + mmal_port_payload_free(port, payload); +} + +/** Create an instance of a component */ +static MMAL_STATUS_T mmal_component_create_from_graph(const char *name, MMAL_COMPONENT_T *component) +{ + MMAL_STATUS_T status = MMAL_ENOMEM; + /* Our context is already allocated and available */ + MMAL_GRAPH_PRIVATE_T *graph = component->priv->module; + unsigned int i; + MMAL_PARAM_UNUSED(name); + + component->control->priv->pf_parameter_get = graph_port_control_parameter_get; + component->control->priv->pf_parameter_set = graph_port_control_parameter_set; + + /* Allocate the ports for this component */ + if(graph->input_num) + { + component->input = mmal_ports_alloc(component, graph->input_num, MMAL_PORT_TYPE_INPUT, 0); + if(!component->input) + goto error; + } + component->input_num = graph->input_num; + for(i = 0; i < component->input_num; i++) + { + component->input[i]->priv->pf_enable = graph_port_enable; + component->input[i]->priv->pf_disable = graph_port_disable; + component->input[i]->priv->pf_flush = graph_port_flush; + component->input[i]->priv->pf_send = graph_port_send; + component->input[i]->priv->pf_set_format = graph_port_format_commit; + component->input[i]->priv->pf_parameter_get = graph_port_parameter_get; + component->input[i]->priv->pf_parameter_set = graph_port_parameter_set; + if (graph->input[i]->priv->pf_connect && 0 /* FIXME: disabled for now */) + component->input[i]->priv->pf_connect = graph_port_connect; + component->input[i]->priv->pf_payload_alloc = graph_port_payload_alloc; + component->input[i]->priv->pf_payload_free = graph_port_payload_free; + + /* Mirror the port values */ + status = graph_port_update(graph, component->input[i], MMAL_TRUE); + if (status != MMAL_SUCCESS) + goto error; + } + if(graph->output_num) + { + component->output = mmal_ports_alloc(component, graph->output_num, MMAL_PORT_TYPE_OUTPUT, 0); + if(!component->output) + goto error; + } + component->output_num = graph->output_num; + for(i = 0; i < component->output_num; i++) + { + component->output[i]->priv->pf_enable = graph_port_enable; + component->output[i]->priv->pf_disable = graph_port_disable; + component->output[i]->priv->pf_flush = graph_port_flush; + component->output[i]->priv->pf_send = graph_port_send; + component->output[i]->priv->pf_set_format = graph_port_format_commit; + component->output[i]->priv->pf_parameter_get = graph_port_parameter_get; + component->output[i]->priv->pf_parameter_set = graph_port_parameter_set; + if (graph->output[i]->priv->pf_connect && 0 /* FIXME: disabled for now */) + component->output[i]->priv->pf_connect = graph_port_connect; + component->output[i]->priv->pf_payload_alloc = graph_port_payload_alloc; + component->output[i]->priv->pf_payload_free = graph_port_payload_free; + + /* Mirror the port values */ + status = graph_port_update(graph, component->output[i], MMAL_TRUE); + if (status != MMAL_SUCCESS) + goto error; + } + + status = mmal_component_action_register(component, graph_do_processing_loop); + if (status != MMAL_SUCCESS) + goto error; + +#if 1 // FIXME + /* Set our connection callback */ + for (i = 0; i < graph->connection_num; i++) + { + graph->connection[i]->callback = graph_component_connection_cb; + graph->connection[i]->user_data = (void *)component; + } +#endif + + component->priv->pf_destroy = graph_component_destroy; + component->priv->pf_enable = graph_component_enable; + component->priv->pf_disable = graph_component_disable; + graph->graph_component = component; + + /* Enable all the control ports */ + for (i = 0; i < graph->component_num; i++) + { + graph->component[i]->control->userdata = (void *)component; + status = mmal_port_enable(graph->component[i]->control, graph_component_control_cb); + if (status != MMAL_SUCCESS) + LOG_ERROR("could not enable port %s", component->control->name); + } + + return MMAL_SUCCESS; + + error: + graph_component_destroy(component); + return status; +} + +MMAL_PORT_T *mmal_graph_find_port(MMAL_GRAPH_T *graph, + const char *name, + MMAL_PORT_TYPE_T type, + unsigned index) +{ + unsigned i; + MMAL_GRAPH_PRIVATE_T *private = (MMAL_GRAPH_PRIVATE_T *)graph; + for (i=0; icomponent_num; i++) + { + MMAL_COMPONENT_T *comp = private->component[i]; + if (vcos_strcasecmp(name, comp->name) == 0) + { + unsigned num; + MMAL_PORT_T **ports; + if (type == MMAL_PORT_TYPE_INPUT) { + num = comp->input_num; + ports = comp->input; + } + else if (type == MMAL_PORT_TYPE_OUTPUT) { + num = comp->output_num; + ports = comp->output; + } + else if (type == MMAL_PORT_TYPE_CONTROL) { + num = 1; + ports = &comp->control; + } + else { + vcos_assert(0); + return NULL; + } + if (index < num) + { + /* coverity[ptr_arith] num is 1 at this point */ + return ports[index]; + } + } + } + LOG_INFO("port %s:%d not found", name, index); + return NULL; +} diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/util/mmal_graph.h b/external_src/raspicam-0.1.3/dependencies/mmal/util/mmal_graph.h new file mode 100644 index 0000000..e6284ba --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/util/mmal_graph.h @@ -0,0 +1,243 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 MMAL_GRAPH_H +#define MMAL_GRAPH_H + +#include "util/mmal_connection.h" + +/** \defgroup MmalGraphUtility Graph Utility + * \ingroup MmalUtilities + * The graph utility functions allows one to easily create graphs of MMAL components. + * + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** List of topology types */ +typedef enum +{ + MMAL_GRAPH_TOPOLOGY_ALL = 0, /**< All input ports and output ports are linked */ + MMAL_GRAPH_TOPOLOGY_STRAIGHT, /**< Input ports and output ports of the same index are linked */ + MMAL_GRAPH_TOPOLOGY_CUSTOM, /**< Custom defined topology */ + MMAL_GRAPH_TOPOLOGY_MAX + +} MMAL_GRAPH_TOPOLOGY_T; + +/** Structure describing a graph */ +typedef struct MMAL_GRAPH_T +{ + /** Pointer to private data of the client */ + struct MMAL_GRAPH_USERDATA_T *userdata; + + /** Optional callback that the client can set to get notified when the graph is going to be destroyed */ + void (*pf_destroy)(struct MMAL_GRAPH_T *); + + /** Optional callback that the client can set to intercept parameter requests on ports exposed by the graph */ + MMAL_STATUS_T (*pf_parameter_set)(struct MMAL_GRAPH_T *, MMAL_PORT_T *port, const MMAL_PARAMETER_HEADER_T *param); + /** Optional callback that the client can set to intercept parameter requests on ports exposed by the graph */ + MMAL_STATUS_T (*pf_parameter_get)(struct MMAL_GRAPH_T *, MMAL_PORT_T *port, MMAL_PARAMETER_HEADER_T *param); + /** Optional callback that the client can set to intercept format commit calls on ports exposed by the graph */ + MMAL_STATUS_T (*pf_format_commit)(struct MMAL_GRAPH_T *, MMAL_PORT_T *port); + /** Optional callback that the client can set to intercept send buffer calls on ports exposed by the graph */ + MMAL_STATUS_T (*pf_send_buffer)(struct MMAL_GRAPH_T *, MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer); + /** Optional callback that the client can set to intercept buffer callbacks on ports exposed by the graph */ + MMAL_STATUS_T (*pf_return_buffer)(struct MMAL_GRAPH_T *, MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer); + /** Optional callback that the client can set to intercept payload alloc calls on ports exposed by the graph */ + MMAL_STATUS_T (*pf_payload_alloc)(struct MMAL_GRAPH_T *, MMAL_PORT_T *port, uint32_t payload_size, uint8_t **); + /** Optional callback that the client can set to intercept payload free calls on ports exposed by the graph */ + MMAL_STATUS_T (*pf_payload_free)(struct MMAL_GRAPH_T *, MMAL_PORT_T *port, uint8_t *payload); + /** Optional callback that the client can set to intercept flush calls on ports exposed by the graph */ + MMAL_STATUS_T (*pf_flush)(struct MMAL_GRAPH_T *, MMAL_PORT_T *port); + /** Optional callback that the client can set to control callbacks from the internal components of the graph */ + /** Optional callback that the client can set to intercept enable calls on ports exposed by the graph */ + MMAL_STATUS_T (*pf_enable)(struct MMAL_GRAPH_T *, MMAL_PORT_T *port); + /** Optional callback that the client can set to intercept disable calls on ports exposed by the graph */ + MMAL_STATUS_T (*pf_disable)(struct MMAL_GRAPH_T *, MMAL_PORT_T *port); + /** Optional callback that the client can set to control callbacks from the internal components of the graph */ + MMAL_STATUS_T (*pf_control_callback)(struct MMAL_GRAPH_T *, MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer); + /** Optional callback that the client can set to intercept component_enable/disable calls made to the graph */ + MMAL_STATUS_T (*pf_graph_enable)(struct MMAL_GRAPH_T *, MMAL_BOOL_T enable); + /** Optional callback that the client can set to intercept buffers going through internal connections. + * This will only be triggered if the connection is not tunnelled */ + MMAL_STATUS_T (*pf_connection_buffer)(struct MMAL_GRAPH_T *, MMAL_CONNECTION_T *connection, MMAL_BUFFER_HEADER_T *buffer); + +} MMAL_GRAPH_T; + +/** Create an instance of a graph. + * The newly created graph will need to be populated by the client. + * + * @param graph returned graph + * @param userdata_size size to be allocated for the userdata field + * @return MMAL_SUCCESS on success + */ +MMAL_STATUS_T mmal_graph_create(MMAL_GRAPH_T **graph, unsigned int userdata_size); + +/** Add a component to a graph. + * Allows the client to add a component to the graph. + * + * @param graph instance of the graph + * @param component component to add to a graph + * @return MMAL_SUCCESS on success + */ +MMAL_STATUS_T mmal_graph_add_component(MMAL_GRAPH_T *graph, MMAL_COMPONENT_T *component); + +/** Describe the topology of the ports of a component. + * Allows the client to describe the topology of a component. This information + * is used by the graph to choose which action to perform when + * enabling / disabling / committing / flushing a port exposed by the graph. + * Note that by default the topology of a component is set to MMAL_GRAPH_TOPOLOGY_ALL. + * + * @param graph instance of the graph + * @param component component to describe + * @param topology type of topology used by this component + * @param input output index (or -1 if sink) linked to each input port + * @param input_num number of indexes in the input list + * @param output input index (or -1 if source) linked to each output port + * @param output_num number of indexes in the output list + * @return MMAL_SUCCESS on success + */ +MMAL_STATUS_T mmal_graph_component_topology(MMAL_GRAPH_T *graph, MMAL_COMPONENT_T *component, + MMAL_GRAPH_TOPOLOGY_T topology, int8_t *input, unsigned int input_num, + int8_t *output, unsigned int output_num); + +/** Add a port to a graph. + * Allows the client to add an input or output port to a graph. The given port + * will effectively become an end point for the graph. + * + * @param graph instance of the graph + * @param port port to add to the graph + * @return MMAL_SUCCESS on success + */ +MMAL_STATUS_T mmal_graph_add_port(MMAL_GRAPH_T *graph, MMAL_PORT_T *port); + +/** Add a connection to a graph. + * Allows the client to add an internal connection to a graph. + * + * @param graph instance of the graph + * @param connection connection to add to the graph + * @return MMAL_SUCCESS on success + */ +MMAL_STATUS_T mmal_graph_add_connection(MMAL_GRAPH_T *graph, MMAL_CONNECTION_T *connection); + +/** Create a new component and add it to a graph. + * Allows the client to create and add a component to the graph. + * + * @param graph instance of the graph + * @param name name of the component to create + * @param component if not NULL, will contain a pointer to the created component + * @return MMAL_SUCCESS on success + */ +MMAL_STATUS_T mmal_graph_new_component(MMAL_GRAPH_T *graph, const char *name, + MMAL_COMPONENT_T **component); + +/** Create and add a connection to a graph. + * Allows the client to create and add an internal connection to a graph. + * + * @param graph instance of the graph + * @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 + * @param connection if not NULL, will contain a pointer to the created connection + * @return MMAL_SUCCESS on success + */ +MMAL_STATUS_T mmal_graph_new_connection(MMAL_GRAPH_T *graph, MMAL_PORT_T *out, MMAL_PORT_T *in, + uint32_t flags, MMAL_CONNECTION_T **connection); + +/** Definition of the callback used by a graph to send events to the client. + * + * @param graph the graph sending the event + * @param port the port which generated the event + * @param buffer the buffer header containing the event data + * @param cb_data data passed back to the client when the callback is invoked + */ +typedef void (*MMAL_GRAPH_EVENT_CB)(MMAL_GRAPH_T *graph, MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer, + void *cb_data); + +/** Enable the graph and start processing. + * + * @param graph the graph to enable + * @param cb the callback to invoke when an event occurs on any of the internal control ports + * @param cb_data data passed back to the client when the callback is invoked + * + * @return MMAL_SUCCESS on success + */ +MMAL_STATUS_T mmal_graph_enable(MMAL_GRAPH_T *graph, MMAL_GRAPH_EVENT_CB cb, void *cb_data); + +MMAL_STATUS_T mmal_graph_disable(MMAL_GRAPH_T *graph); + +/** Find a port in the graph. + * + * @param graph graph instance + * @param name name of the component of interest + * @param type type of port (in/out) + * @param index which port index within the component + * + * @return port, or NULL if not found + */ +MMAL_PORT_T *mmal_graph_find_port(MMAL_GRAPH_T *graph, + const char *name, + MMAL_PORT_TYPE_T type, + unsigned index); + +/** Create an instance of a component from a graph. + * The newly created component will expose input and output ports to the client. + * Not that all the exposed ports will be in a disabled state by default. + * + * @param graph graph to create the component from + * @param name name of the component to create + * @param component returned component + * @return MMAL_SUCCESS on success + */ +MMAL_STATUS_T mmal_graph_build(MMAL_GRAPH_T *ctx, + const char *name, MMAL_COMPONENT_T **component); + +/** Component constructor for a graph. + * FIXME: private function + * + * @param name name of the component to create + * @param component component + * @return MMAL_SUCCESS on success + */ +MMAL_STATUS_T mmal_graph_component_constructor(const char *name, MMAL_COMPONENT_T *component); + +/** Destroy a previously created graph + * @param graph graph to destroy + * @return MMAL_SUCCESS on success + */ +MMAL_STATUS_T mmal_graph_destroy(MMAL_GRAPH_T *ctx); + +#ifdef __cplusplus +} +#endif + +/** @} */ + +#endif /* MMAL_GRAPH_H */ diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/util/mmal_il.c b/external_src/raspicam-0.1.3/dependencies/mmal/util/mmal_il.c new file mode 100644 index 0000000..955e391 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/util/mmal_il.c @@ -0,0 +1,915 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 "mmal.h" +#include "util/mmal_il.h" +#include "interface/vmcs_host/khronos/IL/OMX_Broadcom.h" + +/*****************************************************************************/ +static struct { + MMAL_STATUS_T mmal; + OMX_ERRORTYPE omx; +} mmal_omx_error[] = +{ + {MMAL_SUCCESS, OMX_ErrorNone}, + {MMAL_ENOMEM, OMX_ErrorInsufficientResources}, + {MMAL_ENOSPC, OMX_ErrorInsufficientResources}, + {MMAL_EINVAL, OMX_ErrorBadParameter}, + {MMAL_ENOSYS, OMX_ErrorNotImplemented}, + {(MMAL_STATUS_T)-1, OMX_ErrorUndefined}, +}; + +OMX_ERRORTYPE mmalil_error_to_omx(MMAL_STATUS_T status) +{ + unsigned int i; + for(i = 0; mmal_omx_error[i].mmal != (MMAL_STATUS_T)-1; i++) + if(mmal_omx_error[i].mmal == status) break; + return mmal_omx_error[i].omx; +} + +MMAL_STATUS_T mmalil_error_to_mmal(OMX_ERRORTYPE error) +{ + unsigned int i; + for(i = 0; mmal_omx_error[i].mmal != (MMAL_STATUS_T)-1; i++) + if(mmal_omx_error[i].omx == error) break; + return mmal_omx_error[i].mmal; +} + +/*****************************************************************************/ +OMX_U32 mmalil_buffer_flags_to_omx(uint32_t flags) +{ + OMX_U32 omx_flags = 0; + + if(flags & MMAL_BUFFER_HEADER_FLAG_KEYFRAME) + omx_flags |= OMX_BUFFERFLAG_SYNCFRAME; + if(flags & MMAL_BUFFER_HEADER_FLAG_FRAME_END) + omx_flags |= OMX_BUFFERFLAG_ENDOFFRAME; + if(flags & MMAL_BUFFER_HEADER_FLAG_EOS) + omx_flags |= OMX_BUFFERFLAG_EOS; + if(flags & MMAL_BUFFER_HEADER_FLAG_CONFIG) + omx_flags |= OMX_BUFFERFLAG_CODECCONFIG; + if(flags & MMAL_BUFFER_HEADER_FLAG_DISCONTINUITY) + omx_flags |= OMX_BUFFERFLAG_DISCONTINUITY; + if (flags & MMAL_BUFFER_HEADER_FLAG_CODECSIDEINFO) + omx_flags |= OMX_BUFFERFLAG_CODECSIDEINFO; + if (flags & MMAL_BUFFER_HEADER_FLAGS_SNAPSHOT) + omx_flags |= OMX_BUFFERFLAG_CAPTURE_PREVIEW; + if (flags & MMAL_BUFFER_HEADER_FLAG_CORRUPTED) + omx_flags |= OMX_BUFFERFLAG_DATACORRUPT; + if (flags & MMAL_BUFFER_HEADER_FLAG_DECODEONLY) + omx_flags |= OMX_BUFFERFLAG_DECODEONLY; + if (flags & MMAL_BUFFER_HEADER_FLAG_USER0) + omx_flags |= 1<<28; + if (flags & MMAL_BUFFER_HEADER_FLAG_USER1) + omx_flags |= 1<<29; + if (flags & MMAL_BUFFER_HEADER_FLAG_USER2) + omx_flags |= 1<<30; + if (flags & MMAL_BUFFER_HEADER_FLAG_USER3) + omx_flags |= 1<<31; + + return omx_flags; +} + +uint32_t mmalil_buffer_flags_to_mmal(OMX_U32 flags) +{ + uint32_t mmal_flags = 0; + + if (flags & OMX_BUFFERFLAG_SYNCFRAME) + mmal_flags |= MMAL_BUFFER_HEADER_FLAG_KEYFRAME; + if (flags & OMX_BUFFERFLAG_ENDOFFRAME) + mmal_flags |= MMAL_BUFFER_HEADER_FLAG_FRAME_END; + if (flags & OMX_BUFFERFLAG_EOS) + mmal_flags |= MMAL_BUFFER_HEADER_FLAG_EOS; + if (flags & OMX_BUFFERFLAG_CODECCONFIG) + mmal_flags |= MMAL_BUFFER_HEADER_FLAG_CONFIG; + if (flags & OMX_BUFFERFLAG_DISCONTINUITY) + mmal_flags |= MMAL_BUFFER_HEADER_FLAG_DISCONTINUITY; + if (flags & OMX_BUFFERFLAG_CODECSIDEINFO) + mmal_flags |= MMAL_BUFFER_HEADER_FLAG_CODECSIDEINFO; + if (flags & OMX_BUFFERFLAG_CAPTURE_PREVIEW) + mmal_flags |= MMAL_BUFFER_HEADER_FLAGS_SNAPSHOT; + if (flags & OMX_BUFFERFLAG_DATACORRUPT) + mmal_flags |= MMAL_BUFFER_HEADER_FLAG_CORRUPTED; + if (flags & OMX_BUFFERFLAG_DECODEONLY) + mmal_flags |= MMAL_BUFFER_HEADER_FLAG_DECODEONLY; + if (flags & 1<<28) + mmal_flags |= MMAL_BUFFER_HEADER_FLAG_USER0; + if (flags & 1<<29) + mmal_flags |= MMAL_BUFFER_HEADER_FLAG_USER1; + if (flags & 1<<30) + mmal_flags |= MMAL_BUFFER_HEADER_FLAG_USER2; + if (flags & 1<<31) + mmal_flags |= MMAL_BUFFER_HEADER_FLAG_USER3; + + return mmal_flags; +} + +/*****************************************************************************/ +void mmalil_buffer_header_to_omx(OMX_BUFFERHEADERTYPE *omx, MMAL_BUFFER_HEADER_T *mmal) +{ + omx->pBuffer = mmal->data; + omx->nAllocLen = mmal->alloc_size; + omx->nFilledLen = mmal->length; + omx->nOffset = mmal->offset; + omx->nFlags = mmalil_buffer_flags_to_omx(mmal->flags); + omx->nTimeStamp = omx_ticks_from_s64(mmal->pts); + if (mmal->pts == MMAL_TIME_UNKNOWN) + { + omx->nFlags |= OMX_BUFFERFLAG_TIME_UNKNOWN; + omx->nTimeStamp = omx_ticks_from_s64(0); + } +} + +void mmalil_buffer_header_to_mmal(MMAL_BUFFER_HEADER_T *mmal, OMX_BUFFERHEADERTYPE *omx) +{ + mmal->cmd = 0; + mmal->data = omx->pBuffer; + mmal->alloc_size = omx->nAllocLen; + mmal->length = omx->nFilledLen; + mmal->offset = omx->nOffset; + mmal->pts = omx_ticks_to_s64(omx->nTimeStamp); + if (omx->nFlags & OMX_BUFFERFLAG_TIME_UNKNOWN) + mmal->pts = MMAL_TIME_UNKNOWN; + mmal->dts = MMAL_TIME_UNKNOWN; + mmal->flags = mmalil_buffer_flags_to_mmal(omx->nFlags); +} + +/*****************************************************************************/ +static struct { + MMAL_ES_TYPE_T type; + OMX_PORTDOMAINTYPE domain; +} mmal_omx_es_type_table[] = +{ + {MMAL_ES_TYPE_VIDEO, OMX_PortDomainVideo}, + {MMAL_ES_TYPE_VIDEO, OMX_PortDomainImage}, + {MMAL_ES_TYPE_AUDIO, OMX_PortDomainAudio}, + {MMAL_ES_TYPE_UNKNOWN, OMX_PortDomainMax} +}; + +OMX_PORTDOMAINTYPE mmalil_es_type_to_omx_domain(MMAL_ES_TYPE_T type) +{ + unsigned int i; + for(i = 0; mmal_omx_es_type_table[i].type != MMAL_ES_TYPE_UNKNOWN; i++) + if(mmal_omx_es_type_table[i].type == type) break; + return mmal_omx_es_type_table[i].domain; +} + +MMAL_ES_TYPE_T mmalil_omx_domain_to_es_type(OMX_PORTDOMAINTYPE domain) +{ + unsigned int i; + for(i = 0; mmal_omx_es_type_table[i].type != MMAL_ES_TYPE_UNKNOWN; i++) + if(mmal_omx_es_type_table[i].domain == domain) break; + return mmal_omx_es_type_table[i].type; +} + +/*****************************************************************************/ +static struct { + uint32_t encoding; + OMX_AUDIO_CODINGTYPE coding; +} mmal_omx_audio_coding_table[] = +{ + {MMAL_ENCODING_MP4A, OMX_AUDIO_CodingAAC}, + {MMAL_ENCODING_MPGA, OMX_AUDIO_CodingMP3}, + {MMAL_ENCODING_WMA2, OMX_AUDIO_CodingWMA}, + {MMAL_ENCODING_WMA1, OMX_AUDIO_CodingWMA}, + {MMAL_ENCODING_AMRNB, OMX_AUDIO_CodingAMR}, + {MMAL_ENCODING_AMRWB, OMX_AUDIO_CodingAMR}, + {MMAL_ENCODING_AMRWBP, OMX_AUDIO_CodingAMR}, + {MMAL_ENCODING_VORBIS, OMX_AUDIO_CodingVORBIS}, + {MMAL_ENCODING_ALAW, OMX_AUDIO_CodingPCM}, + {MMAL_ENCODING_MULAW, OMX_AUDIO_CodingPCM}, + {MMAL_ENCODING_PCM_SIGNED_LE, OMX_AUDIO_CodingPCM}, + {MMAL_ENCODING_PCM_UNSIGNED_LE,OMX_AUDIO_CodingPCM}, + {MMAL_ENCODING_PCM_SIGNED_BE, OMX_AUDIO_CodingPCM}, + {MMAL_ENCODING_PCM_UNSIGNED_BE,OMX_AUDIO_CodingPCM}, + {MMAL_ENCODING_AC3, OMX_AUDIO_CodingDDP}, + {MMAL_ENCODING_EAC3, OMX_AUDIO_CodingDDP}, + {MMAL_ENCODING_DTS, OMX_AUDIO_CodingDTS}, + {MMAL_ENCODING_UNKNOWN, OMX_AUDIO_CodingUnused} +}; + +uint32_t mmalil_omx_audio_coding_to_encoding(OMX_AUDIO_CODINGTYPE coding) +{ + unsigned int i; + for(i = 0; mmal_omx_audio_coding_table[i].encoding != MMAL_ENCODING_UNKNOWN; i++) + if(mmal_omx_audio_coding_table[i].coding == coding) break; + return mmal_omx_audio_coding_table[i].encoding; +} + +OMX_AUDIO_CODINGTYPE mmalil_encoding_to_omx_audio_coding(uint32_t encoding) +{ + unsigned int i; + for(i = 0; mmal_omx_audio_coding_table[i].encoding != MMAL_ENCODING_UNKNOWN; i++) + if(mmal_omx_audio_coding_table[i].encoding == encoding) break; + return mmal_omx_audio_coding_table[i].coding; +} + +static struct { + OMX_AUDIO_CODINGTYPE coding; + OMX_INDEXTYPE index; + unsigned int size; +} mmal_omx_audio_format_table[] = +{ + {OMX_AUDIO_CodingPCM, OMX_IndexParamAudioPcm, sizeof(OMX_AUDIO_PARAM_PCMMODETYPE)}, + {OMX_AUDIO_CodingADPCM, OMX_IndexParamAudioAdpcm, sizeof(OMX_AUDIO_PARAM_ADPCMTYPE)}, + {OMX_AUDIO_CodingAMR, OMX_IndexParamAudioAmr, sizeof(OMX_AUDIO_PARAM_AMRTYPE)}, + {OMX_AUDIO_CodingGSMFR, OMX_IndexParamAudioGsm_FR, sizeof(OMX_AUDIO_PARAM_GSMFRTYPE)}, + {OMX_AUDIO_CodingGSMEFR, OMX_IndexParamAudioGsm_EFR, sizeof(OMX_AUDIO_PARAM_GSMEFRTYPE)}, + {OMX_AUDIO_CodingGSMHR, OMX_IndexParamAudioGsm_HR, sizeof(OMX_AUDIO_PARAM_GSMHRTYPE)}, + {OMX_AUDIO_CodingPDCFR, OMX_IndexParamAudioPdc_FR, sizeof(OMX_AUDIO_PARAM_PDCFRTYPE)}, + {OMX_AUDIO_CodingPDCEFR, OMX_IndexParamAudioPdc_EFR, sizeof(OMX_AUDIO_PARAM_PDCEFRTYPE)}, + {OMX_AUDIO_CodingPDCHR, OMX_IndexParamAudioPdc_HR, sizeof(OMX_AUDIO_PARAM_PDCHRTYPE)}, + {OMX_AUDIO_CodingTDMAFR, OMX_IndexParamAudioTdma_FR, sizeof(OMX_AUDIO_PARAM_TDMAFRTYPE)}, + {OMX_AUDIO_CodingTDMAEFR, OMX_IndexParamAudioTdma_EFR, sizeof(OMX_AUDIO_PARAM_TDMAEFRTYPE)}, + {OMX_AUDIO_CodingQCELP8, OMX_IndexParamAudioQcelp8, sizeof(OMX_AUDIO_PARAM_QCELP8TYPE)}, + {OMX_AUDIO_CodingQCELP13, OMX_IndexParamAudioQcelp13, sizeof(OMX_AUDIO_PARAM_QCELP13TYPE)}, + {OMX_AUDIO_CodingEVRC, OMX_IndexParamAudioEvrc, sizeof(OMX_AUDIO_PARAM_EVRCTYPE)}, + {OMX_AUDIO_CodingSMV, OMX_IndexParamAudioSmv, sizeof(OMX_AUDIO_PARAM_SMVTYPE)}, + {OMX_AUDIO_CodingG723, OMX_IndexParamAudioG723, sizeof(OMX_AUDIO_PARAM_G723TYPE)}, + {OMX_AUDIO_CodingG726, OMX_IndexParamAudioG726, sizeof(OMX_AUDIO_PARAM_G726TYPE)}, + {OMX_AUDIO_CodingG729, OMX_IndexParamAudioG729, sizeof(OMX_AUDIO_PARAM_G729TYPE)}, + {OMX_AUDIO_CodingAAC, OMX_IndexParamAudioAac, sizeof(OMX_AUDIO_PARAM_AACPROFILETYPE)}, + {OMX_AUDIO_CodingMP3, OMX_IndexParamAudioMp3, sizeof(OMX_AUDIO_PARAM_MP3TYPE)}, + {OMX_AUDIO_CodingSBC, OMX_IndexParamAudioSbc, sizeof(OMX_AUDIO_PARAM_SBCTYPE)}, + {OMX_AUDIO_CodingVORBIS, OMX_IndexParamAudioVorbis, sizeof(OMX_AUDIO_PARAM_VORBISTYPE)}, + {OMX_AUDIO_CodingWMA, OMX_IndexParamAudioWma, sizeof(OMX_AUDIO_PARAM_WMATYPE)}, + {OMX_AUDIO_CodingRA, OMX_IndexParamAudioRa, sizeof(OMX_AUDIO_PARAM_RATYPE)}, + {OMX_AUDIO_CodingMIDI, OMX_IndexParamAudioMidi, sizeof(OMX_AUDIO_PARAM_MIDITYPE)}, + {OMX_AUDIO_CodingDDP, OMX_IndexParamAudioDdp, sizeof(OMX_AUDIO_PARAM_DDPTYPE)}, + {OMX_AUDIO_CodingDTS, OMX_IndexParamAudioDts, sizeof(OMX_AUDIO_PARAM_DTSTYPE)}, + {OMX_AUDIO_CodingUnused, 0, 0} +}; + +OMX_AUDIO_CODINGTYPE mmalil_omx_audio_param_index_to_coding(OMX_INDEXTYPE index) +{ + unsigned int i; + for(i = 0; mmal_omx_audio_format_table[i].coding != OMX_AUDIO_CodingUnused; i++) + if(mmal_omx_audio_format_table[i].index == index) break; + + return mmal_omx_audio_format_table[i].coding; +} + +OMX_INDEXTYPE mmalil_omx_audio_param_index(OMX_AUDIO_CODINGTYPE coding, OMX_U32 *size) +{ + unsigned int i; + for(i = 0; mmal_omx_audio_format_table[i].coding != OMX_AUDIO_CodingUnused; i++) + if(mmal_omx_audio_format_table[i].coding == coding) break; + + if(size) *size = mmal_omx_audio_format_table[i].size; + return mmal_omx_audio_format_table[i].index; +} + +MMAL_STATUS_T mmalil_omx_default_channel_mapping(OMX_AUDIO_CHANNELTYPE *channel_mapping, unsigned int nchannels) +{ + static const OMX_AUDIO_CHANNELTYPE default_mapping[][8] = { + {OMX_AUDIO_ChannelNone}, + {OMX_AUDIO_ChannelCF}, + {OMX_AUDIO_ChannelLF, OMX_AUDIO_ChannelRF}, + {OMX_AUDIO_ChannelLF, OMX_AUDIO_ChannelRF, OMX_AUDIO_ChannelCF}, + {OMX_AUDIO_ChannelLF, OMX_AUDIO_ChannelRF, OMX_AUDIO_ChannelCF, + OMX_AUDIO_ChannelCS}, + {OMX_AUDIO_ChannelLF, OMX_AUDIO_ChannelRF, OMX_AUDIO_ChannelCF, + OMX_AUDIO_ChannelLR, OMX_AUDIO_ChannelRR}, + {OMX_AUDIO_ChannelLF, OMX_AUDIO_ChannelRF, OMX_AUDIO_ChannelCF, + OMX_AUDIO_ChannelLFE, OMX_AUDIO_ChannelLR, OMX_AUDIO_ChannelRR}, + {OMX_AUDIO_ChannelLF, OMX_AUDIO_ChannelRF, OMX_AUDIO_ChannelCF, + OMX_AUDIO_ChannelLFE, OMX_AUDIO_ChannelLR, OMX_AUDIO_ChannelRR, + OMX_AUDIO_ChannelCS}, + {OMX_AUDIO_ChannelLF, OMX_AUDIO_ChannelRF, OMX_AUDIO_ChannelCF, + OMX_AUDIO_ChannelLFE, OMX_AUDIO_ChannelLR, OMX_AUDIO_ChannelRR, + OMX_AUDIO_ChannelLS, OMX_AUDIO_ChannelRS} + }; + + if (!nchannels || nchannels + 1 >= MMAL_COUNTOF(default_mapping)) + return MMAL_EINVAL; + + memcpy(channel_mapping, default_mapping[nchannels], + sizeof(default_mapping[0][0]) * nchannels); + return MMAL_SUCCESS; +} + +MMAL_FOURCC_T mmalil_omx_audio_param_to_format(MMAL_ES_FORMAT_T *format, + OMX_AUDIO_CODINGTYPE coding, OMX_FORMAT_PARAM_TYPE *param) +{ + MMAL_AUDIO_FORMAT_T *audio = &format->es->audio; + format->encoding = mmalil_omx_audio_coding_to_encoding(coding); + format->encoding_variant = 0; + + switch(coding) + { + case OMX_AUDIO_CodingPCM: + audio->channels = param->pcm.nChannels; + audio->sample_rate = param->pcm.nSamplingRate; + audio->bits_per_sample = param->pcm.nBitPerSample; + if(param->pcm.ePCMMode == OMX_AUDIO_PCMModeLinear && param->pcm.bInterleaved) + { + if(param->pcm.eEndian == OMX_EndianBig && + param->pcm.eNumData == OMX_NumericalDataSigned) + format->encoding = MMAL_ENCODING_PCM_SIGNED_BE; + else if(param->pcm.eEndian == OMX_EndianLittle && + param->pcm.eNumData == OMX_NumericalDataSigned) + format->encoding = MMAL_ENCODING_PCM_SIGNED_LE; + if(param->pcm.eEndian == OMX_EndianBig && + param->pcm.eNumData == OMX_NumericalDataUnsigned) + format->encoding = MMAL_ENCODING_PCM_UNSIGNED_BE; + if(param->pcm.eEndian == OMX_EndianLittle && + param->pcm.eNumData == OMX_NumericalDataUnsigned) + format->encoding = MMAL_ENCODING_PCM_UNSIGNED_LE; + } + else if(param->pcm.ePCMMode == OMX_AUDIO_PCMModeALaw) + format->encoding = MMAL_ENCODING_ALAW; + else if(param->pcm.ePCMMode == OMX_AUDIO_PCMModeMULaw) + format->encoding = MMAL_ENCODING_MULAW; + break; + case OMX_AUDIO_CodingAAC: + audio->channels = param->aac.nChannels; + audio->sample_rate = param->aac.nSampleRate; + format->bitrate = param->aac.nBitRate; + switch(param->aac.eAACStreamFormat) + { + case OMX_AUDIO_AACStreamFormatMP2ADTS: + case OMX_AUDIO_AACStreamFormatMP4ADTS: + format->encoding = MMAL_ENCODING_MP4A; + format->encoding_variant = MMAL_ENCODING_VARIANT_MP4A_ADTS; + break; + case OMX_AUDIO_AACStreamFormatMP4FF: + case OMX_AUDIO_AACStreamFormatRAW: + format->encoding = MMAL_ENCODING_MP4A; + format->encoding_variant = MMAL_ENCODING_VARIANT_MP4A_DEFAULT; + break; + default: break; + } + break; + case OMX_AUDIO_CodingMP3: + format->encoding = MMAL_ENCODING_MPGA; + audio->channels = param->mp3.nChannels; + audio->sample_rate = param->mp3.nSampleRate; + format->bitrate = param->mp3.nBitRate; + break; + case OMX_AUDIO_CodingWMA: + audio->channels = param->wma.nChannels; + audio->sample_rate = param->wma.nSamplingRate; + audio->block_align = param->wma.nBlockAlign; + format->bitrate = param->wma.nBitRate; + switch(param->wma.eFormat) + { + case OMX_AUDIO_WMAFormat7: + format->encoding = MMAL_ENCODING_WMA1; + break; + case OMX_AUDIO_WMAFormat8: + case OMX_AUDIO_WMAFormat9: + format->encoding = MMAL_ENCODING_WMA2; + break; + default: break; + } + break; + case OMX_AUDIO_CodingVORBIS: + audio->channels = param->vorbis.nChannels; + audio->sample_rate = param->vorbis.nSampleRate; + format->bitrate = param->vorbis.nBitRate; + break; + case OMX_AUDIO_CodingAMR: + audio->channels = param->amr.nChannels; + audio->sample_rate = 8000; + format->bitrate = param->amr.nBitRate; + if(param->amr.eAMRBandMode >= OMX_AUDIO_AMRBandModeNB0 && + param->amr.eAMRBandMode <= OMX_AUDIO_AMRBandModeNB7) + format->encoding = MMAL_ENCODING_AMRNB; + if(param->amr.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0 && + param->amr.eAMRBandMode <= OMX_AUDIO_AMRBandModeWB8) + format->encoding = MMAL_ENCODING_AMRWB; + break; + case OMX_AUDIO_CodingDDP: + audio->channels = param->ddp.nChannels; + audio->sample_rate = param->ddp.nSampleRate; + if(param->ddp.eBitStreamId > OMX_AUDIO_DDPBitStreamIdAC3) + format->encoding = MMAL_ENCODING_EAC3; + break; + case OMX_AUDIO_CodingDTS: + audio->channels = param->dts.nChannels; + audio->sample_rate = param->dts.nSampleRate; + audio->block_align = param->dts.nDtsFrameSizeBytes; + break; + + case OMX_AUDIO_CodingADPCM: + case OMX_AUDIO_CodingGSMFR: + case OMX_AUDIO_CodingGSMEFR: + case OMX_AUDIO_CodingGSMHR: + case OMX_AUDIO_CodingPDCFR: + case OMX_AUDIO_CodingPDCEFR: + case OMX_AUDIO_CodingPDCHR: + case OMX_AUDIO_CodingTDMAFR: + case OMX_AUDIO_CodingTDMAEFR: + case OMX_AUDIO_CodingQCELP8: + case OMX_AUDIO_CodingQCELP13: + case OMX_AUDIO_CodingEVRC: + case OMX_AUDIO_CodingSMV: + case OMX_AUDIO_CodingG711: + case OMX_AUDIO_CodingG723: + case OMX_AUDIO_CodingG726: + case OMX_AUDIO_CodingG729: + case OMX_AUDIO_CodingSBC: + case OMX_AUDIO_CodingRA: + case OMX_AUDIO_CodingMIDI: + default: + vcos_assert(0); + break; + } + + return format->encoding; +} + +OMX_AUDIO_CODINGTYPE mmalil_format_to_omx_audio_param(OMX_FORMAT_PARAM_TYPE *param, + OMX_INDEXTYPE *param_index, MMAL_ES_FORMAT_T *format) +{ + MMAL_AUDIO_FORMAT_T *audio = &format->es->audio; + OMX_AUDIO_CODINGTYPE coding = mmalil_encoding_to_omx_audio_coding(format->encoding); + OMX_U32 size = 0; + OMX_INDEXTYPE index = mmalil_omx_audio_param_index(coding, &size); + + if(param_index) *param_index = index; + memset(param, 0, size); + param->common.nSize = size; + + switch(coding) + { + case OMX_AUDIO_CodingPCM: + param->pcm.nChannels = audio->channels; + param->pcm.nSamplingRate = audio->sample_rate; + param->pcm.nBitPerSample = audio->bits_per_sample; + mmalil_omx_default_channel_mapping(param->pcm.eChannelMapping, audio->channels); + if(format->encoding == MMAL_ENCODING_PCM_SIGNED_BE || + format->encoding == MMAL_ENCODING_PCM_SIGNED_LE || + format->encoding == MMAL_ENCODING_PCM_UNSIGNED_BE || + format->encoding == MMAL_ENCODING_PCM_UNSIGNED_LE) + { + param->pcm.ePCMMode = OMX_AUDIO_PCMModeLinear; + param->pcm.bInterleaved = OMX_TRUE; + param->pcm.eEndian = OMX_EndianLittle; + param->pcm.eNumData = OMX_NumericalDataSigned; + if(format->encoding == MMAL_ENCODING_PCM_SIGNED_BE || + format->encoding == MMAL_ENCODING_PCM_UNSIGNED_BE) + param->pcm.eEndian = OMX_EndianBig; + if(format->encoding == MMAL_ENCODING_PCM_UNSIGNED_LE || + format->encoding == MMAL_ENCODING_PCM_UNSIGNED_BE) + param->pcm.eNumData = OMX_NumericalDataUnsigned; + } + else if(format->encoding == MMAL_ENCODING_ALAW) + param->pcm.ePCMMode = OMX_AUDIO_PCMModeALaw; + else if(format->encoding == MMAL_ENCODING_MULAW) + param->pcm.ePCMMode = OMX_AUDIO_PCMModeMULaw; + break; + case OMX_AUDIO_CodingAAC: + param->aac.nChannels = audio->channels; + param->aac.nSampleRate = audio->sample_rate; + param->aac.nBitRate = format->bitrate; + switch(format->encoding_variant) + { + case MMAL_ENCODING_VARIANT_MP4A_ADTS: + param->aac.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4ADTS; + break; + case MMAL_ENCODING_VARIANT_MP4A_DEFAULT: + param->aac.eAACStreamFormat = OMX_AUDIO_AACStreamFormatRAW; + break; + default: break; + } + break; + case OMX_AUDIO_CodingMP3: + param->mp3.nChannels = audio->channels; + param->mp3.nSampleRate = audio->sample_rate; + param->mp3.nBitRate = format->bitrate; + break; + case OMX_AUDIO_CodingWMA: + param->wma.nChannels = audio->channels; + param->wma.nSamplingRate = audio->sample_rate; + param->wma.nBlockAlign = audio->block_align; + param->wma.nBitRate = format->bitrate; + switch(format->encoding) + { + case MMAL_ENCODING_WMA1: + param->wma.eFormat = OMX_AUDIO_WMAFormat7; + break; + case MMAL_ENCODING_WMA2: + param->wma.eFormat = OMX_AUDIO_WMAFormat8; + break; + default: break; + } + break; + case OMX_AUDIO_CodingVORBIS: + param->vorbis.nChannels = audio->channels; + param->vorbis.nSampleRate = audio->sample_rate; + param->vorbis.nBitRate = format->bitrate; + break; + case OMX_AUDIO_CodingAMR: + param->amr.nChannels = audio->channels; + param->amr.nBitRate = format->bitrate; + if(format->encoding == MMAL_ENCODING_AMRNB) + param->amr.eAMRBandMode = OMX_AUDIO_AMRBandModeNB0; + if(format->encoding == MMAL_ENCODING_AMRWB) + param->amr.eAMRBandMode = OMX_AUDIO_AMRBandModeWB0; + break; + case OMX_AUDIO_CodingDDP: + param->ddp.nChannels = audio->channels; + param->ddp.nSampleRate = audio->sample_rate; + param->ddp.eBitStreamId = OMX_AUDIO_DDPBitStreamIdAC3; + if(format->encoding == MMAL_ENCODING_EAC3) + param->ddp.eBitStreamId = OMX_AUDIO_DDPBitStreamIdEAC3; + param->ddp.eBitStreamMode = 0; + param->ddp.eDolbySurroundMode = 0; + mmalil_omx_default_channel_mapping(param->ddp.eChannelMapping, audio->channels); + break; + case OMX_AUDIO_CodingDTS: + param->dts.nChannels = audio->channels; + param->dts.nSampleRate = audio->sample_rate; + param->dts.nDtsFrameSizeBytes = audio->block_align; + param->dts.nDtsType = 1; + param->dts.nFormat = 0; + mmalil_omx_default_channel_mapping(param->dts.eChannelMapping, audio->channels); + break; + case OMX_AUDIO_CodingADPCM: + case OMX_AUDIO_CodingGSMFR: + case OMX_AUDIO_CodingGSMEFR: + case OMX_AUDIO_CodingGSMHR: + case OMX_AUDIO_CodingPDCFR: + case OMX_AUDIO_CodingPDCEFR: + case OMX_AUDIO_CodingPDCHR: + case OMX_AUDIO_CodingTDMAFR: + case OMX_AUDIO_CodingTDMAEFR: + case OMX_AUDIO_CodingQCELP8: + case OMX_AUDIO_CodingQCELP13: + case OMX_AUDIO_CodingEVRC: + case OMX_AUDIO_CodingSMV: + case OMX_AUDIO_CodingG711: + case OMX_AUDIO_CodingG723: + case OMX_AUDIO_CodingG726: + case OMX_AUDIO_CodingG729: + case OMX_AUDIO_CodingSBC: + case OMX_AUDIO_CodingRA: + case OMX_AUDIO_CodingMIDI: + default: + vcos_assert(0); + break; + } + + return coding; +} + +/*****************************************************************************/ +static struct { + uint32_t encoding; + OMX_VIDEO_CODINGTYPE coding; +} mmal_omx_video_coding_table[] = +{ + {MMAL_ENCODING_H264, OMX_VIDEO_CodingAVC}, + {MMAL_ENCODING_MP4V, OMX_VIDEO_CodingMPEG4}, + {MMAL_ENCODING_MP2V, OMX_VIDEO_CodingMPEG2}, + {MMAL_ENCODING_MP1V, OMX_VIDEO_CodingMPEG2}, + {MMAL_ENCODING_H263, OMX_VIDEO_CodingH263}, + {MMAL_ENCODING_WMV3, OMX_VIDEO_CodingWMV}, + {MMAL_ENCODING_WMV2, OMX_VIDEO_CodingWMV}, + {MMAL_ENCODING_WMV1, OMX_VIDEO_CodingWMV}, + {MMAL_ENCODING_WVC1, OMX_VIDEO_CodingWMV}, + {MMAL_ENCODING_VP6, OMX_VIDEO_CodingVP6}, + {MMAL_ENCODING_VP7, OMX_VIDEO_CodingVP7}, + {MMAL_ENCODING_VP8, OMX_VIDEO_CodingVP8}, + {MMAL_ENCODING_SPARK, OMX_VIDEO_CodingSorenson}, + {MMAL_ENCODING_THEORA, OMX_VIDEO_CodingTheora}, + {MMAL_ENCODING_MJPEG, OMX_VIDEO_CodingMJPEG}, + {MMAL_ENCODING_UNKNOWN, OMX_VIDEO_CodingUnused} +}; + +uint32_t mmalil_omx_video_coding_to_encoding(OMX_VIDEO_CODINGTYPE coding) +{ + unsigned int i; + for(i = 0; mmal_omx_video_coding_table[i].encoding != MMAL_ENCODING_UNKNOWN; i++) + if(mmal_omx_video_coding_table[i].coding == coding) break; + return mmal_omx_video_coding_table[i].encoding; +} + +OMX_VIDEO_CODINGTYPE mmalil_encoding_to_omx_video_coding(uint32_t encoding) +{ + unsigned int i; + for(i = 0; mmal_omx_video_coding_table[i].encoding != MMAL_ENCODING_UNKNOWN; i++) + if(mmal_omx_video_coding_table[i].encoding == encoding) break; + return mmal_omx_video_coding_table[i].coding; +} + +/*****************************************************************************/ +static struct { + uint32_t encoding; + OMX_IMAGE_CODINGTYPE coding; +} mmal_omx_image_coding_table[] = +{ + {MMAL_ENCODING_JPEG, OMX_IMAGE_CodingJPEG}, + {MMAL_ENCODING_GIF, OMX_IMAGE_CodingGIF}, + {MMAL_ENCODING_PNG, OMX_IMAGE_CodingPNG}, + {MMAL_ENCODING_BMP, OMX_IMAGE_CodingBMP}, + {MMAL_ENCODING_TGA, OMX_IMAGE_CodingTGA}, + {MMAL_ENCODING_PPM, OMX_IMAGE_CodingPPM}, + {MMAL_ENCODING_UNKNOWN, OMX_IMAGE_CodingUnused} +}; + +uint32_t mmalil_omx_image_coding_to_encoding(OMX_IMAGE_CODINGTYPE coding) +{ + unsigned int i; + for(i = 0; mmal_omx_image_coding_table[i].encoding != MMAL_ENCODING_UNKNOWN; i++) + if(mmal_omx_image_coding_table[i].coding == coding) break; + return mmal_omx_image_coding_table[i].encoding; +} + +OMX_IMAGE_CODINGTYPE mmalil_encoding_to_omx_image_coding(uint32_t encoding) +{ + unsigned int i; + for(i = 0; mmal_omx_image_coding_table[i].encoding != MMAL_ENCODING_UNKNOWN; i++) + if(mmal_omx_image_coding_table[i].encoding == encoding) break; + return mmal_omx_image_coding_table[i].coding; +} + +uint32_t mmalil_omx_coding_to_encoding(uint32_t encoding, OMX_PORTDOMAINTYPE domain) +{ + if(domain == OMX_PortDomainVideo) + return mmalil_omx_video_coding_to_encoding((OMX_VIDEO_CODINGTYPE)encoding); + else if(domain == OMX_PortDomainAudio) + return mmalil_omx_audio_coding_to_encoding((OMX_AUDIO_CODINGTYPE)encoding); + else if(domain == OMX_PortDomainImage) + return mmalil_omx_image_coding_to_encoding((OMX_IMAGE_CODINGTYPE)encoding); + else + return MMAL_ENCODING_UNKNOWN; +} + +/*****************************************************************************/ +static struct { + uint32_t encoding; + OMX_COLOR_FORMATTYPE coding; +} mmal_omx_colorformat_coding_table[] = +{ + {MMAL_ENCODING_I420, OMX_COLOR_FormatYUV420PackedPlanar}, + {MMAL_ENCODING_I422, OMX_COLOR_FormatYUV422PackedPlanar}, + {MMAL_ENCODING_I420_SLICE, OMX_COLOR_FormatYUV420PackedPlanar}, + {MMAL_ENCODING_I422_SLICE, OMX_COLOR_FormatYUV422PackedPlanar}, + {MMAL_ENCODING_I420, OMX_COLOR_FormatYUV420Planar}, + {MMAL_ENCODING_YV12, OMX_COLOR_FormatYVU420PackedPlanar}, + {MMAL_ENCODING_NV12, OMX_COLOR_FormatYUV420PackedSemiPlanar}, + {MMAL_ENCODING_NV12, OMX_COLOR_FormatYUV420SemiPlanar}, + {MMAL_ENCODING_NV21, OMX_COLOR_FormatYVU420PackedSemiPlanar}, + {MMAL_ENCODING_YUVUV128, OMX_COLOR_FormatYUVUV128}, + {MMAL_ENCODING_YUYV, OMX_COLOR_FormatYCbYCr}, + {MMAL_ENCODING_YVYU, OMX_COLOR_FormatYCrYCb}, + {MMAL_ENCODING_UYVY, OMX_COLOR_FormatCbYCrY}, + {MMAL_ENCODING_VYUY, OMX_COLOR_FormatCrYCbY}, + {MMAL_ENCODING_RGB16, OMX_COLOR_Format16bitRGB565}, + {MMAL_ENCODING_BGR24, OMX_COLOR_Format24bitRGB888}, + {MMAL_ENCODING_BGRA, OMX_COLOR_Format32bitARGB8888}, + {MMAL_ENCODING_BGR16, OMX_COLOR_Format16bitBGR565}, + {MMAL_ENCODING_RGB24, OMX_COLOR_Format24bitBGR888}, + {MMAL_ENCODING_ARGB, OMX_COLOR_Format32bitBGRA8888}, + {MMAL_ENCODING_RGBA, OMX_COLOR_Format32bitABGR8888}, + {MMAL_ENCODING_EGL_IMAGE, OMX_COLOR_FormatBRCMEGL}, + {MMAL_ENCODING_OPAQUE, OMX_COLOR_FormatBRCMOpaque}, + {MMAL_ENCODING_UNKNOWN, OMX_COLOR_FormatUnused} +}; + +uint32_t mmalil_omx_color_format_to_encoding(OMX_COLOR_FORMATTYPE coding) +{ + unsigned int i; + for(i = 0; mmal_omx_colorformat_coding_table[i].encoding != MMAL_ENCODING_UNKNOWN; i++) + if(mmal_omx_colorformat_coding_table[i].coding == coding) break; + return mmal_omx_colorformat_coding_table[i].encoding; +} + +OMX_COLOR_FORMATTYPE mmalil_encoding_to_omx_color_format(uint32_t encoding) +{ + unsigned int i; + for(i = 0; mmal_omx_colorformat_coding_table[i].encoding != MMAL_ENCODING_UNKNOWN; i++) + if(mmal_omx_colorformat_coding_table[i].encoding == encoding) break; + return mmal_omx_colorformat_coding_table[i].coding; +} + +/*****************************************************************************/ +static struct { + uint32_t mmal; + OMX_COLORSPACETYPE omx; +} mmal_omx_colorspace_coding_table[] = +{ + {MMAL_COLOR_SPACE_ITUR_BT601, OMX_COLORSPACE_ITU_R_BT601}, + {MMAL_COLOR_SPACE_ITUR_BT709, OMX_COLORSPACE_ITU_R_BT709}, + {MMAL_COLOR_SPACE_JPEG_JFIF, OMX_COLORSPACE_JPEG_JFIF}, + {MMAL_COLOR_SPACE_FCC, OMX_COLORSPACE_FCC}, + {MMAL_COLOR_SPACE_SMPTE240M, OMX_COLORSPACE_SMPTE240M}, + {MMAL_COLOR_SPACE_BT470_2_M, OMX_COLORSPACE_BT470_2_M}, + {MMAL_COLOR_SPACE_BT470_2_BG, OMX_COLORSPACE_BT470_2_BG}, + {MMAL_COLOR_SPACE_JFIF_Y16_255, OMX_COLORSPACE_JFIF_Y16_255}, + {MMAL_COLOR_SPACE_UNKNOWN, OMX_COLORSPACE_UNKNOWN} +}; + +uint32_t mmalil_omx_color_space_to_mmal(OMX_COLORSPACETYPE coding) +{ + unsigned int i; + for(i = 0; mmal_omx_colorspace_coding_table[i].mmal != MMAL_COLOR_SPACE_UNKNOWN; i++) + if(mmal_omx_colorspace_coding_table[i].omx == coding) break; + return mmal_omx_colorspace_coding_table[i].mmal; +} + +OMX_COLORSPACETYPE mmalil_color_space_to_omx(uint32_t coding) +{ + unsigned int i; + for(i = 0; mmal_omx_colorspace_coding_table[i].mmal != MMAL_COLOR_SPACE_UNKNOWN; i++) + if(mmal_omx_colorspace_coding_table[i].mmal == coding) break; + return mmal_omx_colorspace_coding_table[i].omx; +} + +/*****************************************************************************/ +static struct { + uint32_t mmal; + OMX_U32 omx; + OMX_VIDEO_CODINGTYPE omx_coding; +} mmal_omx_video_profile_table[] = +{ + { MMAL_VIDEO_PROFILE_H263_BASELINE, OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_CodingH263}, + { MMAL_VIDEO_PROFILE_H263_H320CODING, OMX_VIDEO_H263ProfileH320Coding, OMX_VIDEO_CodingH263}, + { MMAL_VIDEO_PROFILE_H263_BACKWARDCOMPATIBLE, OMX_VIDEO_H263ProfileBackwardCompatible, OMX_VIDEO_CodingH263}, + { MMAL_VIDEO_PROFILE_H263_ISWV2, OMX_VIDEO_H263ProfileISWV2, OMX_VIDEO_CodingH263}, + { MMAL_VIDEO_PROFILE_H263_ISWV3, OMX_VIDEO_H263ProfileISWV3, OMX_VIDEO_CodingH263}, + { MMAL_VIDEO_PROFILE_H263_HIGHCOMPRESSION, OMX_VIDEO_H263ProfileHighCompression, OMX_VIDEO_CodingH263}, + { MMAL_VIDEO_PROFILE_H263_INTERNET, OMX_VIDEO_H263ProfileInternet, OMX_VIDEO_CodingH263}, + { MMAL_VIDEO_PROFILE_H263_INTERLACE, OMX_VIDEO_H263ProfileInterlace, OMX_VIDEO_CodingH263}, + { MMAL_VIDEO_PROFILE_H263_HIGHLATENCY, OMX_VIDEO_H263ProfileHighLatency, OMX_VIDEO_CodingH263}, + { MMAL_VIDEO_PROFILE_MP4V_SIMPLE, OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_CodingMPEG4}, + { MMAL_VIDEO_PROFILE_MP4V_SIMPLESCALABLE, OMX_VIDEO_MPEG4ProfileSimpleScalable, OMX_VIDEO_CodingMPEG4}, + { MMAL_VIDEO_PROFILE_MP4V_CORE, OMX_VIDEO_MPEG4ProfileCore, OMX_VIDEO_CodingMPEG4}, + { MMAL_VIDEO_PROFILE_MP4V_MAIN, OMX_VIDEO_MPEG4ProfileMain, OMX_VIDEO_CodingMPEG4}, + { MMAL_VIDEO_PROFILE_MP4V_NBIT, OMX_VIDEO_MPEG4ProfileNbit, OMX_VIDEO_CodingMPEG4}, + { MMAL_VIDEO_PROFILE_MP4V_SCALABLETEXTURE, OMX_VIDEO_MPEG4ProfileScalableTexture, OMX_VIDEO_CodingMPEG4}, + { MMAL_VIDEO_PROFILE_MP4V_SIMPLEFACE, OMX_VIDEO_MPEG4ProfileSimpleFace, OMX_VIDEO_CodingMPEG4}, + { MMAL_VIDEO_PROFILE_MP4V_SIMPLEFBA, OMX_VIDEO_MPEG4ProfileSimpleFBA, OMX_VIDEO_CodingMPEG4}, + { MMAL_VIDEO_PROFILE_MP4V_BASICANIMATED, OMX_VIDEO_MPEG4ProfileBasicAnimated, OMX_VIDEO_CodingMPEG4}, + { MMAL_VIDEO_PROFILE_MP4V_HYBRID, OMX_VIDEO_MPEG4ProfileHybrid, OMX_VIDEO_CodingMPEG4}, + { MMAL_VIDEO_PROFILE_MP4V_ADVANCEDREALTIME, OMX_VIDEO_MPEG4ProfileAdvancedRealTime, OMX_VIDEO_CodingMPEG4}, + { MMAL_VIDEO_PROFILE_MP4V_CORESCALABLE, OMX_VIDEO_MPEG4ProfileCoreScalable, OMX_VIDEO_CodingMPEG4}, + { MMAL_VIDEO_PROFILE_MP4V_ADVANCEDCODING, OMX_VIDEO_MPEG4ProfileAdvancedCoding, OMX_VIDEO_CodingMPEG4}, + { MMAL_VIDEO_PROFILE_MP4V_ADVANCEDCORE, OMX_VIDEO_MPEG4ProfileAdvancedCore, OMX_VIDEO_CodingMPEG4}, + { MMAL_VIDEO_PROFILE_MP4V_ADVANCEDSCALABLE, OMX_VIDEO_MPEG4ProfileAdvancedScalable, OMX_VIDEO_CodingMPEG4}, + { MMAL_VIDEO_PROFILE_MP4V_ADVANCEDSIMPLE, OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_CodingMPEG4}, + { MMAL_VIDEO_PROFILE_H264_BASELINE, OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_CodingAVC}, + { MMAL_VIDEO_PROFILE_H264_MAIN, OMX_VIDEO_AVCProfileMain, OMX_VIDEO_CodingAVC}, + { MMAL_VIDEO_PROFILE_H264_EXTENDED, OMX_VIDEO_AVCProfileExtended, OMX_VIDEO_CodingAVC}, + { MMAL_VIDEO_PROFILE_H264_HIGH, OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_CodingAVC}, + { MMAL_VIDEO_PROFILE_H264_HIGH10, OMX_VIDEO_AVCProfileHigh10, OMX_VIDEO_CodingAVC}, + { MMAL_VIDEO_PROFILE_H264_HIGH422, OMX_VIDEO_AVCProfileHigh422, OMX_VIDEO_CodingAVC}, + { MMAL_VIDEO_PROFILE_H264_HIGH444, OMX_VIDEO_AVCProfileHigh444, OMX_VIDEO_CodingAVC}, + { MMAL_VIDEO_PROFILE_H264_CONSTRAINED_BASELINE, OMX_VIDEO_AVCProfileConstrainedBaseline, OMX_VIDEO_CodingAVC}, + { MMAL_VIDEO_PROFILE_DUMMY, OMX_VIDEO_AVCProfileMax, OMX_VIDEO_CodingAVC}, +}; + +uint32_t mmalil_omx_video_profile_to_mmal(OMX_U32 profile, OMX_VIDEO_CODINGTYPE coding) +{ + unsigned int i; + for(i = 0; mmal_omx_video_profile_table[i].mmal != MMAL_VIDEO_PROFILE_DUMMY; i++) + if(mmal_omx_video_profile_table[i].omx == profile + && mmal_omx_video_profile_table[i].omx_coding == coding) break; + return mmal_omx_video_profile_table[i].mmal; +} + +OMX_U32 mmalil_video_profile_to_omx(uint32_t profile) +{ + unsigned int i; + for(i = 0; mmal_omx_video_profile_table[i].mmal != MMAL_VIDEO_PROFILE_DUMMY; i++) + if(mmal_omx_video_profile_table[i].mmal == profile) break; + return mmal_omx_video_profile_table[i].omx; +} + +/*****************************************************************************/ +static struct { + uint32_t mmal; + OMX_U32 omx; + OMX_VIDEO_CODINGTYPE omx_coding; +} mmal_omx_video_level_table[] = +{ + { MMAL_VIDEO_LEVEL_H263_10, OMX_VIDEO_H263Level10, OMX_VIDEO_CodingH263}, + { MMAL_VIDEO_LEVEL_H263_20, OMX_VIDEO_H263Level20, OMX_VIDEO_CodingH263}, + { MMAL_VIDEO_LEVEL_H263_30, OMX_VIDEO_H263Level30, OMX_VIDEO_CodingH263}, + { MMAL_VIDEO_LEVEL_H263_40, OMX_VIDEO_H263Level40, OMX_VIDEO_CodingH263}, + { MMAL_VIDEO_LEVEL_H263_45, OMX_VIDEO_H263Level45, OMX_VIDEO_CodingH263}, + { MMAL_VIDEO_LEVEL_H263_50, OMX_VIDEO_H263Level50, OMX_VIDEO_CodingH263}, + { MMAL_VIDEO_LEVEL_H263_60, OMX_VIDEO_H263Level60, OMX_VIDEO_CodingH263}, + { MMAL_VIDEO_LEVEL_H263_70, OMX_VIDEO_H263Level70, OMX_VIDEO_CodingH263}, + { MMAL_VIDEO_LEVEL_MP4V_0, OMX_VIDEO_MPEG4Level0, OMX_VIDEO_CodingMPEG4}, + { MMAL_VIDEO_LEVEL_MP4V_0b, OMX_VIDEO_MPEG4Level0b, OMX_VIDEO_CodingMPEG4}, + { MMAL_VIDEO_LEVEL_MP4V_1, OMX_VIDEO_MPEG4Level1, OMX_VIDEO_CodingMPEG4}, + { MMAL_VIDEO_LEVEL_MP4V_2, OMX_VIDEO_MPEG4Level2, OMX_VIDEO_CodingMPEG4}, + { MMAL_VIDEO_LEVEL_MP4V_3, OMX_VIDEO_MPEG4Level3, OMX_VIDEO_CodingMPEG4}, + { MMAL_VIDEO_LEVEL_MP4V_4, OMX_VIDEO_MPEG4Level4, OMX_VIDEO_CodingMPEG4}, + { MMAL_VIDEO_LEVEL_MP4V_4a, OMX_VIDEO_MPEG4Level4a, OMX_VIDEO_CodingMPEG4}, + { MMAL_VIDEO_LEVEL_MP4V_5, OMX_VIDEO_MPEG4Level5, OMX_VIDEO_CodingMPEG4}, + { MMAL_VIDEO_LEVEL_MP4V_6, OMX_VIDEO_MPEG4Level6, OMX_VIDEO_CodingMPEG4}, + { MMAL_VIDEO_LEVEL_H264_1, OMX_VIDEO_AVCLevel1, OMX_VIDEO_CodingAVC}, + { MMAL_VIDEO_LEVEL_H264_1b, OMX_VIDEO_AVCLevel1b, OMX_VIDEO_CodingAVC}, + { MMAL_VIDEO_LEVEL_H264_11, OMX_VIDEO_AVCLevel11, OMX_VIDEO_CodingAVC}, + { MMAL_VIDEO_LEVEL_H264_12, OMX_VIDEO_AVCLevel12, OMX_VIDEO_CodingAVC}, + { MMAL_VIDEO_LEVEL_H264_13, OMX_VIDEO_AVCLevel13, OMX_VIDEO_CodingAVC}, + { MMAL_VIDEO_LEVEL_H264_2, OMX_VIDEO_AVCLevel2, OMX_VIDEO_CodingAVC}, + { MMAL_VIDEO_LEVEL_H264_21, OMX_VIDEO_AVCLevel21, OMX_VIDEO_CodingAVC}, + { MMAL_VIDEO_LEVEL_H264_22, OMX_VIDEO_AVCLevel22, OMX_VIDEO_CodingAVC}, + { MMAL_VIDEO_LEVEL_H264_3, OMX_VIDEO_AVCLevel3, OMX_VIDEO_CodingAVC}, + { MMAL_VIDEO_LEVEL_H264_31, OMX_VIDEO_AVCLevel31, OMX_VIDEO_CodingAVC}, + { MMAL_VIDEO_LEVEL_H264_32, OMX_VIDEO_AVCLevel32, OMX_VIDEO_CodingAVC}, + { MMAL_VIDEO_LEVEL_H264_4, OMX_VIDEO_AVCLevel4, OMX_VIDEO_CodingAVC}, + { MMAL_VIDEO_LEVEL_H264_41, OMX_VIDEO_AVCLevel41, OMX_VIDEO_CodingAVC}, + { MMAL_VIDEO_LEVEL_H264_42, OMX_VIDEO_AVCLevel42, OMX_VIDEO_CodingAVC}, + { MMAL_VIDEO_LEVEL_H264_5, OMX_VIDEO_AVCLevel5, OMX_VIDEO_CodingAVC}, + { MMAL_VIDEO_LEVEL_H264_51, OMX_VIDEO_AVCLevel51, OMX_VIDEO_CodingAVC}, + { MMAL_VIDEO_LEVEL_DUMMY, OMX_VIDEO_AVCLevelMax, OMX_VIDEO_CodingMax}, +}; + +uint32_t mmalil_omx_video_level_to_mmal(OMX_U32 level, OMX_VIDEO_CODINGTYPE coding) +{ + unsigned int i; + for(i = 0; mmal_omx_video_level_table[i].mmal != MMAL_VIDEO_LEVEL_DUMMY; i++) + if(mmal_omx_video_level_table[i].omx == level + && mmal_omx_video_level_table[i].omx_coding == coding) break; + return mmal_omx_video_level_table[i].mmal; +} + +OMX_U32 mmalil_video_level_to_omx(uint32_t level) +{ + unsigned int i; + for(i = 0; mmal_omx_video_level_table[i].mmal != MMAL_VIDEO_LEVEL_DUMMY; i++) + if(mmal_omx_video_level_table[i].mmal == level) break; + return mmal_omx_video_level_table[i].omx; +} + +/*****************************************************************************/ +static struct { + MMAL_VIDEO_RATECONTROL_T mmal; + OMX_VIDEO_CONTROLRATETYPE omx; +} mmal_omx_video_ratecontrol_table[] = +{ + { MMAL_VIDEO_RATECONTROL_DEFAULT, OMX_Video_ControlRateDisable}, + { MMAL_VIDEO_RATECONTROL_VARIABLE, OMX_Video_ControlRateVariable}, + { MMAL_VIDEO_RATECONTROL_CONSTANT, OMX_Video_ControlRateConstant}, + { MMAL_VIDEO_RATECONTROL_VARIABLE_SKIP_FRAMES, OMX_Video_ControlRateVariableSkipFrames}, + { MMAL_VIDEO_RATECONTROL_CONSTANT_SKIP_FRAMES, OMX_Video_ControlRateConstantSkipFrames}, + { MMAL_VIDEO_RATECONTROL_DUMMY, OMX_Video_ControlRateMax}, +}; + +MMAL_VIDEO_RATECONTROL_T mmalil_omx_video_ratecontrol_to_mmal(OMX_VIDEO_CONTROLRATETYPE omx) +{ + unsigned int i; + for(i = 0; mmal_omx_video_ratecontrol_table[i].mmal != MMAL_VIDEO_RATECONTROL_DUMMY; i++) + if(mmal_omx_video_ratecontrol_table[i].omx == omx) break; + return mmal_omx_video_ratecontrol_table[i].mmal; +} + +OMX_VIDEO_CONTROLRATETYPE mmalil_video_ratecontrol_to_omx(MMAL_VIDEO_RATECONTROL_T mmal) +{ + unsigned int i; + for(i = 0; mmal_omx_video_ratecontrol_table[i].mmal != MMAL_VIDEO_RATECONTROL_DUMMY; i++) + if(mmal_omx_video_ratecontrol_table[i].mmal == mmal) break; + return mmal_omx_video_ratecontrol_table[i].omx; +} + +/*****************************************************************************/ +static struct { + MMAL_VIDEO_INTRA_REFRESH_T mmal; + OMX_VIDEO_INTRAREFRESHTYPE omx; +} mmal_omx_video_intrarefresh_table[] = +{ + { MMAL_VIDEO_INTRA_REFRESH_CYCLIC, OMX_VIDEO_IntraRefreshCyclic}, + { MMAL_VIDEO_INTRA_REFRESH_ADAPTIVE, OMX_VIDEO_IntraRefreshAdaptive}, + { MMAL_VIDEO_INTRA_REFRESH_BOTH, OMX_VIDEO_IntraRefreshBoth}, + { MMAL_VIDEO_INTRA_REFRESH_KHRONOSEXTENSIONS, OMX_VIDEO_IntraRefreshKhronosExtensions}, + { MMAL_VIDEO_INTRA_REFRESH_VENDORSTARTUNUSED, OMX_VIDEO_IntraRefreshVendorStartUnused}, + { MMAL_VIDEO_INTRA_REFRESH_DUMMY, OMX_VIDEO_IntraRefreshMax}, +}; + +MMAL_VIDEO_INTRA_REFRESH_T mmalil_omx_video_intrarefresh_to_mmal(OMX_VIDEO_INTRAREFRESHTYPE omx) +{ + unsigned int i; + for(i = 0; mmal_omx_video_intrarefresh_table[i].mmal != MMAL_VIDEO_INTRA_REFRESH_DUMMY; i++) + if(mmal_omx_video_intrarefresh_table[i].omx == omx) break; + return mmal_omx_video_intrarefresh_table[i].mmal; +} diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/util/mmal_il.h b/external_src/raspicam-0.1.3/dependencies/mmal/util/mmal_il.h new file mode 100644 index 0000000..b13cbef --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/util/mmal_il.h @@ -0,0 +1,212 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 MMAL_IL_H +#define MMAL_IL_H + +/** \defgroup MmalILUtility MMAL to OMX IL conversion utilities + * \ingroup MmalUtilities + * + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "interface/vmcs_host/khronos/IL/OMX_Core.h" +#include "interface/vmcs_host/khronos/IL/OMX_Component.h" +#include "interface/vmcs_host/khronos/IL/OMX_Video.h" +#include "interface/vmcs_host/khronos/IL/OMX_Audio.h" +#include "interface/vmcs_host/khronos/IL/OMX_Broadcom.h" + +/** Convert MMAL status codes into OMX error codes. + * + * @param status MMAL status code. + * @return OMX error code. + */ +OMX_ERRORTYPE mmalil_error_to_omx(MMAL_STATUS_T status); + +/** Convert OMX error codes into MMAL status codes. + * + * @param error OMX error code. + * @return MMAL status code. + */ +MMAL_STATUS_T mmalil_error_to_mmal(OMX_ERRORTYPE error); + +/** Convert MMAL buffer header flags into OMX buffer header flags. + * + * @param flags OMX buffer header flags. + * @return MMAL buffer header flags. + */ +uint32_t mmalil_buffer_flags_to_mmal(OMX_U32 flags); + +/** Convert OMX buffer header flags into MMAL buffer header flags. + * + * @param flags MMAL buffer header flags. + * @return OMX buffer header flags. + */ +OMX_U32 mmalil_buffer_flags_to_omx(uint32_t flags); + +/** Convert a MMAL buffer header into an OMX buffer header. + * Note that only the fields which have a direct mapping between OMX and MMAL are converted. + * + * @param omx Pointer to the destination OMX buffer header. + * @param mmal Pointer to the source MMAL buffer header. + */ +void mmalil_buffer_header_to_omx(OMX_BUFFERHEADERTYPE *omx, MMAL_BUFFER_HEADER_T *mmal); + +/** Convert an OMX buffer header into a MMAL buffer header. + * + * @param mmal Pointer to the destination MMAL buffer header. + * @param omx Pointer to the source OMX buffer header. + */ +void mmalil_buffer_header_to_mmal(MMAL_BUFFER_HEADER_T *mmal, OMX_BUFFERHEADERTYPE *omx); + + +OMX_PORTDOMAINTYPE mmalil_es_type_to_omx_domain(MMAL_ES_TYPE_T type); +MMAL_ES_TYPE_T mmalil_omx_domain_to_es_type(OMX_PORTDOMAINTYPE domain); +uint32_t mmalil_omx_audio_coding_to_encoding(OMX_AUDIO_CODINGTYPE coding); +OMX_AUDIO_CODINGTYPE mmalil_encoding_to_omx_audio_coding(uint32_t encoding); +uint32_t mmalil_omx_video_coding_to_encoding(OMX_VIDEO_CODINGTYPE coding); +OMX_VIDEO_CODINGTYPE mmalil_encoding_to_omx_video_coding(uint32_t encoding); +uint32_t mmalil_omx_image_coding_to_encoding(OMX_IMAGE_CODINGTYPE coding); +OMX_IMAGE_CODINGTYPE mmalil_encoding_to_omx_image_coding(uint32_t encoding); +uint32_t mmalil_omx_coding_to_encoding(uint32_t encoding, OMX_PORTDOMAINTYPE domain); +uint32_t mmalil_omx_color_format_to_encoding(OMX_COLOR_FORMATTYPE coding); +OMX_COLOR_FORMATTYPE mmalil_encoding_to_omx_color_format(uint32_t encoding); +uint32_t mmalil_omx_color_space_to_mmal(OMX_COLORSPACETYPE coding); +OMX_COLORSPACETYPE mmalil_color_space_to_omx(uint32_t coding); +uint32_t mmalil_omx_video_profile_to_mmal(OMX_U32 level, OMX_VIDEO_CODINGTYPE coding); +OMX_U32 mmalil_video_profile_to_omx(uint32_t profile); +uint32_t mmalil_omx_video_level_to_mmal(OMX_U32 level, OMX_VIDEO_CODINGTYPE coding); +OMX_U32 mmalil_video_level_to_omx(uint32_t level); +MMAL_VIDEO_RATECONTROL_T mmalil_omx_video_ratecontrol_to_mmal(OMX_VIDEO_CONTROLRATETYPE omx); +OMX_VIDEO_CONTROLRATETYPE mmalil_video_ratecontrol_to_omx(MMAL_VIDEO_RATECONTROL_T mmal); +MMAL_VIDEO_INTRA_REFRESH_T mmalil_omx_video_intrarefresh_to_mmal(OMX_VIDEO_INTRAREFRESHTYPE omx); + +/** Union of all the OMX_VIDEO/AUDIO_PARAM types */ +typedef union OMX_FORMAT_PARAM_TYPE { + OMX_PARAM_U32TYPE common; + + /* Video */ + OMX_VIDEO_PARAM_AVCTYPE avc; + OMX_VIDEO_PARAM_H263TYPE h263; + OMX_VIDEO_PARAM_MPEG2TYPE mpeg2; + OMX_VIDEO_PARAM_MPEG4TYPE mpeg4; + OMX_VIDEO_PARAM_WMVTYPE wmv; + OMX_VIDEO_PARAM_RVTYPE rv; + + /* Audio */ + OMX_AUDIO_PARAM_PCMMODETYPE pcm; + OMX_AUDIO_PARAM_MP3TYPE mp3; + OMX_AUDIO_PARAM_AACPROFILETYPE aac; + OMX_AUDIO_PARAM_VORBISTYPE vorbis; + OMX_AUDIO_PARAM_WMATYPE wma; + OMX_AUDIO_PARAM_RATYPE ra; + OMX_AUDIO_PARAM_SBCTYPE sbc; + OMX_AUDIO_PARAM_ADPCMTYPE adpcm; + OMX_AUDIO_PARAM_G723TYPE g723; + OMX_AUDIO_PARAM_G726TYPE g726; + OMX_AUDIO_PARAM_G729TYPE g729; + OMX_AUDIO_PARAM_AMRTYPE amr; + OMX_AUDIO_PARAM_GSMFRTYPE gsmfr; + OMX_AUDIO_PARAM_GSMHRTYPE gsmhr; + OMX_AUDIO_PARAM_GSMEFRTYPE gsmefr; + OMX_AUDIO_PARAM_TDMAFRTYPE tdmafr; + OMX_AUDIO_PARAM_TDMAEFRTYPE tdmaefr; + OMX_AUDIO_PARAM_PDCFRTYPE pdcfr; + OMX_AUDIO_PARAM_PDCEFRTYPE pdcefr; + OMX_AUDIO_PARAM_PDCHRTYPE pdchr; + OMX_AUDIO_PARAM_QCELP8TYPE qcelp8; + OMX_AUDIO_PARAM_QCELP13TYPE qcelp13; + OMX_AUDIO_PARAM_EVRCTYPE evrc; + OMX_AUDIO_PARAM_SMVTYPE smv; + OMX_AUDIO_PARAM_MIDITYPE midi; +#ifdef OMX_AUDIO_CodingDDP_Supported + OMX_AUDIO_PARAM_DDPTYPE ddp; +#endif +#ifdef OMX_AUDIO_CodingDTS_Supported + OMX_AUDIO_PARAM_DTSTYPE dts; +#endif + +} OMX_FORMAT_PARAM_TYPE; + +/** Get the OMX_IndexParamAudio index corresponding to a specified audio coding type. + * + * @param coding Audio coding type. + * @param size Pointer used to return the size of the parameter. + * + * @return OMX index or 0 if no match was found. + */ +OMX_INDEXTYPE mmalil_omx_audio_param_index(OMX_AUDIO_CODINGTYPE coding, OMX_U32 *size); + +/** Get the audio coding corresponding to a specified OMX_IndexParamAudio index. + * + * @param index Audio coding type. + * + * @return Audio coding type. + */ +OMX_AUDIO_CODINGTYPE mmalil_omx_audio_param_index_to_coding(OMX_INDEXTYPE index); + +/** Setup a default channel mapping based on the number of channels + * @param channel_mapping The output channel mapping + * @param nchannels Number of channels + * + * @return MMAL_SUCCESS if we managed to produce a channel mapping + */ +MMAL_STATUS_T mmalil_omx_default_channel_mapping(OMX_AUDIO_CHANNELTYPE *channel_mapping, unsigned int nchannels); + +/** Convert an OMX_IndexParamAudio into a MMAL elementary stream format. + * + * @param format Format structure to update. + * @param coding Audio coding type. + * @param param Source OMX_IndexParamAudio structure. + * + * @return The MMAL encoding if a match was found or MMAL_ENCODING_UNKNOWN otherwise. + */ +MMAL_FOURCC_T mmalil_omx_audio_param_to_format(MMAL_ES_FORMAT_T *format, + OMX_AUDIO_CODINGTYPE coding, OMX_FORMAT_PARAM_TYPE *param); + +/** Convert a MMAL elementary stream format into a OMX_IndexParamAudio structure. + * + * @param param OMX_IndexParamAudio structure to update. + * @param param_index returns the OMX_IndexParamAudio index corresponding to the format. + * @param format Source format structure. + * + * @return The OMX aduio coding type if a match was found or OMX_AUDIO_CodingUnused otherwise. + */ +OMX_AUDIO_CODINGTYPE mmalil_format_to_omx_audio_param(OMX_FORMAT_PARAM_TYPE *param, + OMX_INDEXTYPE *param_index, MMAL_ES_FORMAT_T *format); + +#ifdef __cplusplus +} +#endif + +/** @} */ + +#endif /* MMAL_IL_H */ diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/util/mmal_list.c b/external_src/raspicam-0.1.3/dependencies/mmal/util/mmal_list.c new file mode 100644 index 0000000..6f45d78 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/util/mmal_list.c @@ -0,0 +1,221 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 "interface/vcos/vcos.h" +#include "interface/mmal/util/mmal_list.h" + + +/* Private list context */ +typedef struct MMAL_LIST_PRIVATE_T +{ + MMAL_LIST_T list; /* must be first */ + VCOS_MUTEX_T lock; +} MMAL_LIST_PRIVATE_T; + + +/* Lock the list. */ +static inline void mmal_list_lock(MMAL_LIST_T *list) +{ + vcos_mutex_lock(&((MMAL_LIST_PRIVATE_T*)list)->lock); +} + +/* Unlock the list. */ +static inline void mmal_list_unlock(MMAL_LIST_T *list) +{ + vcos_mutex_unlock(&((MMAL_LIST_PRIVATE_T*)list)->lock); +} + +/* Create a new linked list. */ +MMAL_LIST_T* mmal_list_create(void) +{ + MMAL_LIST_PRIVATE_T *private; + + private = vcos_malloc(sizeof(MMAL_LIST_PRIVATE_T), "mmal-list"); + if (private == NULL) + goto error; + + if (vcos_mutex_create(&private->lock, "mmal-list lock") != VCOS_SUCCESS) + goto error; + + /* lock to keep coverity happy */ + vcos_mutex_lock(&private->lock); + private->list.first = NULL; + private->list.last = NULL; + private->list.length = 0; + vcos_mutex_unlock(&private->lock); + + return &private->list; + +error: + vcos_free(private); + return NULL; +} + +/* Destroy a linked list. */ +void mmal_list_destroy(MMAL_LIST_T *list) +{ + MMAL_LIST_PRIVATE_T *private = (MMAL_LIST_PRIVATE_T*)list; + + vcos_mutex_delete(&private->lock); + vcos_free(private); +} + +/* Remove the last element in the list. */ +MMAL_LIST_ELEMENT_T* mmal_list_pop_back(MMAL_LIST_T *list) +{ + MMAL_LIST_ELEMENT_T *element; + + mmal_list_lock(list); + + element = list->last; + if (element != NULL) + { + list->length--; + + list->last = element->prev; + if (list->last) + list->last->next = NULL; + else + list->first = NULL; /* list is now empty */ + + element->prev = NULL; + element->next = NULL; + } + + mmal_list_unlock(list); + + return element; +} + +/* Remove the first element in the list. */ +MMAL_LIST_ELEMENT_T* mmal_list_pop_front(MMAL_LIST_T *list) +{ + MMAL_LIST_ELEMENT_T *element; + + mmal_list_lock(list); + + element = list->first; + if (element != NULL) + { + list->length--; + + list->first = element->next; + if (list->first) + list->first->prev = NULL; + else + list->last = NULL; /* list is now empty */ + + element->prev = NULL; + element->next = NULL; + } + + mmal_list_unlock(list); + + return element; +} + +/* Add an element to the front of the list. */ +void mmal_list_push_front(MMAL_LIST_T *list, MMAL_LIST_ELEMENT_T *element) +{ + mmal_list_lock(list); + + list->length++; + + element->prev = NULL; + element->next = list->first; + + if (list->first) + list->first->prev = element; + else + list->last = element; /* list was empty */ + + list->first = element; + + mmal_list_unlock(list); +} + +/* Add an element to the back of the list. */ +void mmal_list_push_back(MMAL_LIST_T *list, MMAL_LIST_ELEMENT_T *element) +{ + mmal_list_lock(list); + + list->length++; + + element->next = NULL; + element->prev = list->last; + + if (list->last) + list->last->next = element; + else + list->first = element; /* list was empty */ + + list->last = element; + + mmal_list_unlock(list); +} + +/* Insert an element into the list. */ +void mmal_list_insert(MMAL_LIST_T *list, MMAL_LIST_ELEMENT_T *element, MMAL_LIST_COMPARE_T compare) +{ + MMAL_LIST_ELEMENT_T *cur; + + mmal_list_lock(list); + + if (list->first == NULL) + { + /* List empty */ + mmal_list_unlock(list); + mmal_list_push_front(list, element); + return; + } + + cur = list->first; + while (cur) + { + if (compare(element, cur)) + { + /* Slot found! */ + list->length++; + if (cur == list->first) + list->first = element; + else + cur->prev->next = element; + element->prev = cur->prev; + element->next = cur; + cur->prev = element; + mmal_list_unlock(list); + return; + } + + cur = cur->next; + } + + /* If we get here, none of the existing elements are greater + * than the new on, so just add it to the back of the list */ + mmal_list_unlock(list); + mmal_list_push_back(list, element); +} diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/util/mmal_list.h b/external_src/raspicam-0.1.3/dependencies/mmal/util/mmal_list.h new file mode 100644 index 0000000..967cc7b --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/util/mmal_list.h @@ -0,0 +1,127 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 MMAL_LIST_H +#define MMAL_LIST_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup MmalList Generic Linked List + * This provides a thread-safe implementation of a linked list which can be used + * with any data type. */ +/* @{ */ + +/** Single element in the list */ +typedef struct MMAL_LIST_ELEMENT_T +{ + struct MMAL_LIST_ELEMENT_T *next; + struct MMAL_LIST_ELEMENT_T *prev; +} MMAL_LIST_ELEMENT_T; + +/** Linked list type. + * Clients shouldn't modify this directly. Use the provided API functions to + * add new elements. The public members are only for debug purposes. + * */ +typedef struct MMAL_LIST_T +{ + unsigned int length; /**< Number of elements in the list (read-only) */ + MMAL_LIST_ELEMENT_T *first; /**< First element in the list (read-only) */ + MMAL_LIST_ELEMENT_T *last; /**< Last element in the list (read-only) */ +} MMAL_LIST_T; + +/** Create a new linked list. + * + * @return Pointer to new queue (NULL on failure). + */ +MMAL_LIST_T* mmal_list_create(void); + +/** Destroy a linked list. + * + * @param list List to destroy + */ +void mmal_list_destroy(MMAL_LIST_T *list); + +/** Remove the last element in the list. + * + * @param list List to remove from + * + * @return Pointer to the last element (or NULL if empty) + */ +MMAL_LIST_ELEMENT_T* mmal_list_pop_back(MMAL_LIST_T *list); + +/** Remove the first element in the list. + * + * @param list List to remove from + * + * @return Pointer to the first element (or NULL if empty) + */ +MMAL_LIST_ELEMENT_T* mmal_list_pop_front(MMAL_LIST_T *list); + +/** Add an element to the front of the list. + * + * @param list List to add to + * @param element The element to add + */ +void mmal_list_push_front(MMAL_LIST_T *list, MMAL_LIST_ELEMENT_T *element); + +/** Add an element to the back of the list. + * + * @param list List to add to + * @param element The element to add + */ +void mmal_list_push_back(MMAL_LIST_T *list, MMAL_LIST_ELEMENT_T *element); + +/** List comparison function. + * This is supplied by a client when inserting an element in + * the middle of the list. The list will always insert a smaller + * element in front of a larger element. + * + * @return TRUE: lhs < rhs + * FALSE: lhs >= rhs + */ +typedef int (*MMAL_LIST_COMPARE_T)(MMAL_LIST_ELEMENT_T *lhs, MMAL_LIST_ELEMENT_T *rhs); + +/** Insert an element into the list. + * The location where the element is inserted is determined using + * the supplied comparison function. Smaller elements are inserted + * in front of larger elements. + * + * @param list List to add to + * @param element The element to insert + * @param compare Comparison function supplied by the client + */ +void mmal_list_insert(MMAL_LIST_T *list, MMAL_LIST_ELEMENT_T *element, MMAL_LIST_COMPARE_T compare); + +/* @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* MMAL_LIST_H */ diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/util/mmal_param_convert.c b/external_src/raspicam-0.1.3/dependencies/mmal/util/mmal_param_convert.c new file mode 100644 index 0000000..f470210 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/util/mmal_param_convert.c @@ -0,0 +1,177 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 "mmal_param_convert.h" +#include +#include + +typedef struct string_pair_t +{ + const char *string; + int value; +} string_pair_t; + +static MMAL_STATUS_T parse_enum(int *dest, string_pair_t *pairs, size_t n_pairs, const char *str) +{ + size_t i; + for (i=0; inum = num; + dest->den = den; + return ret; +} + +MMAL_STATUS_T mmal_parse_int(int *dest, const char *str) +{ + char *endptr; + long i = strtol(str, &endptr, 0); + if (endptr[0] == '\0') + { + *dest = i; + return MMAL_SUCCESS; + } + else + { + return MMAL_EINVAL; + } +} + +MMAL_STATUS_T mmal_parse_uint(unsigned int *dest, const char *str) +{ + char *endptr; + unsigned long i = strtoul(str, &endptr, 0); + if (endptr[0] == '\0') + { + *dest = i; + return MMAL_SUCCESS; + } + else + { + return MMAL_EINVAL; + } +} + +MMAL_STATUS_T mmal_parse_video_codec(uint32_t *dest, const char *str) +{ + static string_pair_t video_codec_enums[] = { + { "h264", MMAL_ENCODING_H264 }, + { "h263", MMAL_ENCODING_H263 }, + { "mpeg4", MMAL_ENCODING_MP4V }, + { "mpeg2", MMAL_ENCODING_MP2V }, + { "vp8", MMAL_ENCODING_VP8 }, + { "vp7", MMAL_ENCODING_VP7 }, + { "vp6", MMAL_ENCODING_VP6 }, + }; + int i = 0; + MMAL_STATUS_T ret; + + ret = parse_enum(&i, video_codec_enums, vcos_countof(video_codec_enums), str); + *dest = i; + return ret; +} + +MMAL_STATUS_T mmal_parse_geometry(MMAL_RECT_T *dest, const char *str) +{ + MMAL_STATUS_T ret; + uint32_t w, h, x, y; + x = y = w = h = 0; + /* coverity[secure_coding] */ + if (sscanf(str, "%d*%d+%d+%d", &w,&h,&x,&y) == 4 || + sscanf(str, "%d*%d", &w,&h) == 2) + { + dest->x = x; + dest->y = y; + dest->width = w; + dest->height = h; + ret = MMAL_SUCCESS; + } + else + { + ret = MMAL_EINVAL; + } + return ret; +} + diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/util/mmal_param_convert.h b/external_src/raspicam-0.1.3/dependencies/mmal/util/mmal_param_convert.h new file mode 100644 index 0000000..1d653c2 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/util/mmal_param_convert.h @@ -0,0 +1,92 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. +*/ + +/** \file + * Support for setting/getting parameters as string values. + */ + +#ifndef MMAL_PARAM_CONVERT_H +#define MMAL_PARAM_CONVERT_H + +#include "interface/mmal/mmal.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** Parse a video size. e.g. "1080p" gives 1920x1080. + * + * @param w width result + * @param h height result + * @param str string to convert + * @return MMAL_SUCCESS or error code + */ +MMAL_STATUS_T mmal_parse_video_size(uint32_t *w, uint32_t *h, const char *str); + +/** Parse a rational number. e.g. "30000/1001", "30", etc. + * @param dest filled in with result + * @param str string to convert + * @return MMAL_SUCCESS or error code + */ +MMAL_STATUS_T mmal_parse_rational(MMAL_RATIONAL_T *dest, const char *str); + +/** Parse an integer, e.g. -10, 0x1A, etc. + * @param dest filled in with result + * @param str string to convert + * @return MMAL_SUCCESS or error code + */ +MMAL_STATUS_T mmal_parse_int(int *dest, const char *str); + +/** Parse an unsigned integer, e.g. 10, 0x1A, etc. + * @param dest filled in with result + * @param str string to convert + * @return MMAL_SUCCESS or error code + */ +MMAL_STATUS_T mmal_parse_uint(unsigned int *dest, const char *str); + +/** Parse a geometry for a rectangle + * + * e.g. 100*100+50+75 + * or 200*150 + * @param dest filled in with result + * @param str string to convert + * @return MMAL_SUCCESS or error code + */ +MMAL_STATUS_T mmal_parse_geometry(MMAL_RECT_T *dest, const char *str); + +/** Parse a video codec name (something that can be encoded/decoded) + * @param str string to convert + * @param dest filled in with result + * @return MMAL_SUCCESS or error code + */ +MMAL_STATUS_T mmal_parse_video_codec(uint32_t *dest, const char *str); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/util/mmal_util.c b/external_src/raspicam-0.1.3/dependencies/mmal/util/mmal_util.c new file mode 100644 index 0000000..8959e53 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/util/mmal_util.c @@ -0,0 +1,355 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 "interface/mmal/mmal.h" +#include "mmal_encodings.h" +#include "mmal_util.h" +#include "mmal_logging.h" +#include +#include + +#define STATUS_TO_STR(x) { MMAL_##x, #x } + +static struct { + MMAL_STATUS_T status; + const char *str; +} status_to_string_map[] = +{ + STATUS_TO_STR(SUCCESS), + STATUS_TO_STR(ENOMEM), + STATUS_TO_STR(ENOSPC), + STATUS_TO_STR(EINVAL), + STATUS_TO_STR(ENOSYS), + STATUS_TO_STR(ENOENT), + STATUS_TO_STR(ENXIO), + STATUS_TO_STR(EIO), + STATUS_TO_STR(ESPIPE), + STATUS_TO_STR(ECORRUPT), + STATUS_TO_STR(ENOTREADY), + STATUS_TO_STR(ECONFIG), + {0, 0} +}; + +const char *mmal_status_to_string(MMAL_STATUS_T status) +{ + unsigned i; + + for (i=0; status_to_string_map[i].str; i++) + if (status_to_string_map[i].status == status) + break; + + return status_to_string_map[i].str ? status_to_string_map[i].str : "UNKNOWN"; +} + +static struct { + uint32_t encoding; + uint32_t pitch_num; + uint32_t pitch_den; +} pixel_pitch[] = +{ + {MMAL_ENCODING_I420, 1, 1}, + {MMAL_ENCODING_YV12, 1, 1}, + {MMAL_ENCODING_I422, 1, 1}, + {MMAL_ENCODING_NV21, 1, 1}, + {MMAL_ENCODING_NV12, 1, 1}, + {MMAL_ENCODING_ARGB, 4, 1}, + {MMAL_ENCODING_RGBA, 4, 1}, + {MMAL_ENCODING_RGB32, 4, 1}, + {MMAL_ENCODING_ABGR, 4, 1}, + {MMAL_ENCODING_BGRA, 4, 1}, + {MMAL_ENCODING_BGR32, 4, 1}, + {MMAL_ENCODING_RGB16, 2, 1}, + {MMAL_ENCODING_RGB24, 3, 1}, + {MMAL_ENCODING_BGR16, 2, 1}, + {MMAL_ENCODING_BGR24, 3, 1}, + + {MMAL_ENCODING_YUYV, 2, 1}, + {MMAL_ENCODING_YVYU, 2, 1}, + {MMAL_ENCODING_UYVY, 2, 1}, + {MMAL_ENCODING_VYUY, 2, 1}, + /* {MMAL_ENCODING_YUVUV128, 1, 1}, That's a special case which must not be included */ + {MMAL_ENCODING_UNKNOWN, 0, 0} +}; + +uint32_t mmal_encoding_stride_to_width(uint32_t encoding, uint32_t stride) +{ + unsigned int i; + + for(i = 0; pixel_pitch[i].encoding != MMAL_ENCODING_UNKNOWN; i++) + if(pixel_pitch[i].encoding == encoding) break; + + if(pixel_pitch[i].encoding == MMAL_ENCODING_UNKNOWN) + return 0; + + return pixel_pitch[i].pitch_den * stride / pixel_pitch[i].pitch_num; +} + +uint32_t mmal_encoding_width_to_stride(uint32_t encoding, uint32_t width) +{ + unsigned int i; + + for(i = 0; pixel_pitch[i].encoding != MMAL_ENCODING_UNKNOWN; i++) + if(pixel_pitch[i].encoding == encoding) break; + + if(pixel_pitch[i].encoding == MMAL_ENCODING_UNKNOWN) + return 0; + + return pixel_pitch[i].pitch_num * width / pixel_pitch[i].pitch_den; +} + +const char* mmal_port_type_to_string(MMAL_PORT_TYPE_T type) +{ + const char *str; + + switch (type) + { + case MMAL_PORT_TYPE_INPUT: str = "in"; break; + case MMAL_PORT_TYPE_OUTPUT: str = "out"; break; + case MMAL_PORT_TYPE_CLOCK: str = "clk"; break; + case MMAL_PORT_TYPE_CONTROL: str = "ctr"; break; + default: str = "invalid"; break; + } + + return str; +} + +MMAL_PARAMETER_HEADER_T *mmal_port_parameter_alloc_get(MMAL_PORT_T *port, + uint32_t id, uint32_t size, MMAL_STATUS_T *p_status) +{ + MMAL_PARAMETER_HEADER_T *param = NULL; + MMAL_STATUS_T status = MMAL_ENOSYS; + + if (size < sizeof(MMAL_PARAMETER_HEADER_T)) + size = sizeof(MMAL_PARAMETER_HEADER_T); + + if ((param = vcos_calloc(1, size, "mmal_port_param_get")) == NULL) + { + status = MMAL_ENOMEM; + goto error; + } + + param->id = id; + param->size = size; + + if ((status = mmal_port_parameter_get(port, param)) == MMAL_ENOSPC) + { + /* We need to reallocate to get enough space for all parameter data */ + size = param->size; + vcos_free(param); + if ((param = vcos_calloc(1, size, "mmal_port_param_get")) == NULL) + { + status = MMAL_ENOMEM; + goto error; + } + + /* Now retrieve it again */ + param->id = id; + param->size = size; + status = mmal_port_parameter_get(port, param); + } + + if (status != MMAL_SUCCESS) + goto error; + +end: + if (p_status) *p_status = status; + return param; +error: + if (param) vcos_free(param); + param = NULL; + goto end; +} + +void mmal_port_parameter_free(MMAL_PARAMETER_HEADER_T *param) +{ + vcos_free(param); +} + +/** Copy buffer header metadata from source to dest + */ +void mmal_buffer_header_copy_header(MMAL_BUFFER_HEADER_T *dest, const MMAL_BUFFER_HEADER_T *src) +{ + dest->cmd = src->cmd; + dest->offset = src->offset; + dest->length = src->length; + dest->flags = src->flags; + dest->pts = src->pts; + dest->dts = src->dts; + *dest->type = *src->type; +} + +/** Create a pool of MMAL_BUFFER_HEADER_T */ +MMAL_POOL_T *mmal_port_pool_create(MMAL_PORT_T *port, unsigned int headers, uint32_t payload_size) +{ + if (!port || !port->priv) + return NULL; + + LOG_TRACE("%s(%i:%i) port %p, headers %u, size %i", port->component->name, + (int)port->type, (int)port->index, port, headers, (int)payload_size); + + /* Create a pool and ask the port for some memory */ + return mmal_pool_create_with_allocator(headers, payload_size, (void *)port, + (mmal_pool_allocator_alloc_t)mmal_port_payload_alloc, + (mmal_pool_allocator_free_t)mmal_port_payload_free); +} + +/** Destroy a pool of MMAL_BUFFER_HEADER_T */ +void mmal_port_pool_destroy(MMAL_PORT_T *port, MMAL_POOL_T *pool) +{ + if (!port || !port->priv || !pool) + return; + + LOG_TRACE("%s(%i:%i) port %p, pool %p", port->component->name, + (int)port->type, (int)port->index, port, pool); + + if (!vcos_verify(!port->is_enabled)) + { + LOG_ERROR("port %p, pool %p destroyed while port enabled", port, pool); + mmal_port_disable(port); + } + + mmal_pool_destroy(pool); +} + +/*****************************************************************************/ +void mmal_log_dump_port(MMAL_PORT_T *port) +{ + if (!port) + return; + + LOG_DEBUG("%s(%p)", port->name, port); + + mmal_log_dump_format(port->format); + + LOG_DEBUG(" buffers num: %i(opt %i, min %i), size: %i(opt %i, min: %i), align: %i", + port->buffer_num, port->buffer_num_recommended, port->buffer_num_min, + port->buffer_size, port->buffer_size_recommended, port->buffer_size_min, + port->buffer_alignment_min); +} + +/*****************************************************************************/ +void mmal_log_dump_format(MMAL_ES_FORMAT_T *format) +{ + const char *name_type; + + if (!format) + return; + + switch(format->type) + { + case MMAL_ES_TYPE_AUDIO: name_type = "audio"; break; + case MMAL_ES_TYPE_VIDEO: name_type = "video"; break; + case MMAL_ES_TYPE_SUBPICTURE: name_type = "subpicture"; break; + default: name_type = "unknown"; break; + } + + LOG_DEBUG("type: %s, fourcc: %4.4s", name_type, (char *)&format->encoding); + LOG_DEBUG(" bitrate: %i, framed: %i", format->bitrate, + !!(format->flags & MMAL_ES_FORMAT_FLAG_FRAMED)); + LOG_DEBUG(" extra data: %i, %p", format->extradata_size, format->extradata); + switch(format->type) + { + case MMAL_ES_TYPE_AUDIO: + LOG_DEBUG(" samplerate: %i, channels: %i, bps: %i, block align: %i", + format->es->audio.sample_rate, format->es->audio.channels, + format->es->audio.bits_per_sample, format->es->audio.block_align); + break; + + case MMAL_ES_TYPE_VIDEO: + LOG_DEBUG(" width: %i, height: %i, (%i,%i,%i,%i)", + format->es->video.width, format->es->video.height, + format->es->video.crop.x, format->es->video.crop.y, + format->es->video.crop.width, format->es->video.crop.height); + LOG_DEBUG(" pixel aspect ratio: %i/%i, frame rate: %i/%i", + format->es->video.par.num, format->es->video.par.den, + format->es->video.frame_rate.num, format->es->video.frame_rate.den); + break; + + case MMAL_ES_TYPE_SUBPICTURE: + break; + + default: break; + } +} + +MMAL_PORT_T *mmal_util_get_port(MMAL_COMPONENT_T *comp, MMAL_PORT_TYPE_T type, unsigned index) +{ + unsigned num; + MMAL_PORT_T **list; + + switch (type) + { + case MMAL_PORT_TYPE_INPUT: + num = comp->input_num; + list = comp->input; + break; + + case MMAL_PORT_TYPE_OUTPUT: + num = comp->output_num; + list = comp->output; + break; + + case MMAL_PORT_TYPE_CLOCK: + num = comp->clock_num; + list = comp->clock; + break; + + case MMAL_PORT_TYPE_CONTROL: + num = 1; + list = &comp->control; + break; + + default: + vcos_assert(0); + return NULL; + } + if (index < num) + /* coverity[ptr_arith] num is 1 here */ + return list[index]; + else + return NULL; +} + +char *mmal_4cc_to_string(char *buf, size_t len, uint32_t fourcc) +{ + char *src = (char*)&fourcc; + vcos_assert(len >= 5); + if (len < 5) + { + buf[0] = '\0'; + } + else if (fourcc) + { + memcpy(buf, src, 4); + buf[4] = '\0'; + } + else + { + snprintf(buf, len, "<0>"); + } + return buf; +} + diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/util/mmal_util.h b/external_src/raspicam-0.1.3/dependencies/mmal/util/mmal_util.h new file mode 100644 index 0000000..4e5c803 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/util/mmal_util.h @@ -0,0 +1,173 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 MMAL_UTIL_H +#define MMAL_UTIL_H + +#include "mmal.h" + +/** \defgroup MmalUtilities Utility functions + * The utility functions provide helpers for common functionality that is not part + * of the core MMAL API. + * @{ + */ + +/** Offset in bytes of FIELD in TYPE. */ +#define MMAL_OFFSET(TYPE, FIELD) ((size_t)((uint8_t *)&((TYPE*)0)->FIELD - (uint8_t *)0)) + +#ifdef __cplusplus +extern "C" { +#endif + +/** Convert a status to a statically-allocated string. + * + * @param status The MMAL status code. + * @return A C string describing the status code. + */ +const char *mmal_status_to_string(MMAL_STATUS_T status); + +/** Convert stride to pixel width for a given pixel encoding. + * + * @param encoding The pixel encoding (such as one of the \ref MmalEncodings "pre-defined encodings") + * @param stride The stride in bytes. + * @return The width in pixels. + */ +uint32_t mmal_encoding_stride_to_width(uint32_t encoding, uint32_t stride); + +/** Convert pixel width to stride for a given pixel encoding + * + * @param encoding The pixel encoding (such as one of the \ref MmalEncodings "pre-defined encodings") + * @param width The width in pixels. + * @return The stride in bytes. + */ +uint32_t mmal_encoding_width_to_stride(uint32_t encoding, uint32_t width); + +/** Convert a port type to a string. + * + * @param type The MMAL port type. + * @return A NULL-terminated string describing the port type. + */ +const char* mmal_port_type_to_string(MMAL_PORT_TYPE_T type); + +/** Get a parameter from a port allocating the required amount of memory + * for the parameter (i.e. for variable length parameters like URI or arrays). + * The size field will be set on output to the actual size of the + * parameter allocated and retrieved. + * + * The pointer returned must be released by a call to \ref mmal_port_parameter_free(). + * + * @param port port to send request to + * @param id parameter id + * @param size initial size hint for allocation (can be 0) + * @param status status of the parameter get operation (can be 0) + * @return pointer to the header of the parameter or NULL on failure. + */ +MMAL_PARAMETER_HEADER_T *mmal_port_parameter_alloc_get(MMAL_PORT_T *port, + uint32_t id, uint32_t size, MMAL_STATUS_T *status); + +/** Free a parameter structure previously allocated via + * \ref mmal_port_parameter_alloc_get(). + * + * @param param pointer to header of the parameter + */ +void mmal_port_parameter_free(MMAL_PARAMETER_HEADER_T *param); + +/** Copy buffer header metadata from source to destination. + * + * @param dest The destination buffer header. + * @param src The source buffer header. + */ +void mmal_buffer_header_copy_header(MMAL_BUFFER_HEADER_T *dest, const MMAL_BUFFER_HEADER_T *src); + +/** 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); + +/** Destroy a pool of MMAL_BUFFER_HEADER_T associated with a specific port. + * This will also deallocate all of the memory which was allocated when creating or + * resizing the pool. + * + * @param port Pointer to the port responsible for creating the pool. + * @param pool Pointer to the pool to be destroyed. + */ +void mmal_port_pool_destroy(MMAL_PORT_T *port, MMAL_POOL_T *pool); + +/** Log the content of a \ref MMAL_PORT_T structure. + * + * @param port Pointer to the port to dump. + */ +void mmal_log_dump_port(MMAL_PORT_T *port); + +/** Log the content of a \ref MMAL_ES_FORMAT_T structure. + * + * @param format Pointer to the format to dump. + */ +void mmal_log_dump_format(MMAL_ES_FORMAT_T *format); + +/** Return the nth port. + * + * @param comp component to query + * @param index port index + * @param type port type + * + * @return port or NULL if not found + */ +MMAL_PORT_T *mmal_util_get_port(MMAL_COMPONENT_T *comp, MMAL_PORT_TYPE_T type, unsigned index); + +/** Convert a 4cc into a string. + * + * @param buf Destination for result + * @param len Size of result buffer + * @param fourcc 4cc to be converted + * @return converted string (buf) + * + */ +char *mmal_4cc_to_string(char *buf, size_t len, uint32_t fourcc); + + +#ifdef __cplusplus +} +#endif + +/** @} */ + +#endif diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/util/mmal_util_params.c b/external_src/raspicam-0.1.3/dependencies/mmal/util/mmal_util_params.c new file mode 100644 index 0000000..6e24791 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/util/mmal_util_params.c @@ -0,0 +1,223 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 "mmal_util_params.h" + +/** Helper function to set the value of a boolean parameter */ +MMAL_STATUS_T mmal_port_parameter_set_boolean(MMAL_PORT_T *port, uint32_t id, MMAL_BOOL_T value) +{ + MMAL_PARAMETER_BOOLEAN_T param = {{id, sizeof(param)}, value}; + return mmal_port_parameter_set(port, ¶m.hdr); +} + +/** Helper function to get the value of a boolean parameter */ +MMAL_STATUS_T mmal_port_parameter_get_boolean(MMAL_PORT_T *port, uint32_t id, MMAL_BOOL_T *value) +{ + MMAL_PARAMETER_BOOLEAN_T param = {{id, sizeof(param)}, 0}; + // coverity[overrun-buffer-val] Structure accessed correctly via size field + MMAL_STATUS_T status = mmal_port_parameter_get(port, ¶m.hdr); + if (status == MMAL_SUCCESS) + *value = param.enable; + return status; +} + +/** Helper function to set the value of a 64 bits unsigned integer parameter */ +MMAL_STATUS_T mmal_port_parameter_set_uint64(MMAL_PORT_T *port, uint32_t id, uint64_t value) +{ + MMAL_PARAMETER_UINT64_T param = {{id, sizeof(param)}, value}; + return mmal_port_parameter_set(port, ¶m.hdr); +} + +/** Helper function to get the value of a 64 bits unsigned integer parameter */ +MMAL_STATUS_T mmal_port_parameter_get_uint64(MMAL_PORT_T *port, uint32_t id, uint64_t *value) +{ + MMAL_PARAMETER_UINT64_T param = {{id, sizeof(param)}, 0LL}; + // coverity[overrun-buffer-val] Structure accessed correctly via size field + MMAL_STATUS_T status = mmal_port_parameter_get(port, ¶m.hdr); + if (status == MMAL_SUCCESS) + *value = param.value; + return status; +} + +/** Helper function to set the value of a 64 bits signed integer parameter */ +MMAL_STATUS_T mmal_port_parameter_set_int64(MMAL_PORT_T *port, uint32_t id, int64_t value) +{ + MMAL_PARAMETER_INT64_T param = {{id, sizeof(param)}, value}; + return mmal_port_parameter_set(port, ¶m.hdr); +} + +/** Helper function to get the value of a 64 bits signed integer parameter */ +MMAL_STATUS_T mmal_port_parameter_get_int64(MMAL_PORT_T *port, uint32_t id, int64_t *value) +{ + MMAL_PARAMETER_INT64_T param = {{id, sizeof(param)}, 0LL}; + // coverity[overrun-buffer-val] Structure accessed correctly via size field + MMAL_STATUS_T status = mmal_port_parameter_get(port, ¶m.hdr); + if (status == MMAL_SUCCESS) + *value = param.value; + return status; +} + +/** Helper function to set the value of a 32 bits unsigned integer parameter */ +MMAL_STATUS_T mmal_port_parameter_set_uint32(MMAL_PORT_T *port, uint32_t id, uint32_t value) +{ + MMAL_PARAMETER_UINT32_T param = {{id, sizeof(param)}, value}; + return mmal_port_parameter_set(port, ¶m.hdr); +} + +/** Helper function to get the value of a 32 bits unsigned integer parameter */ +MMAL_STATUS_T mmal_port_parameter_get_uint32(MMAL_PORT_T *port, uint32_t id, uint32_t *value) +{ + MMAL_PARAMETER_UINT32_T param = {{id, sizeof(param)}, 0}; + // coverity[overrun-buffer-val] Structure accessed correctly via size field + MMAL_STATUS_T status = mmal_port_parameter_get(port, ¶m.hdr); + if (status == MMAL_SUCCESS) + *value = param.value; + return status; +} + +/** Helper function to set the value of a 32 bits signed integer parameter */ +MMAL_STATUS_T mmal_port_parameter_set_int32(MMAL_PORT_T *port, uint32_t id, int32_t value) +{ + MMAL_PARAMETER_INT32_T param = {{id, sizeof(param)}, value}; + return mmal_port_parameter_set(port, ¶m.hdr); +} + +/** Helper function to get the value of a 32 bits signed integer parameter */ +MMAL_STATUS_T mmal_port_parameter_get_int32(MMAL_PORT_T *port, uint32_t id, int32_t *value) +{ + MMAL_PARAMETER_INT32_T param = {{id, sizeof(param)}, 0}; + // coverity[overrun-buffer-val] Structure accessed correctly via size field + MMAL_STATUS_T status = mmal_port_parameter_get(port, ¶m.hdr); + if (status == MMAL_SUCCESS) + *value = param.value; + return status; +} + +/** Helper function to set the value of a rational parameter */ +MMAL_STATUS_T mmal_port_parameter_set_rational(MMAL_PORT_T *port, uint32_t id, MMAL_RATIONAL_T value) +{ + MMAL_PARAMETER_RATIONAL_T param = {{id, sizeof(param)}, {value.num, value.den}}; + return mmal_port_parameter_set(port, ¶m.hdr); +} + +/** Helper function to get the value of a rational parameter */ +MMAL_STATUS_T mmal_port_parameter_get_rational(MMAL_PORT_T *port, uint32_t id, MMAL_RATIONAL_T *value) +{ + MMAL_PARAMETER_RATIONAL_T param = {{id, sizeof(param)}, {0,0}}; + // coverity[overrun-buffer-val] Structure accessed correctly via size field + MMAL_STATUS_T status = mmal_port_parameter_get(port, ¶m.hdr); + if (status == MMAL_SUCCESS) + *value = param.value; + return status; +} + +/** Helper function to set the value of a string parameter */ +MMAL_STATUS_T mmal_port_parameter_set_string(MMAL_PORT_T *port, uint32_t id, const char *value) +{ + MMAL_PARAMETER_STRING_T *param = 0; + MMAL_STATUS_T status; + size_t param_size = sizeof(param->hdr) + strlen(value) + 1; + + param = calloc(1, param_size); + if (!param) + return MMAL_ENOMEM; + + param->hdr.id = id; + param->hdr.size = param_size; + memcpy(param->str, value, strlen(value)+1); + status = mmal_port_parameter_set(port, ¶m->hdr); + free(param); + return status; +} + +/** Helper function to set a MMAL_PARAMETER_URI_T parameter on a port */ +MMAL_STATUS_T mmal_util_port_set_uri(MMAL_PORT_T *port, const char *uri) +{ + return mmal_port_parameter_set_string(port, MMAL_PARAMETER_URI, uri); +} + +/** Helper function to set the value of an array of bytes parameter */ +MMAL_STATUS_T mmal_port_parameter_set_bytes(MMAL_PORT_T *port, uint32_t id, + const uint8_t *data, unsigned int size) +{ + MMAL_PARAMETER_BYTES_T *param = 0; + MMAL_STATUS_T status; + size_t param_size = sizeof(param->hdr) + size; + + param = calloc(1, param_size); + if (!param) + return MMAL_ENOMEM; + + param->hdr.id = id; + param->hdr.size = param_size; + memcpy(param->data, data, size); + status = mmal_port_parameter_set(port, ¶m->hdr); + free(param); + return status; +} + +/** Set the display region. + * @param port port to configure + * @param region region + * + * @return MMAL_SUCCESS or error + */ + +MMAL_STATUS_T mmal_util_set_display_region(MMAL_PORT_T *port, + MMAL_DISPLAYREGION_T *region) +{ + region->hdr.id = MMAL_PARAMETER_DISPLAYREGION; + region->hdr.size = sizeof(*region); + return mmal_port_parameter_set(port, ®ion->hdr); +} + +MMAL_STATUS_T mmal_util_camera_use_stc_timestamp(MMAL_PORT_T *port, MMAL_CAMERA_STC_MODE_T mode) +{ + MMAL_PARAMETER_CAMERA_STC_MODE_T param = + {{MMAL_PARAMETER_USE_STC, sizeof(MMAL_PARAMETER_CAMERA_STC_MODE_T)},mode}; + return mmal_port_parameter_set(port, ¶m.hdr); +} + +MMAL_STATUS_T mmal_util_get_core_port_stats(MMAL_PORT_T *port, + MMAL_CORE_STATS_DIR dir, + MMAL_BOOL_T reset, + MMAL_CORE_STATISTICS_T *stats) +{ + MMAL_PARAMETER_CORE_STATISTICS_T param; + MMAL_STATUS_T ret; + + memset(¶m, 0, sizeof(param)); + param.hdr.id = MMAL_PARAMETER_CORE_STATISTICS; + param.hdr.size = sizeof(param); + param.dir = dir; + param.reset = reset; + // coverity[overrun-buffer-val] Structure accessed correctly via size field + ret = mmal_port_parameter_get(port, ¶m.hdr); + if (ret == MMAL_SUCCESS) + *stats = param.stats; + return ret; +} diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/util/mmal_util_params.h b/external_src/raspicam-0.1.3/dependencies/mmal/util/mmal_util_params.h new file mode 100644 index 0000000..0b85e5b --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/util/mmal_util_params.h @@ -0,0 +1,210 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 MMAL_UTIL_PARAMS_H +#define MMAL_UTIL_PARAMS_H + +#include "mmal.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @file + * Utility functions to set some common parameters. + */ + +/** 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); + +/** Helper function to get the value of a boolean parameter. + * @param port port on which to get the parameter + * @param id parameter id + * @param value pointer to where the value will be returned + * + * @return MMAL_SUCCESS or error + */ +MMAL_STATUS_T mmal_port_parameter_get_boolean(MMAL_PORT_T *port, uint32_t id, MMAL_BOOL_T *value); + +/** Helper function to set the value of a 64 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_uint64(MMAL_PORT_T *port, uint32_t id, uint64_t value); + +/** Helper function to get the value of a 64 bits unsigned integer parameter. + * @param port port on which to get the parameter + * @param id parameter id + * @param value pointer to where the value will be returned + * + * @return MMAL_SUCCESS or error + */ +MMAL_STATUS_T mmal_port_parameter_get_uint64(MMAL_PORT_T *port, uint32_t id, uint64_t *value); + +/** Helper function to set the value of a 64 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_int64(MMAL_PORT_T *port, uint32_t id, int64_t value); + +/** Helper function to get the value of a 64 bits signed integer parameter. + * @param port port on which to get the parameter + * @param id parameter id + * @param value pointer to where the value will be returned + * + * @return MMAL_SUCCESS or error + */ +MMAL_STATUS_T mmal_port_parameter_get_int64(MMAL_PORT_T *port, uint32_t id, int64_t *value); + +/** 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); + +/** Helper function to get the value of a 32 bits unsigned integer parameter. + * @param port port on which to get the parameter + * @param id parameter id + * @param value pointer to where the value will be returned + * + * @return MMAL_SUCCESS or error + */ +MMAL_STATUS_T mmal_port_parameter_get_uint32(MMAL_PORT_T *port, uint32_t id, uint32_t *value); + +/** 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); + +/** Helper function to get the value of a 32 bits signed integer parameter. + * @param port port on which to get the parameter + * @param id parameter id + * @param value pointer to where the value will be returned + * + * @return MMAL_SUCCESS or error + */ +MMAL_STATUS_T mmal_port_parameter_get_int32(MMAL_PORT_T *port, uint32_t id, int32_t *value); + +/** 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); + +/** Helper function to get the value of a rational parameter. + * @param port port on which to get the parameter + * @param id parameter id + * @param value pointer to where the value will be returned + * + * @return MMAL_SUCCESS or error + */ +MMAL_STATUS_T mmal_port_parameter_get_rational(MMAL_PORT_T *port, uint32_t id, MMAL_RATIONAL_T *value); + +/** Helper function to set the value of a string parameter. + * @param port port on which to set the parameter + * @param id parameter id + * @param value null-terminated string value + * + * @return MMAL_SUCCESS or error + */ +MMAL_STATUS_T mmal_port_parameter_set_string(MMAL_PORT_T *port, uint32_t id, const char *value); + +/** Helper function to set the value of an array of bytes parameter. + * @param port port on which to set the parameter + * @param id parameter id + * @param data pointer to the array of bytes + * @param size size of the array of bytes + * + * @return MMAL_SUCCESS or error + */ +MMAL_STATUS_T mmal_port_parameter_set_bytes(MMAL_PORT_T *port, uint32_t id, + const uint8_t *data, unsigned int size); + +/** Helper function to set a MMAL_PARAMETER_URI_T parameter on a port. + * @param port port on which to set the parameter + * @param uri URI string + * + * @return MMAL_SUCCESS or error + */ +MMAL_STATUS_T mmal_util_port_set_uri(MMAL_PORT_T *port, const char *uri); + +/** Set the display region. + * @param port port to configure + * @param region region + * + * @return MMAL_SUCCESS or error + */ +MMAL_STATUS_T mmal_util_set_display_region(MMAL_PORT_T *port, + MMAL_DISPLAYREGION_T *region); + +/** Tell the camera to use the STC for timestamps rather than the clock. + * + * @param port port to configure + * @param mode STC mode to use + * @return MMAL_SUCCESS or error + */ +MMAL_STATUS_T mmal_util_camera_use_stc_timestamp(MMAL_PORT_T *port, MMAL_CAMERA_STC_MODE_T mode); + +/** Get the MMAL core statistics for a given port. + * + * @param port port to query + * @param dir port direction + * @param reset reset the stats as well + * @param stats filled in with results + * @return MMAL_SUCCESS or error + */ +MMAL_STATUS_T mmal_util_get_core_port_stats(MMAL_PORT_T *port, MMAL_CORE_STATS_DIR dir, MMAL_BOOL_T reset, + MMAL_CORE_STATISTICS_T *stats); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/util/mmal_util_rational.c b/external_src/raspicam-0.1.3/dependencies/mmal/util/mmal_util_rational.c new file mode 100644 index 0000000..288b27b --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/util/mmal_util_rational.c @@ -0,0 +1,158 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 +#include "interface/mmal/util/mmal_util_rational.h" + +#define Q16_ONE (1 << 16) + +#define ABS(v) (((v) < 0) ? -(v) : (v)) + +/** Calculate the greatest common denominator between 2 integers. + * Avoids division. */ +static int32_t gcd(int32_t a, int32_t b) +{ + int shift; + + if (a == 0 || b == 0) + return 1; + + a = ABS(a); + b = ABS(b); + for (shift = 0; !((a | b) & 0x01); shift++) + a >>= 1, b >>= 1; + + while (a > 0) + { + while (!(a & 0x01)) + a >>= 1; + while (!(b & 0x01)) + b >>= 1; + if (a >= b) + a = (a - b) >> 1; + else + b = (b - a) >> 1; + } + return b << shift; +} + +/** Calculate a + b. */ +MMAL_RATIONAL_T mmal_rational_add(MMAL_RATIONAL_T a, MMAL_RATIONAL_T b) +{ + MMAL_RATIONAL_T result; + int32_t g = gcd(a.den, b.den); + a.den /= g; + a.num = a.num * (b.den / g) + b.num * a.den; + g = gcd(a.num, g); + a.num /= g; + a.den *= b.den / g; + + result.num = a.num; + result.den = a.den; + return result; +} + +/** Calculate a - b. */ +MMAL_RATIONAL_T mmal_rational_subtract(MMAL_RATIONAL_T a, MMAL_RATIONAL_T b) +{ + b.num = -b.num; + return mmal_rational_add(a, b); +} + +/** Calculate a * b */ +MMAL_RATIONAL_T mmal_rational_multiply(MMAL_RATIONAL_T a, MMAL_RATIONAL_T b) +{ + MMAL_RATIONAL_T result; + int32_t gcd1 = gcd(a.num, b.den); + int32_t gcd2 = gcd(b.num, a.den); + result.num = (a.num / gcd1) * (b.num / gcd2); + result.den = (a.den / gcd2) * (b.den / gcd1); + + return result; +} + +/** Calculate a / b */ +MMAL_RATIONAL_T mmal_rational_divide(MMAL_RATIONAL_T a, MMAL_RATIONAL_T b) +{ + MMAL_RATIONAL_T result; + int32_t gcd1, gcd2; + + if (b.num == 0) + { + vcos_assert(0); + return a; + } + + if (a.num == 0) + return a; + + gcd1 = gcd(a.num, b.num); + gcd2 = gcd(b.den, a.den); + result.num = (a.num / gcd1) * (b.den / gcd2); + result.den = (a.den / gcd2) * (b.num / gcd1); + + return result; +} + +/** Convert a rational number to a signed 32-bit Q16 number. */ +int32_t mmal_rational_to_fixed_16_16(MMAL_RATIONAL_T rational) +{ + int64_t result = (int64_t)rational.num << 16; + if (rational.den) + result /= rational.den; + + if (result > INT_MAX) + result = INT_MAX; + else if (result < INT_MIN) + result = INT_MIN; + + return (int32_t)result; +} + +/** Convert a rational number to a signed 32-bit Q16 number. */ +MMAL_RATIONAL_T mmal_rational_from_fixed_16_16(int32_t fixed) +{ + MMAL_RATIONAL_T result = { fixed, Q16_ONE }; + mmal_rational_simplify(&result); + return result; +} + +/** Reduce a rational number to it's simplest form. */ +void mmal_rational_simplify(MMAL_RATIONAL_T *rational) +{ + int g = gcd(rational->num, rational->den); + rational->num /= g; + rational->den /= g; +} + +/** Tests for equality */ +MMAL_BOOL_T mmal_rational_equal(MMAL_RATIONAL_T a, MMAL_RATIONAL_T b) +{ + if (a.num != b.num && a.num * (int64_t)b.num == 0) + return MMAL_FALSE; + return a.num * (int64_t)b.den == b.num * (int64_t)a.den; +} diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/util/mmal_util_rational.h b/external_src/raspicam-0.1.3/dependencies/mmal/util/mmal_util_rational.h new file mode 100644 index 0000000..f459f51 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/util/mmal_util_rational.h @@ -0,0 +1,127 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 MMAL_UTIL_RATIONAL_H +#define MMAL_UTIL_RATIONAL_H + +#include "interface/mmal/mmal_types.h" + +/** \defgroup MmalRationalUtilities Rational Utility Functions + * \ingroup MmalUtilities + * The rational utility functions allow easy manipulation of rational numbers. + * + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** Add 2 rational numbers. + * It is assumed that both input rational numbers are in + * their simplest form. + * + * @param a First operand + * @param b Second operand + * + * @return a + b + */ +MMAL_RATIONAL_T mmal_rational_add(MMAL_RATIONAL_T a, MMAL_RATIONAL_T b); + +/** Subtract 2 rational numbers. + * It is assumed that both input rational numbers are in + * their simplest form. + * + * @param a First operand + * @param b Second operand + * + * @return a - b + */ +MMAL_RATIONAL_T mmal_rational_subtract(MMAL_RATIONAL_T a, MMAL_RATIONAL_T b); + +/** Multiply 2 rational numbers. + * It is assumed that both input rational numbers are in + * their simplest form. + * + * @param a First operand + * @param b Second operand + * + * @return a * b + */ +MMAL_RATIONAL_T mmal_rational_multiply(MMAL_RATIONAL_T a, MMAL_RATIONAL_T b); + +/** Divide 2 rational numbers. + * It is assumed that both input rational numbers are in + * their simplest form. + * + * @param a First operand + * @param b Second operand + * + * @return a / b + */ +MMAL_RATIONAL_T mmal_rational_divide(MMAL_RATIONAL_T a, MMAL_RATIONAL_T b); + +/** Convert a rational number to a 32-bit signed Q16 number. + * Saturation will occur for rational numbers with an absolute + * value greater than 32768. + * + * @param rational Rational number to convert + * + * @return 32-bit signed Q16 number + */ +int32_t mmal_rational_to_fixed_16_16(MMAL_RATIONAL_T rational); + +/** Convert a signed 32-bit Q16 number to a rational number. + * + * @param fixed Signed 32-bit Q16 number to convert + * + * @return Rational number + */ +MMAL_RATIONAL_T mmal_rational_from_fixed_16_16(int32_t fixed); + +/** Reduce a rational number to it's simplest form. + * + * @param rational Rational number to simplify + */ +void mmal_rational_simplify(MMAL_RATIONAL_T *rational); + +/** Test 2 rational numbers for equality. + * + * @param a First operand + * @param b Second operand + * + * @return true if equal + */ +MMAL_BOOL_T mmal_rational_equal(MMAL_RATIONAL_T a, MMAL_RATIONAL_T b); + +#ifdef __cplusplus +} +#endif + +/** @} */ + +#endif diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/vc/CMakeLists.txt b/external_src/raspicam-0.1.3/dependencies/mmal/vc/CMakeLists.txt new file mode 100644 index 0000000..8065a48 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/vc/CMakeLists.txt @@ -0,0 +1,29 @@ +# MMAL can use VCSM to allow zero copy for ARM accessible buffers. +# This is not enabled by default right now because VCSM on RPI is still +# experimental. +# add_definitions(-DENABLE_MMAL_VCSM) + +add_library(mmal_vc_client ${LIBRARY_TYPE} mmal_vc_client.c mmal_vc_shm.c mmal_vc_api.c mmal_vc_opaque_alloc.c mmal_vc_msgnames.c mmal_vc_api_drm.c) +target_link_libraries(mmal_vc_client vchiq_arm vcos) + +# target_link_libraries(mmal_vc_client vchiq_arm vcos vcsm) + +if(BUILD_MMAL_APPS) +add_executable(mmal_vc_diag mmal_vc_diag.c) +target_link_libraries(mmal_vc_diag mmal mmal_vc_client debug_sym vcos) +install(TARGETS mmal_vc_diag RUNTIME DESTINATION bin) +endif(BUILD_MMAL_APPS) + +include_directories ( ../../../host_applications/linux/libs/sm ) + +install(TARGETS mmal_vc_client DESTINATION lib) +install(FILES + mmal_vc_api.h + mmal_vc_api_drm.h + mmal_vc_client_priv.h + mmal_vc_msgnames.h + mmal_vc_msgs.h + mmal_vc_opaque_alloc.h + mmal_vc_shm.h + DESTINATION include/interface/mmal/vc +) diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/vc/mmal_vc_api.c b/external_src/raspicam-0.1.3/dependencies/mmal/vc/mmal_vc_api.c new file mode 100644 index 0000000..2e13418 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/vc/mmal_vc_api.c @@ -0,0 +1,1481 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 "interface/mmal/mmal_logging.h" +#include "interface/mmal/mmal.h" +#include "mmal_vc_api.h" +#include "mmal_vc_msgs.h" +#include "mmal_vc_client_priv.h" +#include "mmal_vc_opaque_alloc.h" +#include "mmal_vc_shm.h" +#include "interface/mmal/util/mmal_util.h" +#include "interface/mmal/core/mmal_component_private.h" +#include "interface/mmal/core/mmal_port_private.h" +#include "interface/mmal/core/mmal_buffer_private.h" +#include "interface/vcos/vcos.h" + +/** Private information for MMAL VC components + */ + +typedef enum MMAL_ZEROLEN_CHECK_T +{ + ZEROLEN_NOT_INITIALIZED, + ZEROLEN_COMPATIBLE, + ZEROLEN_INCOMPATIBLE +} MMAL_ZEROLEN_CHECK_T; + +typedef enum MMAL_PORT_FLUSH_CHECK_T +{ + PORT_FLUSH_NOT_INITIALIZED, + PORT_FLUSH_COMPATIBLE, + PORT_FLUSH_INCOMPATIBLE +} MMAL_PORT_FLUSH_CHECK_T; + +typedef struct MMAL_PORT_MODULE_T +{ + uint32_t magic; + uint32_t component_handle; + MMAL_PORT_T *port; + uint32_t port_handle; + + MMAL_BOOL_T has_pool; + VCOS_BLOCKPOOL_T pool; + + MMAL_BOOL_T is_zero_copy; + MMAL_BOOL_T zero_copy_workaround; + + MMAL_BOOL_T sent_data_on_port; + + MMAL_PORT_T *connected; /**< Connected port if any */ +} MMAL_PORT_MODULE_T; + +typedef struct MMAL_COMPONENT_MODULE_T +{ + uint32_t component_handle; + + MMAL_PORT_MODULE_T **ports; + uint32_t ports_num; + + MMAL_QUEUE_T *callback_queue; /**< Used to queue the callbacks we need to make to the client */ + + MMAL_BOOL_T event_ctx_initialised; + MMAL_VC_CLIENT_BUFFER_CONTEXT_T event_ctx; /**< Used as the ctx for event buffers */ +} MMAL_COMPONENT_MODULE_T; + +/***************************************************************************** + * Local function prototypes + *****************************************************************************/ +static void mmal_vc_do_callback(MMAL_COMPONENT_T *component); +static MMAL_STATUS_T mmal_vc_port_info_get(MMAL_PORT_T *port); + +/*****************************************************************************/ +MMAL_STATUS_T mmal_vc_get_version(uint32_t *major, uint32_t *minor, uint32_t *minimum) +{ + mmal_worker_version msg; + size_t len = sizeof(msg); + MMAL_STATUS_T status; + + status = mmal_vc_sendwait_message(mmal_vc_get_client(), &msg.header, sizeof(msg), + MMAL_WORKER_GET_VERSION, &msg, &len, MMAL_FALSE); + + if (status != MMAL_SUCCESS) + return status; + + if (!vcos_verify(len == sizeof(msg))) + return MMAL_EINVAL; + + *major = msg.major; + *minor = msg.minor; + *minimum = msg.minimum; + return MMAL_SUCCESS; +} + +/*****************************************************************************/ +MMAL_STATUS_T mmal_vc_get_stats(MMAL_VC_STATS_T *stats, int reset) +{ + mmal_worker_stats msg; + size_t len = sizeof(msg); + msg.reset = reset; + + MMAL_STATUS_T status = mmal_vc_sendwait_message(mmal_vc_get_client(), + &msg.header, sizeof(msg), + MMAL_WORKER_GET_STATS, + &msg, &len, MMAL_FALSE); + + + if (status == MMAL_SUCCESS) + { + vcos_assert(len == sizeof(msg)); + *stats = msg.stats; + } + return status; +} + +/** Set port buffer requirements. */ +static MMAL_STATUS_T mmal_vc_port_requirements_set(MMAL_PORT_T *port) +{ + MMAL_PORT_MODULE_T *module = port->priv->module; + MMAL_STATUS_T status; + mmal_worker_reply reply; + mmal_worker_port_action msg; + size_t replylen = sizeof(reply); + + msg.component_handle = module->component_handle; + msg.action = MMAL_WORKER_PORT_ACTION_SET_REQUIREMENTS; + msg.port_handle = module->port_handle; + msg.param.enable.port = *port; + + status = mmal_vc_sendwait_message(mmal_vc_get_client(), &msg.header, sizeof(msg), + MMAL_WORKER_PORT_ACTION, &reply, &replylen, MMAL_FALSE); + if (status == MMAL_SUCCESS) + { + vcos_assert(replylen == sizeof(reply)); + status = reply.status; + } + if (status != MMAL_SUCCESS) + LOG_ERROR("failed to set port requirements (%i/%i,%i/%i)", + port->buffer_num, port->buffer_num_min, + port->buffer_size, port->buffer_size_min); + + return status; +} + +/** Get port buffer requirements. */ +static MMAL_STATUS_T mmal_vc_port_requirements_get(MMAL_PORT_T *port) +{ + MMAL_PORT_MODULE_T *module = port->priv->module; + mmal_worker_port_info_get msg; + mmal_worker_port_info reply; + size_t replylen = sizeof(reply); + MMAL_STATUS_T status; + + msg.component_handle = module->component_handle; + msg.port_type = port->type; + msg.index = port->index; + + LOG_TRACE("get port requirements (%i:%i)", port->type, port->index); + + status = mmal_vc_sendwait_message(mmal_vc_get_client(), &msg.header, sizeof(msg), + MMAL_WORKER_PORT_INFO_GET, &reply, &replylen, MMAL_FALSE); + if (status == MMAL_SUCCESS) + { + vcos_assert(replylen == sizeof(reply)); + status = reply.status; + } + if (status != MMAL_SUCCESS) + { + LOG_ERROR("failed to get port requirements (%i:%i)", port->type, port->index); + return status; + } + + port->buffer_num_min = reply.port.buffer_num_min; + port->buffer_num_recommended = reply.port.buffer_num_recommended; + port->buffer_size_min = reply.port.buffer_size_min; + port->buffer_size_recommended = reply.port.buffer_size_recommended; + port->buffer_alignment_min = reply.port.buffer_alignment_min; + + return MMAL_SUCCESS; +} + +/** Enable processing on a port */ +static MMAL_STATUS_T mmal_vc_port_enable(MMAL_PORT_T *port, MMAL_PORT_BH_CB_T cb) +{ + MMAL_PORT_MODULE_T *module = port->priv->module; + MMAL_STATUS_T status; + mmal_worker_reply reply; + mmal_worker_port_action msg; + size_t replylen = sizeof(reply); + MMAL_PARAM_UNUSED(cb); + + if (!port->component->priv->module->event_ctx_initialised) + { + MMAL_POOL_T *pool = port->component->priv->event_pool; + MMAL_DRIVER_BUFFER_T *drv; + unsigned int i; + + /* We need to associate our vc client context to all our event buffers. + * This only needs to be done when the first port is enabled because no event + * can be received on disabled ports. */ + for (i = 0; i < pool->headers_num; i++) + { + drv = mmal_buffer_header_driver_data(pool->header[i]); + drv->client_context = &port->component->priv->module->event_ctx; + drv->magic = MMAL_MAGIC; + } + + port->component->priv->module->event_ctx_initialised = MMAL_TRUE; + } + + if (!module->connected) + { + if (vcos_blockpool_create_on_heap(&module->pool, port->buffer_num, + sizeof(MMAL_VC_CLIENT_BUFFER_CONTEXT_T), + VCOS_BLOCKPOOL_ALIGN_DEFAULT, VCOS_BLOCKPOOL_FLAG_NONE, "mmal vc port pool") != VCOS_SUCCESS) + { + LOG_ERROR("failed to create port pool"); + return MMAL_ENOMEM; + } + module->has_pool = 1; + } + + if (module->connected) + { + /* The connected port won't be enabled explicitly so make sure we apply + * the buffer requirements now. */ + status = mmal_vc_port_requirements_set(module->connected); + if (status != MMAL_SUCCESS) + goto error; + } + + msg.component_handle = module->component_handle; + msg.action = MMAL_WORKER_PORT_ACTION_ENABLE; + msg.port_handle = module->port_handle; + msg.param.enable.port = *port; + + status = mmal_vc_sendwait_message(mmal_vc_get_client(), &msg.header, sizeof(msg), + MMAL_WORKER_PORT_ACTION, &reply, &replylen, MMAL_FALSE); + if (status == MMAL_SUCCESS) + { + vcos_assert(replylen == sizeof(reply)); + status = reply.status; + } + if (status != MMAL_SUCCESS) + { + LOG_ERROR("failed to enable port %s: %s", + port->name, mmal_status_to_string(status)); + goto error; + } + + if (module->connected) + mmal_vc_port_info_get(module->connected); + + return MMAL_SUCCESS; + + error: + if (module->has_pool) + vcos_blockpool_delete(&module->pool); + return status; +} + +/** Disable processing on a port */ +static MMAL_STATUS_T mmal_vc_port_disable(MMAL_PORT_T *port) +{ + MMAL_PORT_MODULE_T *module = port->priv->module; + MMAL_STATUS_T status; + mmal_worker_reply reply; + mmal_worker_port_action msg; + size_t replylen = sizeof(reply); + + msg.component_handle = module->component_handle; + msg.action = MMAL_WORKER_PORT_ACTION_DISABLE; + msg.port_handle = module->port_handle; + + status = mmal_vc_sendwait_message(mmal_vc_get_client(), &msg.header, sizeof(msg), + MMAL_WORKER_PORT_ACTION, &reply, &replylen, MMAL_FALSE); + if (status == MMAL_SUCCESS) + { + vcos_assert(replylen == sizeof(reply)); + status = reply.status; + } + if (status != MMAL_SUCCESS) + LOG_ERROR("failed to disable port - reason %d", status); + + if (module->has_pool) + { + /* MMAL server should make sure that all buffers are sent back before it + * disables the port. */ + vcos_assert(vcos_blockpool_available_count(&module->pool) == port->buffer_num); + vcos_blockpool_delete(&module->pool); + module->has_pool = 0; + } + + /* We need to make sure all the queued callbacks have been done */ + while (mmal_queue_length(port->component->priv->module->callback_queue)) + mmal_vc_do_callback(port->component); + + if (module->connected) + mmal_vc_port_info_get(module->connected); + + return status; +} + +/** Flush a port using MMAL_WORKER_PORT_ACTION - when the port is zero-copy or no data has been sent */ +static MMAL_STATUS_T mmal_vc_port_flush_normal(MMAL_PORT_T *port) +{ + MMAL_PORT_MODULE_T *module = port->priv->module; + MMAL_STATUS_T status; + mmal_worker_reply reply; + mmal_worker_port_action msg; + size_t replylen = sizeof(reply); + + msg.component_handle = module->component_handle; + msg.action = MMAL_WORKER_PORT_ACTION_FLUSH; + msg.port_handle = module->port_handle; + + status = mmal_vc_sendwait_message(mmal_vc_get_client(), &msg.header, sizeof(msg), + MMAL_WORKER_PORT_ACTION, &reply, &replylen, MMAL_FALSE); + if (status == MMAL_SUCCESS) + { + vcos_assert(replylen == sizeof(reply)); + status = reply.status; + } + if (status != MMAL_SUCCESS) + LOG_ERROR("failed to disable port - reason %d", status); + + return status; +} + + +/** Flush a port using PORT_FLUSH - generates a dummy bulk transfer to keep it in sync + * with buffers being passed using bulk transfer */ +static MMAL_STATUS_T mmal_vc_port_flush_sync(MMAL_PORT_T *port) +{ + MMAL_PORT_MODULE_T *module = port->priv->module; + MMAL_STATUS_T status; + mmal_worker_reply reply; + MMAL_VC_CLIENT_BUFFER_CONTEXT_T client_context; + mmal_worker_buffer_from_host *msg; + + size_t replylen = sizeof(reply); + + msg = &client_context.msg; + + client_context.magic = MMAL_MAGIC; + client_context.port = port; + + msg->drvbuf.client_context = &client_context; + msg->drvbuf.component_handle = module->component_handle; + msg->drvbuf.port_handle = module->port_handle; + msg->drvbuf.magic = MMAL_MAGIC; + + + status = mmal_vc_sendwait_message(mmal_vc_get_client(), &msg->header, sizeof(*msg), + MMAL_WORKER_PORT_FLUSH, &reply, &replylen, MMAL_TRUE); + if (status == MMAL_SUCCESS) + { + vcos_assert(replylen == sizeof(reply)); + status = reply.status; + } + if (status != MMAL_SUCCESS) + LOG_ERROR("failed to disable port - reason %d", status); + + return status; +} + +/** Flush a port */ +static MMAL_STATUS_T mmal_vc_port_flush(MMAL_PORT_T *port) +{ + static MMAL_PORT_FLUSH_CHECK_T is_port_flush_compatible = PORT_FLUSH_NOT_INITIALIZED; + uint32_t major = 0, minor = 0, minimum = 0; + MMAL_STATUS_T status; + /* Buffers sent to videocore, if not zero-copy, use vchiq bulk transfers to copy the data. + A flush could be sent while one of these buffers is being copied. If the normal flushing method + is used, the flush can arrive before the buffer, which causes confusion when a pre-flush buffer + arrives after the flush. So use a special flush mode that uses a dummy vchiq transfer to synchronise + things. + If data has never been sent on the port, then we don't need to worry about a flush overtaking data. + In that case, the port may not actually be set up on the other end to receive bulk transfers, so use + the normal flushing mechanism in that case. + */ + + if (port->priv->module->is_zero_copy || !port->priv->module->sent_data_on_port) + return mmal_vc_port_flush_normal(port); + + if (is_port_flush_compatible == PORT_FLUSH_NOT_INITIALIZED) + { + status = mmal_vc_get_version(&major, &minor, &minimum); + if (major >= 15) + { + is_port_flush_compatible = PORT_FLUSH_COMPATIBLE; + } + else + { + LOG_ERROR("Version number of MMAL Server incompatible. Required Major:14 Minor: 2 \ + or Greater. Current Major %d , Minor %d",major,minor); + is_port_flush_compatible = PORT_FLUSH_INCOMPATIBLE; + } + } + + if (is_port_flush_compatible == PORT_FLUSH_COMPATIBLE) + return mmal_vc_port_flush_sync(port); + else + return mmal_vc_port_flush_normal(port); +} + + +/** Connect 2 ports together */ +static MMAL_STATUS_T mmal_vc_port_connect(MMAL_PORT_T *port, MMAL_PORT_T *other_port) +{ + MMAL_PORT_MODULE_T *module = port->priv->module; + MMAL_STATUS_T status; + mmal_worker_reply reply; + mmal_worker_port_action msg; + size_t replylen = sizeof(reply); + + /* We only support connecting vc components together */ + if (other_port && port->priv->pf_enable != other_port->priv->pf_enable) + return MMAL_ENOSYS; + + /* Send the request to the video side */ + msg.component_handle = module->component_handle; + msg.action = other_port ? MMAL_WORKER_PORT_ACTION_CONNECT : MMAL_WORKER_PORT_ACTION_DISCONNECT; + msg.port_handle = module->port_handle; + if (other_port) + { + msg.param.connect.component_handle = other_port->priv->module->component_handle; + msg.param.connect.port_handle = other_port->priv->module->port_handle; + } + + status = mmal_vc_sendwait_message(mmal_vc_get_client(), &msg.header, sizeof(msg), + MMAL_WORKER_PORT_ACTION, &reply, &replylen, MMAL_FALSE); + if (status == MMAL_SUCCESS) + { + vcos_assert(replylen == sizeof(reply)); + status = reply.status; + } + + if (status != MMAL_SUCCESS) + { + LOG_ERROR("failed to connect ports: %s", mmal_status_to_string(status)); + return status; + } + + if (other_port) + { + /* Connection */ + module->connected = other_port; + other_port->priv->module->connected = port; + } + else + { + /* Disconnection */ + if (module->connected) + module->connected->priv->module->connected = NULL; + module->connected = NULL; + } + + return MMAL_SUCCESS; +} + +/*****************************************************************************/ +static void mmal_vc_do_callback(MMAL_COMPONENT_T *component) +{ + MMAL_COMPONENT_MODULE_T *module = component->priv->module; + MMAL_BUFFER_HEADER_T *buffer; + MMAL_PORT_T *port; + + /* Get a buffer from this port */ + buffer = mmal_queue_get(module->callback_queue); + if (!buffer) + return; /* Will happen when a port gets disabled */ + + port = (MMAL_PORT_T *)buffer->priv->component_data; + + /* Catch and report any transmission error */ + if (buffer->flags & MMAL_BUFFER_HEADER_FLAG_TRANSMISSION_FAILED) + mmal_event_error_send(port->component, MMAL_EIO); + + /* Events generated by this component are handled differently */ + if (mmal_buffer_header_driver_data(buffer)->client_context == + &component->priv->module->event_ctx) + { + mmal_port_event_send(port, buffer); + return; + } + + buffer->data = mmal_vc_shm_lock(buffer->data, port->priv->module->zero_copy_workaround); + mmal_port_buffer_header_callback(port, buffer); +} + +static void mmal_vc_do_callback_loop(MMAL_COMPONENT_T *component) +{ + while (mmal_queue_length(component->priv->module->callback_queue)) + mmal_vc_do_callback(component); +} + +/** Called back from VCHI(Q) event handler when buffers come back from the copro. + * + * The message points to the message sent by videocore, and which should have + * a pointer back to our original client side context. + * + */ +static void mmal_vc_port_send_callback(mmal_worker_buffer_from_host *msg) +{ + MMAL_BUFFER_HEADER_T *buffer; + MMAL_PORT_T *port; + MMAL_VC_CLIENT_BUFFER_CONTEXT_T *client_context = msg->drvbuf.client_context; + + vcos_assert(client_context); + vcos_assert(client_context->magic == MMAL_MAGIC); + + buffer = client_context->buffer; + port = client_context->port; + vcos_blockpool_free(msg->drvbuf.client_context); + + vcos_assert(port->priv->module->magic == MMAL_MAGIC); + mmal_vc_msg_to_buffer_header(buffer, msg); + + /* Queue the callback so it is delivered by the action thread */ + buffer->priv->component_data = (void *)port; + mmal_queue_put(port->component->priv->module->callback_queue, buffer); + mmal_component_action_trigger(port->component); +} + +static void mmal_vc_port_send_event_callback(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) +{ + /* Queue the event to be delivered by the action thread */ + buffer->priv->component_data = (void *)port; + mmal_queue_put(port->component->priv->module->callback_queue, buffer); + mmal_component_action_trigger(port->component); +} + +/** Called from the client to send a buffer (empty or full) to + * the copro. + */ +static MMAL_STATUS_T mmal_vc_port_send(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) +{ + MMAL_PORT_MODULE_T *module = port->priv->module; + MMAL_STATUS_T status; + MMAL_VC_CLIENT_BUFFER_CONTEXT_T *client_context; + mmal_worker_buffer_from_host *msg; + uint32_t length; + uint32_t msgid = MMAL_WORKER_BUFFER_FROM_HOST; + uint32_t major = 0, minor = 0, minimum = 0; + static MMAL_ZEROLEN_CHECK_T is_vc_zerolength_compatible = ZEROLEN_NOT_INITIALIZED; + + vcos_assert(port); + vcos_assert(module); + vcos_assert(module->magic == MMAL_MAGIC); + + /* Handle event buffers */ + if (buffer->cmd) + { + MMAL_EVENT_FORMAT_CHANGED_T *event = mmal_event_format_changed_get(buffer); + if (event) + { + mmal_format_copy(port->format, event->format); + status = port->priv->pf_set_format(port); + if(status != MMAL_SUCCESS) + LOG_ERROR("format not set on port %p", port); + } + else + { + LOG_ERROR("discarding event %i on port %p", (int)buffer->cmd, port); + } + + buffer->length = 0; + mmal_port_buffer_header_callback(port, buffer); + return MMAL_SUCCESS; + } + + /* We can only send buffers if we have a pool */ + if (!module->has_pool) + { + LOG_ERROR("no pool on port %p", port); + return MMAL_EINVAL; + } + + client_context = vcos_blockpool_alloc(&module->pool); + if(!client_context) + { + LOG_INFO("couldn't allocate client buffer context from pool"); + return MMAL_ENOMEM; + } + msg = &client_context->msg; + + client_context->magic = MMAL_MAGIC; + client_context->buffer = buffer; + client_context->callback = mmal_vc_port_send_callback; + client_context->callback_event = NULL; + client_context->port = port; + + msg->drvbuf.client_context = client_context; + msg->drvbuf.component_handle = module->component_handle; + msg->drvbuf.port_handle = module->port_handle; + msg->drvbuf.magic = MMAL_MAGIC; + + length = buffer->length; + + if (length <= MMAL_VC_SHORT_DATA && !port->priv->module->is_zero_copy && + port->format->encoding == MMAL_ENCODING_OPAQUE) + { + memcpy(msg->short_data, buffer->data + buffer->offset, buffer->length); + msg->payload_in_message = length; + length = 0; + } + else + { + msg->payload_in_message = 0; + } + + buffer->data = + mmal_vc_shm_unlock(buffer->data, &length, port->priv->module->zero_copy_workaround); + mmal_vc_buffer_header_to_msg(msg, buffer); + + if (!VCOS_BLOCKPOOL_IS_VALID_HANDLE_FORMAT(msg->drvbuf.component_handle, 256)) + { + LOG_ERROR("bad component handle 0x%x", msg->drvbuf.component_handle); + return MMAL_EINVAL; + } + + if (msg->drvbuf.port_handle > 255) + { + LOG_ERROR("bad port handle 0x%x", msg->drvbuf.port_handle); + return MMAL_EINVAL; + } + + if (module->is_zero_copy) + length = 0; + + if (is_vc_zerolength_compatible == ZEROLEN_NOT_INITIALIZED) + { + status = mmal_vc_get_version(&major, &minor, &minimum); + if ((major > 12 ) || ((major == 12) && (minor >= 2))) + { + is_vc_zerolength_compatible = ZEROLEN_COMPATIBLE; + } + else + { + LOG_ERROR("Version number of MMAL Server incompatible. Required Major:12 Minor: 2 \ + or Greater. Current Major %d , Minor %d",major,minor); + is_vc_zerolength_compatible = ZEROLEN_INCOMPATIBLE; + } + } + + if ((is_vc_zerolength_compatible == ZEROLEN_COMPATIBLE) && !(module->is_zero_copy) && !length + && (msg->buffer_header.flags & MMAL_BUFFER_HEADER_FLAG_EOS)) + { + length = 8; + msgid = MMAL_WORKER_BUFFER_FROM_HOST_ZEROLEN; + } + + if (length) + { + // We're doing a bulk transfer. Note this so that flushes know + // they need to use the more cumbersome fake-bulk-transfer mechanism + // to guarantee correct ordering. + port->priv->module->sent_data_on_port = MMAL_TRUE; + + // Data will be received at the start of the destination buffer, so fixup + // the offset in the destination buffer header. + msg->buffer_header.offset = 0; + } + + status = mmal_vc_send_message(mmal_vc_get_client(), &msg->header, sizeof(*msg), + buffer->data + buffer->offset, length, + msgid); + if (status != MMAL_SUCCESS) + { + LOG_INFO("failed %d", status); + vcos_blockpool_free(msg->drvbuf.client_context); + buffer->data = mmal_vc_shm_lock(buffer->data, port->priv->module->zero_copy_workaround); + } + + return status; +} + +static MMAL_STATUS_T mmal_vc_component_disable(MMAL_COMPONENT_T *component) +{ + MMAL_STATUS_T status; + mmal_worker_reply reply; + mmal_worker_component_disable msg; + size_t replylen = sizeof(reply); + + vcos_assert(component && component->priv && component->priv->module); + + msg.component_handle = component->priv->module->component_handle; + + status = mmal_vc_sendwait_message(mmal_vc_get_client(), &msg.header, sizeof(msg), + MMAL_WORKER_COMPONENT_DISABLE, + &reply, &replylen, MMAL_FALSE); + + if (status == MMAL_SUCCESS) + { + vcos_assert(replylen == sizeof(reply)); + status = reply.status; + } + + if (status != MMAL_SUCCESS && status != MMAL_ENOSYS) + { + LOG_ERROR("failed to disable component - reason %d", status); + goto fail; + } + + return status; +fail: + return status; +} + +static MMAL_STATUS_T mmal_vc_component_enable(MMAL_COMPONENT_T *component) +{ + MMAL_STATUS_T status; + mmal_worker_reply reply; + mmal_worker_component_enable msg; + size_t replylen = sizeof(reply); + + vcos_assert(component && component->priv && component->priv->module); + + msg.component_handle = component->priv->module->component_handle; + + status = mmal_vc_sendwait_message(mmal_vc_get_client(), &msg.header, sizeof(msg), + MMAL_WORKER_COMPONENT_ENABLE, &reply, &replylen, MMAL_FALSE); + + if (status == MMAL_SUCCESS) + { + vcos_assert(replylen == sizeof(reply)); + status = reply.status; + } + + if (status != MMAL_SUCCESS && status != MMAL_ENOSYS) + { + LOG_ERROR("failed to enable component: %s", mmal_status_to_string(status)); + return status; + } + + return MMAL_SUCCESS; +} + +static MMAL_STATUS_T mmal_vc_component_destroy(MMAL_COMPONENT_T *component) +{ + MMAL_STATUS_T status; + mmal_worker_component_destroy msg; + mmal_worker_reply reply; + size_t replylen = sizeof(reply); + + vcos_assert(component && component->priv && component->priv->module); + + msg.component_handle = component->priv->module->component_handle; + + status = mmal_vc_sendwait_message(mmal_vc_get_client(), &msg.header, sizeof(msg), + MMAL_WORKER_COMPONENT_DESTROY, + &reply, &replylen, MMAL_FALSE); + + if (status == MMAL_SUCCESS) + { + vcos_assert(replylen == sizeof(reply)); + status = reply.status; + } + if (status != MMAL_SUCCESS) + { + LOG_ERROR("failed to destroy component - reason %d", status ); + goto fail; + } + + if(component->input_num) + mmal_ports_free(component->input, component->input_num); + if(component->output_num) + mmal_ports_free(component->output, component->output_num); + if(component->clock_num) + mmal_ports_free(component->clock, component->clock_num); + + mmal_queue_destroy(component->priv->module->callback_queue); + + vcos_free(component->priv->module); + component->priv->module = NULL; + +fail: + // no longer require videocore + mmal_vc_release(); + mmal_vc_deinit(); + return status; +} + +MMAL_STATUS_T mmal_vc_consume_mem(size_t size, uint32_t *handle) +{ + MMAL_STATUS_T status; + mmal_worker_consume_mem req; + mmal_worker_consume_mem reply; + size_t len = sizeof(reply); + + req.size = (uint32_t) size; + + status = mmal_vc_sendwait_message(mmal_vc_get_client(), + &req.header, sizeof(req), + MMAL_WORKER_CONSUME_MEM, + &reply, &len, MMAL_FALSE); + if (status == MMAL_SUCCESS) + { + vcos_assert(len == sizeof(reply)); + status = reply.status; + *handle = reply.handle; + } + return status; +} + +MMAL_STATUS_T mmal_vc_lmk(uint32_t alloc_size) +{ + MMAL_STATUS_T status; + mmal_worker_lmk req; + mmal_worker_lmk reply; + size_t len = sizeof(reply); + + req.alloc_size = alloc_size; + + status = mmal_vc_sendwait_message(mmal_vc_get_client(), + &req.header, sizeof(req), + MMAL_WORKER_LMK, + &reply, &len, MMAL_FALSE); + return status; +} + +MMAL_STATUS_T mmal_vc_host_log(const char *msg) +{ + MMAL_STATUS_T status = MMAL_EINVAL; + if (msg) + { + mmal_worker_host_log req; + mmal_worker_reply reply; + size_t replylen = sizeof(reply); + size_t msg_len = vcos_safe_strcpy(req.msg, msg, sizeof(req.msg), 0); + + /* Reduce the length if it is shorter than the max message length */ + status = mmal_vc_sendwait_message(mmal_vc_get_client(), &req.header, + sizeof(req) - sizeof(req.msg) + vcos_min(sizeof(req.msg), msg_len + 1), + MMAL_WORKER_HOST_LOG, + &reply, &replylen, MMAL_FALSE); + + if (status == MMAL_SUCCESS) + { + vcos_assert(replylen == sizeof(reply)); + status = reply.status; + } + } + return status; +} + +MMAL_STATUS_T mmal_vc_get_core_stats(MMAL_CORE_STATISTICS_T *stats, + MMAL_STATS_RESULT_T *result, + char *name, + size_t namelen, + MMAL_PORT_TYPE_T type, + unsigned component_index, + unsigned port_index, + MMAL_CORE_STATS_DIR dir, + MMAL_BOOL_T reset) +{ + mmal_worker_get_core_stats_for_port req; + mmal_worker_get_core_stats_for_port_reply reply; + MMAL_STATUS_T status; + size_t len = sizeof(reply); + + req.component_index = component_index; + req.port_index = port_index; + req.type = type; + req.reset = reset; + req.dir = dir; + + status = mmal_vc_sendwait_message(mmal_vc_get_client(), + &req.header, sizeof(req), + MMAL_WORKER_GET_CORE_STATS_FOR_PORT, + &reply, &len, MMAL_FALSE); + + if (status == MMAL_SUCCESS) + { + vcos_assert(len == sizeof(reply)); + *stats = reply.stats; + *result = reply.result; + strncpy(name, reply.component_name, namelen); + name[namelen-1] = '\0'; + } + return status; +} + + +/** Get port context data. */ +static MMAL_STATUS_T mmal_vc_port_info_get(MMAL_PORT_T *port) +{ + MMAL_PORT_MODULE_T *module = port->priv->module; + mmal_worker_port_info_get msg; + mmal_worker_port_info reply; + size_t replylen = sizeof(reply); + MMAL_STATUS_T status; + + msg.component_handle = module->component_handle; + msg.port_type = port->type; + msg.index = port->index; + + LOG_TRACE("get port info (%i:%i)", port->type, port->index); + + status = mmal_vc_sendwait_message(mmal_vc_get_client(), &msg.header, sizeof(msg), + MMAL_WORKER_PORT_INFO_GET, &reply, &replylen, MMAL_FALSE); + if (status == MMAL_SUCCESS) + { + vcos_assert(replylen == sizeof(reply)); + status = reply.status; + } + + if (status != MMAL_SUCCESS) + { + LOG_ERROR("failed to get port info (%i:%i): %s", port->type, port->index, + mmal_status_to_string(status)); + return status; + } + + module->port_handle = reply.port_handle; + port->buffer_num_min = reply.port.buffer_num_min; + port->buffer_num_recommended = reply.port.buffer_num_recommended; + port->buffer_num = reply.port.buffer_num; + port->buffer_size_min = reply.port.buffer_size_min; + port->buffer_size_recommended = reply.port.buffer_size_recommended; + port->buffer_size = reply.port.buffer_size; + port->buffer_alignment_min = reply.port.buffer_alignment_min; + port->is_enabled = reply.port.is_enabled; + port->capabilities = reply.port.capabilities; + reply.format.extradata = port->format->extradata; + reply.format.es = port->format->es; + *port->format = reply.format; + *port->format->es = reply.es; + if(port->format->extradata_size) + { + status = mmal_format_extradata_alloc(port->format, port->format->extradata_size); + if(status != MMAL_SUCCESS) + { + vcos_assert(0); + port->format->extradata_size = 0; + LOG_ERROR("couldn't allocate extradata %i", port->format->extradata_size); + return MMAL_ENOMEM; + } + memcpy(port->format->extradata, reply.extradata, port->format->extradata_size); + } + + return MMAL_SUCCESS; +} + +/** Set port context data. */ +static MMAL_STATUS_T mmal_vc_port_info_set(MMAL_PORT_T *port) +{ + MMAL_PORT_MODULE_T *module = port->priv->module; + mmal_worker_port_info_set msg; + mmal_worker_port_info reply; + size_t replylen = sizeof(reply); + MMAL_STATUS_T status; + + msg.component_handle = module->component_handle; + msg.port_type = port->type; + msg.index = port->index; + msg.port = *port; + msg.format = *port->format; + msg.es = *port->format->es; + if(msg.format.extradata_size > MMAL_FORMAT_EXTRADATA_MAX_SIZE) + { + vcos_assert(0); + msg.format.extradata_size = MMAL_FORMAT_EXTRADATA_MAX_SIZE; + } + memcpy(msg.extradata, msg.format.extradata, msg.format.extradata_size); + + LOG_TRACE("set port info (%i:%i)", port->type, port->index); + + status = mmal_vc_sendwait_message(mmal_vc_get_client(), &msg.header, sizeof(msg), + MMAL_WORKER_PORT_INFO_SET, &reply, &replylen, MMAL_FALSE); + if (status == MMAL_SUCCESS) + { + vcos_assert(replylen == sizeof(reply)); + status = reply.status; + } + + if (status != MMAL_SUCCESS) + { + LOG_ERROR("failed to set port info (%i:%i): %s", port->type, port->index, + mmal_status_to_string(status)); + return status; + } + + port->buffer_num_min = reply.port.buffer_num_min; + port->buffer_num_recommended = reply.port.buffer_num_recommended; + port->buffer_num = reply.port.buffer_num; + port->buffer_size_min = reply.port.buffer_size_min; + port->buffer_size_recommended = reply.port.buffer_size_recommended; + port->buffer_size = reply.port.buffer_size; + port->buffer_alignment_min = reply.port.buffer_alignment_min; + port->is_enabled = reply.port.is_enabled; + port->capabilities = reply.port.capabilities; + reply.format.extradata = port->format->extradata; + reply.format.es = port->format->es; + *port->format = reply.format; + *port->format->es = reply.es; + if(port->format->extradata_size) + { + status = mmal_format_extradata_alloc(port->format, port->format->extradata_size); + if(status != MMAL_SUCCESS) + { + vcos_assert(0); + port->format->extradata_size = 0; + LOG_ERROR("couldn't allocate extradata %i", port->format->extradata_size); + return MMAL_ENOMEM; + } + memcpy(port->format->extradata, reply.extradata, port->format->extradata_size); + } + + return MMAL_SUCCESS; +} + +/** Set format on a port */ +static MMAL_STATUS_T mmal_vc_port_set_format(MMAL_PORT_T *port) +{ + MMAL_COMPONENT_T *component = port->component; + MMAL_COMPONENT_MODULE_T *module = component->priv->module; + MMAL_STATUS_T status; + unsigned int i; + + status = mmal_vc_port_info_set(port); + if (status != MMAL_SUCCESS) + { + LOG_ERROR("mmal_vc_port_info_set failed %p (%s)", port, + mmal_status_to_string(status)); + return status; + } + + /* Get the setting back for this port */ + status = mmal_vc_port_info_get(port); + if (status != MMAL_SUCCESS) + { + LOG_ERROR("mmal_vc_port_info_get failed %p (%s)", port, + mmal_status_to_string(status)); + return status; + } + + /* Get the settings for the output ports in case they have changed */ + if (port->type == MMAL_PORT_TYPE_INPUT) + { + for (i = 0; i < module->ports_num; i++) + { + if (module->ports[i]->port->type != MMAL_PORT_TYPE_OUTPUT) + continue; + + status = mmal_vc_port_info_get(module->ports[i]->port); + if (status != MMAL_SUCCESS) + { + LOG_ERROR("mmal_vc_port_info_get failed %p (%i)", + module->ports[i]->port, status); + return status; + } + } + } + + return MMAL_SUCCESS; +} + +/** Set parameter on a port */ +static MMAL_STATUS_T mmal_vc_port_parameter_set(MMAL_PORT_T *port, const MMAL_PARAMETER_HEADER_T *param) +{ + MMAL_PORT_MODULE_T *module = port->priv->module; + MMAL_STATUS_T status; + mmal_worker_port_param_set msg; + size_t msglen = MMAL_OFFSET(mmal_worker_port_param_set, param) + param->size; + mmal_worker_reply reply; + size_t replylen = sizeof(reply); + + if(param->size > MMAL_WORKER_PORT_PARAMETER_SET_MAX) + { + LOG_ERROR("parameter too large (%u > %u)", param->size, MMAL_WORKER_PORT_PARAMETER_SET_MAX); + return MMAL_ENOSPC; + } + + /* Intercept the zero copy parameter */ + if (param->id == MMAL_PARAMETER_ZERO_COPY && + param->size >= sizeof(MMAL_PARAMETER_BOOLEAN_T) ) + { + module->is_zero_copy = !!((MMAL_PARAMETER_BOOLEAN_T *)param)->enable; + module->zero_copy_workaround = ((MMAL_PARAMETER_BOOLEAN_T *)param)->enable == 0xBEEF; + LOG_DEBUG("%s zero copy on port %p", module->is_zero_copy ? "enable" : "disable", port); + } + + msg.component_handle = module->component_handle; + msg.port_handle = module->port_handle; + /* coverity[overrun-buffer-arg] */ + memcpy(&msg.param, param, param->size); + + status = mmal_vc_sendwait_message(mmal_vc_get_client(), &msg.header, msglen, + MMAL_WORKER_PORT_PARAMETER_SET, &reply, &replylen, MMAL_FALSE); + + if (status == MMAL_SUCCESS) + { + vcos_assert(replylen == sizeof(reply)); + status = reply.status; + } + if (status != MMAL_SUCCESS) + { + LOG_WARN("failed to set port parameter %u:%u %u:%u %s", msg.component_handle, msg.port_handle, + param->id, param->size, mmal_status_to_string(status)); + return status; + } + + if (param->id == MMAL_PARAMETER_BUFFER_REQUIREMENTS) + { + /* This might have changed the buffer requirements of other ports so fetch them all */ + MMAL_COMPONENT_T *component = port->component; + unsigned int i; + for (i = 0; status == MMAL_SUCCESS && i < component->input_num; i++) + status = mmal_vc_port_requirements_get(component->input[i]); + for (i = 0; status == MMAL_SUCCESS && i < component->output_num; i++) + status = mmal_vc_port_requirements_get(component->output[i]); + } + + return status; +} + +/** Get parameter on a port */ +static MMAL_STATUS_T mmal_vc_port_parameter_get(MMAL_PORT_T *port, MMAL_PARAMETER_HEADER_T *param) +{ + MMAL_PORT_MODULE_T *module = port->priv->module; + MMAL_STATUS_T status; + mmal_worker_port_param_get msg; + size_t msglen = MMAL_OFFSET(mmal_worker_port_param_get, param) + param->size; + mmal_worker_port_param_get_reply reply; + size_t replylen = MMAL_OFFSET(mmal_worker_port_param_get_reply, param) + param->size; + + if(param->size > MMAL_WORKER_PORT_PARAMETER_GET_MAX) + { + LOG_ERROR("parameter too large (%u > %u) id %u", param->size, + MMAL_WORKER_PORT_PARAMETER_GET_MAX, param->id); + return MMAL_ENOMEM; + } + + msg.component_handle = module->component_handle; + msg.port_handle = module->port_handle; + memcpy(&msg.param, param, param->size); + + status = mmal_vc_sendwait_message(mmal_vc_get_client(), &msg.header, msglen, + MMAL_WORKER_PORT_PARAMETER_GET, &reply, &replylen, MMAL_FALSE); + if (status == MMAL_SUCCESS) + { + status = reply.status; + /* Reply must include the parameter header */ + vcos_assert(replylen >= MMAL_OFFSET(mmal_worker_port_param_get_reply, space)); + + /* If the call fails with MMAL_ENOSPC then reply.param.size is set to the size required for + * the call to succeed, and that may be bigger than the buffers, so only check these asserts + * if the call succeeded. + */ + if ( status == MMAL_SUCCESS ) + { + /* Reply mustn't be bigger than the parameter given */ + vcos_assert(replylen <= (MMAL_OFFSET(mmal_worker_port_param_get_reply, param) + param->size)); + /* Reply must be consistent with the parameter size embedded in it */ + vcos_assert(replylen == (MMAL_OFFSET(mmal_worker_port_param_get_reply, param) + reply.param.size)); + } + } + + if (status != MMAL_SUCCESS && status != MMAL_ENOSPC) + { + LOG_WARN("failed to get port parameter %u:%u %u:%u %s", msg.component_handle, msg.port_handle, + param->id, param->size, mmal_status_to_string(status)); + return status; + } + + if (status == MMAL_ENOSPC) + { + /* Copy only as much as we have space for but report true size of parameter */ + /* coverity[overrun-buffer-arg] */ + memcpy(param, &reply.param, param->size); + param->size = reply.param.size; + } + else + { + memcpy(param, &reply.param, reply.param.size); + } + + return status; +} + +static uint8_t *mmal_vc_port_payload_alloc(MMAL_PORT_T *port, uint32_t payload_size) +{ + MMAL_PORT_MODULE_T *module = port->priv->module; + MMAL_BOOL_T can_deref = MMAL_TRUE; + char buf[5]; + MMAL_PARAM_UNUSED(module); + void *ret; + (void)buf; + + LOG_TRACE("%s: allocating %d bytes, format %s, is_zero_copy %d", + port->name, + payload_size, + mmal_4cc_to_string(buf, sizeof(buf), port->format->encoding), + module->is_zero_copy); + + if (port->format->encoding == MMAL_ENCODING_OPAQUE && + module->is_zero_copy) + { + MMAL_OPAQUE_IMAGE_HANDLE_T h = mmal_vc_opaque_alloc_desc(port->name); + can_deref = MMAL_FALSE; + ret = (void*)h; + if (!ret) + { + LOG_ERROR("%s: failed to allocate %d bytes opaque memory", + port->name, payload_size); + return NULL; + } + } + + else if (module->is_zero_copy) + { + ret = mmal_vc_shm_alloc(payload_size); + if (!ret) + { + LOG_ERROR("%s: failed to allocate %d bytes of shared memory", + port->name, payload_size); + return NULL; + } + } + + else + { + /* Allocate conventional memory */ + ret = vcos_malloc(payload_size, "mmal_vc_port payload"); + if (!ret) + { + LOG_ERROR("could not allocate %i bytes", (int)payload_size); + return NULL; + } + } + + /* Ensure that newly minted opaque buffers are always in a sensible + * state, and don't have random garbage in them. + */ + if (can_deref && port->format->encoding == MMAL_ENCODING_OPAQUE) + memset(ret, 0, payload_size); + + LOG_DEBUG("%s: allocated at %p", port->name, ret); + return ret; +} + +static void mmal_vc_port_payload_free(MMAL_PORT_T *port, uint8_t *payload) +{ + MMAL_PARAM_UNUSED(port); + + if (port->format->encoding == MMAL_ENCODING_OPAQUE) + { + mmal_vc_opaque_release((MMAL_OPAQUE_IMAGE_HANDLE_T)payload); + return; + } + + else if (mmal_vc_shm_free(payload) == MMAL_SUCCESS) + return; + + /* We're dealing with conventional memory */ + vcos_free(payload); +} + +/** Create a component given its name. */ +static MMAL_STATUS_T mmal_vc_component_create(const char *name, MMAL_COMPONENT_T *component) +{ + MMAL_STATUS_T status; + const char *basename; + mmal_worker_component_create msg; + mmal_worker_component_create_reply reply; + size_t replylen = sizeof(reply); + MMAL_COMPONENT_MODULE_T *module = NULL; + unsigned int ports_num, i; + + LOG_TRACE("%s", name); + + if (strstr(name, VIDEOCORE_PREFIX ".") != name) + return MMAL_ENOSYS; + + basename = name + sizeof(VIDEOCORE_PREFIX ".") - 1; + if (strlen(basename) >= sizeof(msg.name)-1) + { + vcos_assert(0); + return MMAL_EINVAL; + } + + msg.client_component = component; + /* coverity[secure_coding] Length tested above */ + strcpy(msg.name, basename); +#ifdef __linux__ + msg.pid = getpid(); +#endif + + status = mmal_vc_init(); + if (status != MMAL_SUCCESS) + { + LOG_ERROR("failed to initialise mmal ipc for '%s' (%i:%s)", + name, status, mmal_status_to_string(status)); + return status; + } + // claim VC for entire duration of component. + status = mmal_vc_use(); + + status = mmal_vc_sendwait_message(mmal_vc_get_client(), &msg.header, sizeof(msg), + MMAL_WORKER_COMPONENT_CREATE, &reply, &replylen, MMAL_FALSE); + + vcos_log_info("%s: %s: handle 0x%x status %d reply status %d", + __FUNCTION__, name, reply.component_handle, status, reply.status); + + if (status == MMAL_SUCCESS) + { + vcos_assert(replylen == sizeof(reply)); + status = reply.status; + } + + if (status != MMAL_SUCCESS) + { + LOG_ERROR("failed to create component '%s' (%i:%s)", name, status, + mmal_status_to_string(status)); + mmal_vc_release(); + mmal_vc_deinit(); + return status; + } + + /* Component has been created, allocate our context. */ + status = MMAL_ENOMEM; + ports_num = 1 + reply.input_num + reply.output_num + reply.clock_num; + module = vcos_calloc(1, sizeof(*module) + ports_num * sizeof(*module->ports), "mmal_vc_module"); + if (!module) + { + mmal_worker_component_destroy msg; + mmal_worker_reply reply; + size_t replylen = sizeof(reply); + MMAL_STATUS_T destroy_status; + + destroy_status = mmal_vc_sendwait_message(mmal_vc_get_client(), &msg.header, sizeof(msg), + MMAL_WORKER_COMPONENT_DESTROY, &reply, &replylen, MMAL_FALSE); + vcos_assert(destroy_status == MMAL_SUCCESS); + mmal_vc_release(); + mmal_vc_deinit(); + return status; + } + module->ports = (MMAL_PORT_MODULE_T **)&module[1]; + module->component_handle = reply.component_handle; + component->priv->module = module; + + /* Allocate our local ports. Control port reallocated to set module size. */ + mmal_port_free(component->control); + component->control = mmal_port_alloc(component, MMAL_PORT_TYPE_CONTROL, + sizeof(MMAL_PORT_MODULE_T)); + if (!component->control) + goto fail; + + if (reply.input_num) + { + component->input = mmal_ports_alloc(component, reply.input_num, MMAL_PORT_TYPE_INPUT, + sizeof(MMAL_PORT_MODULE_T)); + if (!component->input) + goto fail; + } + component->input_num = reply.input_num; + + if (reply.output_num) + { + component->output = mmal_ports_alloc(component, reply.output_num, MMAL_PORT_TYPE_OUTPUT, + sizeof(MMAL_PORT_MODULE_T)); + if (!component->output) + goto fail; + } + component->output_num = reply.output_num; + + if (reply.clock_num) + { + component->clock = mmal_ports_alloc(component, reply.clock_num, MMAL_PORT_TYPE_CLOCK, + sizeof(MMAL_PORT_MODULE_T)); + if (!component->clock) + goto fail; + } + component->clock_num = reply.clock_num; + + /* We want to do the buffer callbacks to the client into a separate thread. + * We'll need to queue these callbacks and have an action which does the actual callback. */ + module->callback_queue = mmal_queue_create(); + if (!module->callback_queue) + goto fail; + status = mmal_component_action_register(component, mmal_vc_do_callback_loop); + if (status != MMAL_SUCCESS) + goto fail; + + LOG_TRACE(" handle %i", reply.component_handle); + + module->ports[module->ports_num] = component->control->priv->module; + module->ports[module->ports_num]->port = component->control; + module->ports[module->ports_num]->component_handle = module->component_handle; + module->ports_num++; + + for (i = 0; i < component->input_num; i++, module->ports_num++) + { + module->ports[module->ports_num] = component->input[i]->priv->module; + module->ports[module->ports_num]->port = component->input[i]; + module->ports[module->ports_num]->component_handle = module->component_handle; + } + + for (i = 0; i < component->output_num; i++, module->ports_num++) + { + module->ports[module->ports_num] = component->output[i]->priv->module; + module->ports[module->ports_num]->port = component->output[i]; + module->ports[module->ports_num]->component_handle = module->component_handle; + } + + for (i = 0; i < component->clock_num; i++, module->ports_num++) + { + module->ports[module->ports_num] = component->clock[i]->priv->module; + module->ports[module->ports_num]->port = component->clock[i]; + module->ports[module->ports_num]->component_handle = module->component_handle; + } + + /* Get the ports info */ + for (i = 0; i < module->ports_num; i++) + { + MMAL_PORT_T *port = module->ports[i]->port; + port->priv->pf_set_format = mmal_vc_port_set_format; + port->priv->pf_enable = mmal_vc_port_enable; + port->priv->pf_disable = mmal_vc_port_disable; + port->priv->pf_send = mmal_vc_port_send; + port->priv->pf_flush = mmal_vc_port_flush; + port->priv->pf_connect = mmal_vc_port_connect; + port->priv->pf_parameter_set = mmal_vc_port_parameter_set; + port->priv->pf_parameter_get = mmal_vc_port_parameter_get; + port->priv->pf_payload_alloc = mmal_vc_port_payload_alloc; + port->priv->pf_payload_free = mmal_vc_port_payload_free; + port->priv->module->component_handle = module->component_handle; + port->priv->module->magic = MMAL_MAGIC; + + status = mmal_vc_port_info_get(port); + if (status != MMAL_SUCCESS) + goto fail; + } + + /* Initialise the vc client context which will be used for our event buffers */ + module->event_ctx_initialised = MMAL_FALSE; + module->event_ctx.magic = MMAL_MAGIC; + module->event_ctx.callback_event = mmal_vc_port_send_event_callback; + + /* populate component structure */ + component->priv->pf_enable = mmal_vc_component_enable; + component->priv->pf_disable = mmal_vc_component_disable; + component->priv->pf_destroy = mmal_vc_component_destroy; + return MMAL_SUCCESS; + +fail: + mmal_vc_component_destroy(component); + return status; +} + +MMAL_CONSTRUCTOR(mmal_register_component_videocore); +void mmal_register_component_videocore(void) +{ + mmal_vc_shm_init(); + mmal_component_supplier_register(VIDEOCORE_PREFIX, mmal_vc_component_create); +} + diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/vc/mmal_vc_api.h b/external_src/raspicam-0.1.3/dependencies/mmal/vc/mmal_vc_api.h new file mode 100644 index 0000000..c80fb10 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/vc/mmal_vc_api.h @@ -0,0 +1,219 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 MMAL_VC_API_H +#define MMAL_VC_API_H + +/** @file + * + * Public API for MMAL VC client. Most functionality is exposed + * via MMAL itself. + */ + +#include "interface/mmal/mmal_types.h" +#include "interface/mmal/mmal_parameters.h" +#include "interface/mmal/mmal_port.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** State of components created by the VC adaptation layer, used for + * statistics reporting. + */ +typedef enum { + MMAL_STATS_COMP_IDLE, + MMAL_STATS_COMP_CREATED, + MMAL_STATS_COMP_DESTROYING, + MMAL_STATS_COMP_DESTROYED, + MMAL_STATS_COMP_UNUSED = 0xffffffff /* force 32bit */ +} MMAL_STATS_COMP_STATE_T; + +/** Per-component statistics collected by the VC adaptation layer. + */ +struct MMAL_VC_COMP_STATS_T { + struct MMAL_DRIVER_COMPONENT_T *comp; + MMAL_STATS_COMP_STATE_T state; + uint32_t pid; + uint32_t pool_mem_alloc_size; + char name[20]; +}; + +/** VC adaptation layer statistics. + */ +struct MMAL_VC_STATS_T +{ + struct + { + uint32_t rx; /**< Count of data buffers received */ + uint32_t rx_zero_copy; /**< Count of zero-copy data buffers received */ + uint32_t rx_empty; /**< Empty data buffers (to be filled) */ + uint32_t rx_fails; /**< Gave up partway through */ + uint32_t tx; /**< Count of data buffers sent */ + uint32_t tx_zero_copy; /**< Count of zero-copy data buffers sent */ + uint32_t tx_empty; /**< Count of empty data buffers sent */ + uint32_t tx_fails; /**< Gave up partway through */ + uint32_t tx_short_msg; /**< Messages sent directly in the control message */ + uint32_t rx_short_msg; /**< Messages received directly in the control message */ + } buffers; + struct service + { + uint32_t created; /**< How many services created */ + uint32_t pending_destroy; /**< How many destroyed */ + uint32_t destroyed; /**< How many destroyed */ + uint32_t failures; /**< Failures to create a service */ + } service; + struct commands + { + uint32_t bad_messages; + uint32_t executed; + uint32_t failed; + uint32_t replies; + uint32_t reply_fails; + } commands; + struct + { + uint32_t tx; /**< Count of events sent */ + uint32_t tx_fails; /**< Count of events not fully sent */ + } events; + struct + { + uint32_t created; + uint32_t destroyed; + uint32_t destroying; + uint32_t failed; + uint32_t list_size; + struct MMAL_VC_COMP_STATS_T component_list[8]; + } components; + struct + { + uint32_t enqueued_messages; + uint32_t dequeued_messages; + uint32_t max_parameter_set_delay; + uint32_t max_messages_waiting; + } worker; + +}; +typedef struct MMAL_VC_STATS_T MMAL_VC_STATS_T; + +/* Simple circular text buffer used to store 'interesting' data + * from MMAL clients. e.g. settings for each picture taken */ +struct MMAL_VC_HOST_LOG_T +{ + /** Simple circular buffer of plain text log messages separated by NUL */ + char buffer[16 << 10]; + /** For VCDBG validation and to help detect buffer overflow */ + uint32_t magic; + /** Write offset into buffer */ + int32_t offset; + /** Counter of host messages logged since boot */ + unsigned count; +}; +typedef struct MMAL_VC_HOST_LOG_T MMAL_VC_HOST_LOG_T; + +/** Status from querying MMAL core statistics. + */ +typedef enum +{ + MMAL_STATS_FOUND, + MMAL_STATS_COMPONENT_NOT_FOUND, + MMAL_STATS_PORT_NOT_FOUND, + MMAL_STATS_INVALID = 0x7fffffff +} MMAL_STATS_RESULT_T; + +MMAL_STATUS_T mmal_vc_init(void); +void mmal_vc_deinit(void); + +MMAL_STATUS_T mmal_vc_use(void); +MMAL_STATUS_T mmal_vc_release(void); + +MMAL_STATUS_T mmal_vc_get_version(uint32_t *major, uint32_t *minor, uint32_t *minimum); +MMAL_STATUS_T mmal_vc_get_stats(MMAL_VC_STATS_T *stats, int reset); + +/** Return the MMAL core statistics for a given component/port. + * + * @param stats Updated with given port statistics + * @param result Whether the port/component was found + * @param name Filled in with the name of the port + * @param namelen Length of name + * @param component Which component (indexed from zero) + * @param port_type Which type of port + * @param port Which port (index from zero) + * @param reset Reset the stats. + */ +MMAL_STATUS_T mmal_vc_get_core_stats(MMAL_CORE_STATISTICS_T *stats, + MMAL_STATS_RESULT_T *result, + char *name, + size_t namelen, + MMAL_PORT_TYPE_T type, + unsigned component, + unsigned port, + MMAL_CORE_STATS_DIR dir, + MMAL_BOOL_T reset); +/** + * Stores an arbitrary text message in a circular buffer inside the MMAL VC server. + * The purpose of this message is to log high level events from the host in order + * to diagnose problems that require multiple actions to reproduce. e.g. taking + * multiple pictures with different settings. + * + * @param msg The message text. + * @return MMAL_SUCCESS if the message was logged or MMAL_ENOSYS if the API + * if not supported. + */ +MMAL_STATUS_T mmal_vc_host_log(const char *msg); + +/* For backwards compatibility in builds */ +#define MMAL_VC_API_HAVE_HOST_LOG + +/* VC DEBUG ONLY ************************************************************/ +/** Consumes memory in the relocatable heap. + * + * The existing reserved memory is freed first then the new chunk is allocated. + * If zero is specified for the size then the previously reserved memory + * is freed and no allocation occurs. + * + * At startup no memory is reserved. + * + * @param size Size of memory to consume in bytes. + * @param handle Set to the mem handle for the reserved memory or zero + * if no memory was allocated. + * @return MMAL_SUCCESS if memory was reserved (or size zero requested), + * MMAL_ENOSPC if the allocation failed or MMAL_ENOSYS if the + * API is not supported e.g in release mode VC images. + * @internal + */ +MMAL_STATUS_T mmal_vc_consume_mem(size_t size, uint32_t *handle); + +/** Trigger LMK action from VC, for diagnostics. + * @internal + */ +MMAL_STATUS_T mmal_vc_lmk(uint32_t alloc_size); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/vc/mmal_vc_api_drm.c b/external_src/raspicam-0.1.3/dependencies/mmal/vc/mmal_vc_api_drm.c new file mode 100644 index 0000000..a926a86 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/vc/mmal_vc_api_drm.c @@ -0,0 +1,77 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 "mmal_vc_api_drm.h" +#include "mmal_vc_api.h" +#include "interface/mmal/mmal_logging.h" +#include "interface/mmal/mmal.h" +#include "mmal_vc_api.h" +#include "mmal_vc_msgs.h" +#include "mmal_vc_client_priv.h" +#include "mmal_vc_opaque_alloc.h" +#include "mmal_vc_shm.h" +#include "interface/mmal/util/mmal_util.h" +#include "interface/mmal/core/mmal_component_private.h" +#include "interface/mmal/core/mmal_port_private.h" +#include "interface/mmal/core/mmal_buffer_private.h" +#include "interface/vcos/vcos.h" + + +int mmal_vc_drm_get_time(unsigned int * time) +{ + MMAL_STATUS_T status; + mmal_worker_msg_header req; + mmal_worker_drm_get_time_reply reply; + size_t len = sizeof(reply); + status = mmal_vc_init(); + if (status != MMAL_SUCCESS) return status; + status = mmal_vc_sendwait_message(mmal_vc_get_client(), + &req, sizeof(req), + MMAL_WORKER_DRM_GET_TIME, + &reply, &len, MMAL_FALSE); + *time = reply.time; + mmal_vc_deinit(); + return status; +} + + +int mmal_vc_drm_get_lhs32(unsigned char * into) +{ + MMAL_STATUS_T status; + mmal_worker_msg_header req; + mmal_worker_drm_get_lhs32_reply reply; + size_t len = sizeof(reply); + status = mmal_vc_init(); + if (status != MMAL_SUCCESS) return status; + + status = mmal_vc_sendwait_message(mmal_vc_get_client(), + &req, sizeof(req), + MMAL_WORKER_DRM_GET_LHS32, + &reply, &len, MMAL_FALSE); + memcpy(into, reply.secret, 32); + mmal_vc_deinit(); + return status; +} diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/vc/mmal_vc_api_drm.h b/external_src/raspicam-0.1.3/dependencies/mmal/vc/mmal_vc_api_drm.h new file mode 100644 index 0000000..04688b6 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/vc/mmal_vc_api_drm.h @@ -0,0 +1,55 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 MMAL_VC_API_DRM_H +#define MMAL_VC_API_DRM_H + +/** @file + * + * Public API for MMAL VC client. (Divx DRM part) + */ + + +#ifdef __cplusplus +extern "C" { +#endif + +// Reads the current clock (in microseconds) into the "time" variable. +// Returns zero on success, nonszero on failure +int mmal_vc_drm_get_time(unsigned int * time); + +// Reads the local hardware secret into the "into" variable (needs to be 32 bytes of space for this) +// Returns 0 on success, nonzero on failure +// Usage: +// unsigned char buffer[32]; +// success = mmal_vc_divx_drm_get_lhs(buffer); +int mmal_vc_drm_get_lhs32(unsigned char * into); + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/vc/mmal_vc_client.c b/external_src/raspicam-0.1.3/dependencies/mmal/vc/mmal_vc_client.c new file mode 100644 index 0000000..b60544b --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/vc/mmal_vc_client.c @@ -0,0 +1,822 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 "mmal.h" +#include "mmal_vc_msgs.h" +#include "mmal_vc_api.h" +#include "mmal_vc_client_priv.h" +#include "interface/vcos/vcos.h" +#include "vchiq_util.h" +#include "interface/mmal/core/mmal_buffer_private.h" +#include "interface/mmal/core/mmal_component_private.h" +#include "interface/mmal/core/mmal_port_private.h" +#include "interface/mmal/util/mmal_list.h" +#include "interface/mmal/util/mmal_util.h" + +#define VCOS_LOG_CATEGORY (&mmal_ipc_log_category) +#include "interface/mmal/mmal_logging.h" + +#include + +#define MAX_WAITERS 16 +static VCOS_ONCE_T once = VCOS_ONCE_INIT; +static VCHIQ_INSTANCE_T mmal_vchiq_instance; +static VCOS_LOG_CAT_T mmal_ipc_log_category; + +/** Client threads use one of these to wait for + * a reply from VideoCore. + */ +typedef struct MMAL_WAITER_T +{ + VCOS_SEMAPHORE_T sem; + unsigned inuse; + void *dest; /**< Where to write reply */ + size_t destlen; /**< Max length for reply */ +} MMAL_WAITER_T; + +/** We have an array of waiters and allocate them to waiting + * threads. They can be released back to the pool in any order. + * If there are none free, the calling thread will block until + * one becomes available. + */ +typedef struct +{ + MMAL_WAITER_T waiters[MAX_WAITERS]; + VCOS_SEMAPHORE_T sem; +} MMAL_WAITPOOL_T; + +struct MMAL_CLIENT_T +{ + int refcount; + int usecount; + VCOS_MUTEX_T lock; + VCHIQ_SERVICE_HANDLE_T service; + MMAL_WAITPOOL_T waitpool; + VCOS_MUTEX_T bulk_lock; + + MMAL_BOOL_T inited; +}; + +/* One client per process/VC connection. Multiple threads may + * be using a single client. + */ +static MMAL_CLIENT_T client; + +static void init_once(void) +{ + vcos_mutex_create(&client.lock, VCOS_FUNCTION); +} + +/** Create a pool of wait-structures. + */ +static MMAL_STATUS_T create_waitpool(MMAL_WAITPOOL_T *waitpool) +{ + MMAL_STATUS_T status; + int i; + + status = vcos_semaphore_create(&waitpool->sem, VCOS_FUNCTION, + MAX_WAITERS); + if (status != MMAL_SUCCESS) + return status; + + for (i=0; iwaiters[i].inuse = 0; + status = vcos_semaphore_create(&waitpool->waiters[i].sem, + "mmal waiter", 0); + if (status != MMAL_SUCCESS) + break; + } + + if (status != MMAL_SUCCESS) + { + /* clean up */ + i--; + while (i>=0) + { + vcos_semaphore_delete(&waitpool->waiters[i].sem); + i--; + } + vcos_semaphore_delete(&waitpool->sem); + } + return status; +} + +static void destroy_waitpool(MMAL_WAITPOOL_T *waitpool) +{ + int i; + for (i=0; iwaiters[i].sem); + + vcos_semaphore_delete(&waitpool->sem); +} + +/** Grab a waiter from the pool. Return immediately if one already + * available, or wait for one to become available. + */ +static MMAL_WAITER_T *get_waiter(MMAL_CLIENT_T *client) +{ + int i; + MMAL_WAITER_T *waiter = NULL; + vcos_semaphore_wait(&client->waitpool.sem); + vcos_mutex_lock(&client->lock); + for (i=0; iwaitpool.waiters[i].inuse == 0) + break; + } + /* If this fails, the semaphore is not working */ + if (vcos_verify(i != MAX_WAITERS)) + { + waiter = client->waitpool.waiters+i; + waiter->inuse = 1; + } + vcos_mutex_unlock(&client->lock); + + return waiter; +} + +/** Return a waiter to the pool. + */ +static void release_waiter(MMAL_CLIENT_T *client, MMAL_WAITER_T *waiter) +{ + LOG_TRACE("at %p", waiter); + vcos_assert(waiter); + vcos_assert(waiter->inuse); + waiter->inuse = 0; + vcos_semaphore_post(&client->waitpool.sem); +} + +static MMAL_PORT_T *mmal_vc_port_by_number(MMAL_COMPONENT_T *component, uint32_t type, uint32_t number) +{ + switch (type) + { + case MMAL_PORT_TYPE_CONTROL: + vcos_assert(number == 0); + return component->control; + case MMAL_PORT_TYPE_INPUT: + vcos_assert(number < component->input_num); + return component->input[number]; + case MMAL_PORT_TYPE_OUTPUT: + vcos_assert(number < component->output_num); + return component->output[number]; + case MMAL_PORT_TYPE_CLOCK: + vcos_assert(number < component->clock_num); + return component->clock[number]; + } + + return NULL; +} + +static void mmal_vc_handle_event_msg(VCHIQ_HEADER_T *vchiq_header, + VCHIQ_SERVICE_HANDLE_T service, + void *context) +{ + mmal_worker_event_to_host *msg = (mmal_worker_event_to_host *)vchiq_header->data; + MMAL_COMPONENT_T *component = msg->client_component; + MMAL_BUFFER_HEADER_T *buffer; + MMAL_STATUS_T status; + MMAL_PORT_T *port; + + LOG_DEBUG("event to host, cmd 0x%08x len %d to component %p port (%d,%d)", + msg->cmd, msg->length, msg->client_component, msg->port_type, msg->port_num); + (void)context; + + port = mmal_vc_port_by_number(component, msg->port_type, msg->port_num); + if (!vcos_verify(port)) + { + LOG_ERROR("port (%i,%i) doesn't exist", (int)msg->port_type, (int)msg->port_num); + goto error; + } + + status = mmal_port_event_get(port, &buffer, msg->cmd); + if (status != MMAL_SUCCESS) + { + LOG_ERROR("no event buffer available to receive event (%i)", (int)status); + goto error; + } + + if (!vcos_verify(msg->length <= buffer->alloc_size)) + { + LOG_ERROR("event buffer to small to receive event (%i/%i)", + (int)buffer->alloc_size, (int)msg->length); + goto error; + } + buffer->length = msg->length; + + /* Sanity check that the event buffers have the proper vc client context */ + if (!vcos_verify(mmal_buffer_header_driver_data(buffer)->magic == MMAL_MAGIC && + mmal_buffer_header_driver_data(buffer)->client_context && + mmal_buffer_header_driver_data(buffer)->client_context->magic == MMAL_MAGIC && + mmal_buffer_header_driver_data(buffer)->client_context->callback_event)) + { + LOG_ERROR("event buffers not configured properly by component"); + goto error; + } + + if (buffer->length > MMAL_WORKER_EVENT_SPACE) + { + /* a buffer full of data for us to process */ + int len = buffer->length; + len = (len+3) & (~3); + LOG_DEBUG("queue event bulk rx: %p, %d", buffer->data, buffer->length); + msg->delayed_buffer = buffer; + + VCHIQ_STATUS_T vst = vchiq_queue_bulk_receive(service, buffer->data, len, vchiq_header); + if (vst != VCHIQ_SUCCESS) + { + LOG_TRACE("queue event bulk rx len %d failed to start", buffer->length); + mmal_buffer_header_release(buffer); + goto error; + } + } + else + { + if (msg->length) + memcpy(buffer->data, msg->data, msg->length); + + mmal_buffer_header_driver_data(buffer)->client_context->callback_event(port, buffer); + LOG_DEBUG("done callback back to client"); + vchiq_release_message(service, vchiq_header); + } + + return; + +error: + /* FIXME: How to abort bulk receive if necessary? */ + msg->length = 0; /* FIXME: set a buffer flag to signal error */ + vchiq_release_message(service, vchiq_header); +} + +static MMAL_STATUS_T mmal_vc_use_internal(MMAL_CLIENT_T *client) +{ + MMAL_STATUS_T status = MMAL_SUCCESS; + vcos_mutex_lock(&client->lock); + if(client->usecount++ == 0) + { + if(vchiq_use_service(client->service) != VCHIQ_SUCCESS) + { + client->usecount--; + status = MMAL_EIO; + } + } + vcos_mutex_unlock(&client->lock); + return status; +} + +static MMAL_STATUS_T mmal_vc_release_internal(MMAL_CLIENT_T *client) +{ + MMAL_STATUS_T status = MMAL_SUCCESS; + vcos_mutex_lock(&client->lock); + if(--client->usecount == 0) + { + if(vchiq_release_service(client->service) != VCHIQ_SUCCESS) + { + client->usecount++; + status = MMAL_EIO; + } + } + vcos_mutex_unlock(&client->lock); + return status; +} + + +/** Callback invoked by VCHIQ + */ +static VCHIQ_STATUS_T mmal_vc_vchiq_callback(VCHIQ_REASON_T reason, + VCHIQ_HEADER_T *vchiq_header, + VCHIQ_SERVICE_HANDLE_T service, + void *context) +{ + LOG_TRACE("reason %d", reason); + + switch (reason) + { + case VCHIQ_MESSAGE_AVAILABLE: + { + mmal_worker_msg_header *msg = (mmal_worker_msg_header*)vchiq_header->data; + vcos_assert(msg->magic == MMAL_MAGIC); + + if (msg->msgid == MMAL_WORKER_BUFFER_TO_HOST) + { + LOG_TRACE("buffer to host"); + mmal_worker_buffer_from_host *msg = (mmal_worker_buffer_from_host *)vchiq_header->data; + LOG_TRACE("len %d context %p", msg->buffer_header.length, msg->drvbuf.client_context); + vcos_assert(msg->drvbuf.client_context); + vcos_assert(msg->drvbuf.client_context->magic == MMAL_MAGIC); + + /* If the buffer is referencing another, need to replicate it here + * in order to use the reference buffer's payload and ensure the + * reference is not released prematurely */ + if (msg->has_reference) + mmal_buffer_header_replicate(msg->drvbuf.client_context->buffer, + msg->drvbuf_ref.client_context->buffer); + + /* Sanity check the size of the transfer so we don't overrun our buffer */ + if (!vcos_verify(msg->buffer_header.offset + msg->buffer_header.length <= + msg->drvbuf.client_context->buffer->alloc_size)) + { + LOG_TRACE("buffer too small (%i, %i)", + msg->buffer_header.offset + msg->buffer_header.length, + msg->drvbuf.client_context->buffer->alloc_size); + msg->buffer_header.length = 0; /* FIXME: set a buffer flag to signal error */ + msg->drvbuf.client_context->callback(msg); + vchiq_release_message(service, vchiq_header); + break; + } + /*To handle VC to HOST filled buffer callback of EOS buffer to receive in sync with data buffers*/ + if (!msg->is_zero_copy && + (msg->buffer_header.length != 0 || + (msg->buffer_header.flags & MMAL_BUFFER_HEADER_FLAG_EOS))) + { + /* a buffer full of data for us to process */ + VCHIQ_STATUS_T vst = VCHIQ_SUCCESS; + LOG_TRACE("queue bulk rx: %p, %d", msg->drvbuf.client_context->buffer->data + + msg->buffer_header.offset, msg->buffer_header.length); + int len = msg->buffer_header.length; + len = (len+3) & (~3); + + if (!len && (msg->buffer_header.flags & MMAL_BUFFER_HEADER_FLAG_EOS)) + { + len = 8; + } + if (!msg->payload_in_message) + { + /* buffer transferred using vchiq bulk xfer */ + vst = vchiq_queue_bulk_receive(service, + msg->drvbuf.client_context->buffer->data + msg->buffer_header.offset, + len, vchiq_header); + + if (vst != VCHIQ_SUCCESS) + { + LOG_TRACE("queue bulk rx len %d failed to start", msg->buffer_header.length); + msg->buffer_header.length = 0; /* FIXME: set a buffer flag to signal error */ + msg->drvbuf.client_context->callback(msg); + vchiq_release_message(service, vchiq_header); + } + } + else if (msg->payload_in_message <= MMAL_VC_SHORT_DATA) + { + /* we have already received the buffer data in the message! */ + MMAL_BUFFER_HEADER_T *dst = msg->drvbuf.client_context->buffer; + LOG_TRACE("short data: dst = %p, dst->data = %p, len %d short len %d", dst, dst? dst->data : 0, msg->buffer_header.length, msg->payload_in_message); + memcpy(dst->data, msg->short_data, msg->payload_in_message); + dst->offset = 0; + dst->length = msg->payload_in_message; + vchiq_release_message(service, vchiq_header); + msg->drvbuf.client_context->callback(msg); + } + else + { + /* impossible short data length */ + LOG_ERROR("Message with invalid short payload length %d", + msg->payload_in_message); + vcos_assert(0); + } + } + else + { + + /* Message received from videocore; the client_context should have + * been passed all the way through by videocore back to us, and will + * be picked up in the callback to complete the sequence. + */ + LOG_TRACE("doing cb (%p) context %p", + msg->drvbuf.client_context, msg->drvbuf.client_context ? + msg->drvbuf.client_context->callback : 0); + msg->drvbuf.client_context->callback(msg); + LOG_TRACE("done callback back to client"); + vchiq_release_message(service, vchiq_header); + } + } + else if (msg->msgid == MMAL_WORKER_EVENT_TO_HOST) + { + mmal_vc_handle_event_msg(vchiq_header, service, context); + } + else + { + MMAL_WAITER_T *waiter = msg->u.waiter; + LOG_TRACE("waking up waiter at %p", waiter); + vcos_assert(waiter->inuse); + int len = vcos_min(waiter->destlen, vchiq_header->size); + waiter->destlen = len; + LOG_TRACE("copying payload @%p to %p len %d", waiter->dest, msg, len); + memcpy(waiter->dest, msg, len); + vchiq_release_message(service, vchiq_header); + vcos_semaphore_post(&waiter->sem); + } + } + break; + case VCHIQ_BULK_TRANSMIT_DONE: + { + /* nothing to do here, need to wait for the copro to tell us it + * has emptied the buffer before we can recycle it, otherwise we + * end up feeding the copro with buffers it cannot handle. + */ +#ifdef VCOS_LOGGING_ENABLED + mmal_worker_buffer_from_host *msg = (mmal_worker_buffer_from_host *)context; +#endif + LOG_TRACE("bulk tx done: %p, %d", msg->buffer_header.data, msg->buffer_header.length); + } + break; + case VCHIQ_BULK_RECEIVE_DONE: + { + VCHIQ_HEADER_T *header = (VCHIQ_HEADER_T *)context; + mmal_worker_msg_header *msg_hdr = (mmal_worker_msg_header*)header->data; + if (msg_hdr->msgid == MMAL_WORKER_BUFFER_TO_HOST) + { + mmal_worker_buffer_from_host *msg = (mmal_worker_buffer_from_host *)msg_hdr; + vcos_assert(msg->drvbuf.client_context->magic == MMAL_MAGIC); + msg->drvbuf.client_context->callback(msg); + LOG_TRACE("bulk rx done: %p, %d", msg->buffer_header.data, msg->buffer_header.length); + } + else + { + mmal_worker_event_to_host *msg = (mmal_worker_event_to_host *)msg_hdr; + MMAL_PORT_T *port = mmal_vc_port_by_number(msg->client_component, msg->port_type, msg->port_num); + + vcos_assert(port); + mmal_buffer_header_driver_data(msg->delayed_buffer)-> + client_context->callback_event(port, msg->delayed_buffer); + LOG_DEBUG("event bulk rx done, length %d", msg->length); + } + vchiq_release_message(service, header); + } + break; + case VCHIQ_BULK_RECEIVE_ABORTED: + { + VCHIQ_HEADER_T *header = (VCHIQ_HEADER_T *)context; + mmal_worker_msg_header *msg_hdr = (mmal_worker_msg_header*)header->data; + if (msg_hdr->msgid == MMAL_WORKER_BUFFER_TO_HOST) + { + mmal_worker_buffer_from_host *msg = (mmal_worker_buffer_from_host *)msg_hdr; + LOG_TRACE("bulk rx aborted: %p, %d", msg->buffer_header.data, msg->buffer_header.length); + vcos_assert(msg->drvbuf.client_context->magic == MMAL_MAGIC); + msg->buffer_header.flags |= MMAL_BUFFER_HEADER_FLAG_TRANSMISSION_FAILED; + msg->drvbuf.client_context->callback(msg); + } + else + { + mmal_worker_event_to_host *msg = (mmal_worker_event_to_host *)msg_hdr; + MMAL_PORT_T *port = mmal_vc_port_by_number(msg->client_component, msg->port_type, msg->port_num); + + vcos_assert(port); + LOG_DEBUG("event bulk rx aborted"); + msg->delayed_buffer->flags |= MMAL_BUFFER_HEADER_FLAG_TRANSMISSION_FAILED; + mmal_buffer_header_driver_data(msg->delayed_buffer)-> + client_context->callback_event(port, msg->delayed_buffer); + } + vchiq_release_message(service, header); + } + break; + case VCHIQ_BULK_TRANSMIT_ABORTED: + { + mmal_worker_buffer_from_host *msg = (mmal_worker_buffer_from_host *)context; + LOG_INFO("bulk tx aborted: %p, %d", msg->buffer_header.data, msg->buffer_header.length); + vcos_assert(msg->drvbuf.client_context->magic == MMAL_MAGIC); + /* Nothing to do as the VC side will release the buffer and notify us of the error */ + } + break; + default: + break; + } + + return VCHIQ_SUCCESS; +} + +/** Send a message and wait for a reply. + * + * @param client client to send message for + * @param msg_header message vchiq_header to send + * @param size length of message, including header + * @param msgid message id + * @param dest destination for reply + * @param destlen size of destination, updated with actual length + * @param send_dummy_bulk whether to send a dummy bulk transfer + */ +MMAL_STATUS_T mmal_vc_sendwait_message(struct MMAL_CLIENT_T *client, + mmal_worker_msg_header *msg_header, + size_t size, + uint32_t msgid, + void *dest, + size_t *destlen, + MMAL_BOOL_T send_dummy_bulk) +{ + MMAL_STATUS_T ret; + MMAL_WAITER_T *waiter; + VCHIQ_STATUS_T vst; + VCHIQ_ELEMENT_T elems[] = {{msg_header, size}}; + + vcos_assert(size >= sizeof(mmal_worker_msg_header)); + vcos_assert(dest); + + if (!client->inited) + { + vcos_assert(0); + return MMAL_EINVAL; + } + + if (send_dummy_bulk) + vcos_mutex_lock(&client->bulk_lock); + + waiter = get_waiter(client); + msg_header->msgid = msgid; + msg_header->u.waiter = waiter; + msg_header->magic = MMAL_MAGIC; + + waiter->dest = dest; + waiter->destlen = *destlen; + LOG_TRACE("wait %p, reply to %p", waiter, dest); + mmal_vc_use_internal(client); + + vst = vchiq_queue_message(client->service, elems, 1); + + if (vst != VCHIQ_SUCCESS) + { + ret = MMAL_EIO; + if (send_dummy_bulk) + vcos_mutex_unlock(&client->bulk_lock); + goto fail_msg; + } + + if (send_dummy_bulk) + { + uint32_t data_size = 8; + /* The data is just some dummy bytes so it's fine for it to be static */ + static uint8_t data[8]; + vst = vchiq_queue_bulk_transmit(client->service, data, data_size, msg_header); + + vcos_mutex_unlock(&client->bulk_lock); + + if (!vcos_verify(vst == VCHIQ_SUCCESS)) + { + LOG_ERROR("failed bulk transmit"); + /* This really should not happen and if it does, things will go wrong as + * we've already queued the vchiq message above. */ + vcos_assert(0); + ret = MMAL_EIO; + goto fail_msg; + } + } + + /* now wait for the reply... + * + * FIXME: we could do with a timeout here. Need to be careful to cancel + * the semaphore on a timeout. + */ + /* coverity[lock] This semaphore isn't being used as a mutex */ + vcos_semaphore_wait(&waiter->sem); + + mmal_vc_release_internal(client); + LOG_TRACE("got reply (len %i/%i)", (int)*destlen, (int)waiter->destlen); + *destlen = waiter->destlen; + + release_waiter(client, waiter); + return MMAL_SUCCESS; + +fail_msg: + mmal_vc_release_internal(client); + + release_waiter(client, waiter); + return ret; +} + +/** Send a message and do not wait for a reply. + * + * @note + * This function should only be called from within a mmal component, so + * vchiq_use/release_service calls aren't required (dealt with at higher level). + * + * @param client client to send message for + * @param msg_header message header to send + * @param size length of message, including header + * @param msgid message id + */ +MMAL_STATUS_T mmal_vc_send_message(MMAL_CLIENT_T *client, + mmal_worker_msg_header *msg_header, size_t size, + uint8_t *data, size_t data_size, + uint32_t msgid) +{ + VCHIQ_STATUS_T vst; + VCHIQ_ELEMENT_T elems[] = {{msg_header, size}}; + MMAL_BOOL_T using_bulk_transfer = (data_size != 0); + + LOG_TRACE("len %d", data_size); + vcos_assert(size >= sizeof(mmal_worker_msg_header)); + + if (!client->inited) + { + vcos_assert(0); + return MMAL_EINVAL; + } + + if (using_bulk_transfer) + vcos_mutex_lock(&client->bulk_lock); + + msg_header->msgid = msgid; + msg_header->magic = MMAL_MAGIC; + + vst = vchiq_queue_message(client->service, elems, 1); + + if (vst != VCHIQ_SUCCESS) + { + if (using_bulk_transfer) + vcos_mutex_unlock(&client->bulk_lock); + + LOG_ERROR("failed"); + goto error; + } + + if (using_bulk_transfer) + { + LOG_TRACE("bulk transmit: %p, %i", data, data_size); + + data_size = (data_size + 3) & ~3; + vst = vchiq_queue_bulk_transmit(client->service, data, data_size, msg_header); + + vcos_mutex_unlock(&client->bulk_lock); + + if (!vcos_verify(vst == VCHIQ_SUCCESS)) + { + LOG_ERROR("failed bulk transmit"); + /* This really should not happen and if it does, things will go wrong as + * we've already queued the vchiq message above. */ + vcos_assert(0); + goto error; + } + } + + return MMAL_SUCCESS; + + error: + return MMAL_EIO; +} + +MMAL_STATUS_T mmal_vc_use(void) +{ + MMAL_STATUS_T status = MMAL_ENOTCONN; + if(client.inited) + status = mmal_vc_use_internal(&client); + return status; +} + +MMAL_STATUS_T mmal_vc_release(void) +{ + MMAL_STATUS_T status = MMAL_ENOTCONN; + if(client.inited) + status = mmal_vc_release_internal(&client); + return status; +} + +MMAL_STATUS_T mmal_vc_init(void) +{ + VCHIQ_SERVICE_PARAMS_T vchiq_params; + MMAL_BOOL_T vchiq_initialised = 0, waitpool_initialised = 0; + MMAL_BOOL_T service_initialised = 0; + MMAL_STATUS_T status = MMAL_EIO; + VCHIQ_STATUS_T vchiq_status; + int count; + + vcos_once(&once, init_once); + + vcos_mutex_lock(&client.lock); + + count = client.refcount++; + if (count > 0) + { + /* Already initialised so nothing to do */ + vcos_mutex_unlock(&client.lock); + return MMAL_SUCCESS; + } + + vcos_log_register("mmalipc", VCOS_LOG_CATEGORY); + + /* Initialise a VCHIQ instance */ + vchiq_status = vchiq_initialise(&mmal_vchiq_instance); + if (vchiq_status != VCHIQ_SUCCESS) + { + LOG_ERROR("failed to initialise vchiq"); + status = MMAL_EIO; + goto error; + } + vchiq_initialised = 1; + + vchiq_status = vchiq_connect(mmal_vchiq_instance); + if (vchiq_status != VCHIQ_SUCCESS) + { + LOG_ERROR("failed to connect to vchiq"); + status = MMAL_EIO; + goto error; + } + + memset(&vchiq_params,0,sizeof(vchiq_params)); + vchiq_params.fourcc = MMAL_CONTROL_FOURCC(); + vchiq_params.callback = mmal_vc_vchiq_callback; + vchiq_params.userdata = &client; + vchiq_params.version = WORKER_VER_MAJOR; + vchiq_params.version_min = WORKER_VER_MINIMUM; + + vchiq_status = vchiq_open_service(mmal_vchiq_instance, &vchiq_params, &client.service); + if (vchiq_status != VCHIQ_SUCCESS) + { + LOG_ERROR("could not open vchiq service"); + status = MMAL_EIO; + goto error; + } + client.usecount = 1; /* usecount set to 1 by the open call. */ + service_initialised = 1; + + status = create_waitpool(&client.waitpool); + if (status != MMAL_SUCCESS) + { + LOG_ERROR("could not create wait pool"); + goto error; + } + waitpool_initialised = 1; + + if (vcos_mutex_create(&client.bulk_lock, "mmal client bulk lock") != VCOS_SUCCESS) + { + LOG_ERROR("could not create bulk lock"); + status = MMAL_ENOSPC; + goto error; + } + + client.inited = 1; + + vcos_mutex_unlock(&client.lock); + /* assume we're not using VC immediately. Do this outside the lock */ + mmal_vc_release(); + + + return MMAL_SUCCESS; + + error: + if (waitpool_initialised) + destroy_waitpool(&client.waitpool); + if (service_initialised) + { + client.usecount = 0; + vchiq_close_service(client.service); + } + if (vchiq_initialised) + vchiq_shutdown(mmal_vchiq_instance); + vcos_log_unregister(VCOS_LOG_CATEGORY); + client.refcount--; + + vcos_mutex_unlock(&client.lock); + return status; +} + +void mmal_vc_deinit(void) +{ + int count; + + vcos_mutex_lock(&client.lock); + count = --client.refcount; + if (count != 0) + { + /* Still in use so don't do anything */ + vcos_mutex_unlock(&client.lock); + return; + } + + vcos_mutex_delete(&client.bulk_lock); + destroy_waitpool(&client.waitpool); + vchiq_close_service(client.service); + vchiq_shutdown(mmal_vchiq_instance); + vcos_log_unregister(VCOS_LOG_CATEGORY); + + client.service = VCHIQ_SERVICE_HANDLE_INVALID; + client.inited = 0; + vcos_mutex_unlock(&client.lock); +} + +MMAL_CLIENT_T *mmal_vc_get_client(void) +{ + return &client; +} diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/vc/mmal_vc_client_priv.h b/external_src/raspicam-0.1.3/dependencies/mmal/vc/mmal_vc_client_priv.h new file mode 100644 index 0000000..0fc3aaa --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/vc/mmal_vc_client_priv.h @@ -0,0 +1,80 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 MMAL_VC_CLIENT_H +#define MMAL_VC_CLIENT_H + +/** @file mmal_vc_client_priv.h + * + * Internal API for vchiq_arm MMAL client. + */ + +struct MMAL_CLIENT_T; +typedef struct MMAL_CLIENT_T MMAL_CLIENT_T; + +void mmal_vc_client_init(void); + +/** Hold the context required when sending a buffer to the copro. + */ +typedef struct MMAL_VC_CLIENT_BUFFER_CONTEXT_T +{ + uint32_t magic; + + /** Called when VC is done with the buffer */ + void (*callback)(struct mmal_worker_buffer_from_host *); + + /** Called when VC sends an event */ + void (*callback_event)(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *event); + + /** The port this buffer was sent to */ + MMAL_PORT_T *port; + + /** The original buffer from the host. */ + MMAL_BUFFER_HEADER_T *buffer; + + /** The actual message sent to the host */ + struct mmal_worker_buffer_from_host msg; +} MMAL_VC_CLIENT_BUFFER_CONTEXT_T; + + +MMAL_CLIENT_T *mmal_vc_get_client(void); + +MMAL_STATUS_T mmal_vc_sendwait_message(MMAL_CLIENT_T *client, + mmal_worker_msg_header *header, + size_t size, + uint32_t msgid, + void *dest, + size_t *destlen, + MMAL_BOOL_T send_dummy_bulk); + +MMAL_STATUS_T mmal_vc_send_message(MMAL_CLIENT_T *client, + mmal_worker_msg_header *header, size_t size, + uint8_t *data, size_t data_size, + uint32_t msgid); + +#endif + diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/vc/mmal_vc_dbglog.h b/external_src/raspicam-0.1.3/dependencies/mmal/vc/mmal_vc_dbglog.h new file mode 100644 index 0000000..0008bc4 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/vc/mmal_vc_dbglog.h @@ -0,0 +1,160 @@ +/* +Copyright (c) 2013, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. +*/ + +/** \file + * Multi-Media Abstraction Layer API + */ +#ifndef MMAL_VC_DBGLOG_H +#define MMAL_VC_DBGLOG_H + +#include "interface/mmal/mmal.h" +#include "mmal_vc_msgs.h" + +/* Debug log for MMAL messages going past */ + +typedef enum { + MMAL_DBG_MSG, + MMAL_DBG_BULK, + MMAL_DBG_OPENED, + MMAL_DBG_CLOSED, + MMAL_DBG_BULK_ACK, + MMAL_DBG_BULK_TX, + MMAL_DBG_BULK_RX, +} MMAL_DBG_EVENT_TYPE_T; + + +/** Debug log data. */ +typedef union +{ + struct { + mmal_worker_msg_header header; + uint32_t msg[4]; /**< Snarf this much message data */ + } msg; + + struct { + uint32_t len; /**< Length of transfer */ + uint32_t data[4]; /**< Snarf this much payload data */ + } bulk; + + uint32_t uint; + + uint32_t arr[15]; /** Pad complete DBG_ENTRY_T to 64 bytes per line */ + +} MMAL_DBG_DATA_T; + +/** One entry in the debug log */ +typedef struct +{ + uint32_t time; + uint32_t event_type; + MMAL_DBG_DATA_T u; +} MMAL_DBG_ENTRY_T; + +#define MMAL_DBG_ENTRIES_MAX 64 +#define MMAL_DBG_ENTRIES_MASK (MMAL_DBG_ENTRIES_MAX-1) +#define MMAL_DBG_VERSION 1 + +/** The debug log itself. This is currently allocated in uncached + * memory so that the ARM can easily access it. + */ +typedef struct +{ + uint32_t version; + uint32_t magic; + uint32_t num_entries; + uint32_t index; + uint32_t size; + uint32_t elemsize; + uint32_t pad[2]; + MMAL_DBG_ENTRY_T entries[MMAL_DBG_ENTRIES_MAX]; + +} MMAL_DBG_LOG_T; + +extern VCOS_MUTEX_T mmal_dbg_lock; +extern MMAL_DBG_LOG_T *mmal_dbg_log; + +/** Get the next event and hold the lock. Should only be + * accessed by the macros below. + */ +static inline MMAL_DBG_ENTRY_T *mmal_log_lock_event(MMAL_DBG_EVENT_TYPE_T event_type ) { + uint32_t index; + MMAL_DBG_ENTRY_T *entry; + vcos_mutex_lock(&mmal_dbg_lock); + index = mmal_dbg_log->index++; + entry = mmal_dbg_log->entries + (index & MMAL_DBG_ENTRIES_MASK); + entry->time = vcos_getmicrosecs(); + entry->event_type = event_type; + return entry; +} + +/** Release the lock. Should only be accessed by the macros below. */ +static inline void mmal_log_unlock_event(void) { + vcos_mutex_unlock(&mmal_dbg_lock); +} + +/** Initialise the logging module. */ +MMAL_STATUS_T mmal_vc_dbglog_init(void); + +/** Deinitialise the logging module. */ +void mmal_vc_dbglog_deinit(void); + +/** Put an entry into the log. + * + * @param short_type type of event, e.g. OPENED + * @param name union entry name, e.g. uint. + * @param event event data + */ +#define MMAL_LOG_EVENT(short_type, name, value) {\ + MMAL_DBG_ENTRY_T *entry = mmal_log_lock_event(MMAL_DBG_##short_type); \ + entry->u.name = value;\ + mmal_log_unlock_event(); \ +} + +/** Log an uint event (i.e. all just the fact that it occurred */ +#define LOG_EVENT_UINT(short_type,u) MMAL_LOG_EVENT(short_type, uint, u) + +#define LOG_EVENT_OPENED() LOG_EVENT_UINT(OPENED,0) +#define LOG_EVENT_CLOSED() LOG_EVENT_UINT(CLOSED,0) +#define LOG_EVENT_BULK_ACK(reason) LOG_EVENT_UINT(BULK_ACK,reason) + +/** Log a message. Grabs part of the message data. + */ +#define LOG_EVENT_MSG(header) {\ + MMAL_DBG_ENTRY_T *entry = mmal_log_lock_event(MMAL_DBG_MSG); \ + memcpy(&entry->u.msg, header, sizeof(entry->u.msg)); \ + mmal_log_unlock_event(); \ +} + +/** Log bulk data. For now, do not grab the actual data itself */ +#define LOG_EVENT_BULK(type, len, data) {\ + MMAL_DBG_ENTRY_T *entry = mmal_log_lock_event(MMAL_DBG_BULK_##type); \ + entry->u.bulk.len = len; \ + mmal_log_unlock_event(); \ +} + + +#endif diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/vc/mmal_vc_diag.c b/external_src/raspicam-0.1.3/dependencies/mmal/vc/mmal_vc_diag.c new file mode 100644 index 0000000..df39199 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/vc/mmal_vc_diag.c @@ -0,0 +1,843 @@ +/* +Copyright (c) 2013, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 "interface/mmal/mmal.h" +#include "interface/mmal/util/mmal_util.h" +#include "mmal_vc_api.h" +#include +#include +#include +#include +#ifdef __ANDROID__ +#include +#endif +#include "host_applications/linux/libs/debug_sym/debug_sym.h" +#include "mmal_vc_msgnames.h" +#include "mmal_vc_dbglog.h" +#include "vchiq.h" +#include "interface/vmcs_host/vc_imageconv_defs.h" + +/** Command-line diagnostics at the VC MMAL API level. + * + * @fixme: how does this work with multiple videocores? + */ + +struct cmd { + const char *name; + int (*pfn)(int argc, const char **argv); + const char *descr; + int flags; +}; + +#define CONNECT 1 + +static int do_commands(int argc, const char **argv); +static int do_version(int argc, const char **argv); +static int do_stats(int argc, const char **argv); +static int do_usage(int argc, const char **argv); +static int do_create(int argc, const char **argv); +static int do_eventlog(int argc, const char **argv); +static int do_components(int argc, const char **argv); +static int do_mmal_stats(int argc, const char **argv); +static int do_imageconv_stats(int argc, const char **argv); +static int do_autosusptest(int argc, const char **argv); +static int do_camerainfo(int argc, const char **argv); +static int do_host_log(int argc, const char **argv); +static int do_host_log_write(int argc, const char **argv); + +static struct cmd cmds[] = { + { "help", do_usage, "give this help", 0 }, + { "version", do_version, "report VC MMAL server version number", CONNECT }, + { "stats", do_stats, "report VC MMAL statistics", CONNECT }, + { "reset", do_stats, "reset VC MMAL statistics", CONNECT }, + { "commands", do_commands, "list available commands", CONNECT }, + { "create", do_create, "create a component", CONNECT }, + { "eventlog", do_eventlog, "display event log", 0 }, + { "components", do_components, "[update] list components", 0 }, + { "mmal-stats", do_mmal_stats, "list mmal core stats", CONNECT }, + { "ic-stats", do_imageconv_stats, "[reset] list imageconv stats", CONNECT }, + { "autosusp", do_autosusptest, "test out auto-suspend/resume", CONNECT }, + { "camerainfo", do_camerainfo, "get camera info", CONNECT }, + { "host_log", do_host_log, "dumps the MMAL VC log", CONNECT }, + { "host_log_write", do_host_log_write, "appends a message to the MMAL VC log of host messages", CONNECT }, + { NULL, NULL, NULL, 0}, +}; + +static void do_connect(void) +{ + /* this command needs a vchiq connection */ + MMAL_STATUS_T st; + if ((st = mmal_vc_init()) != MMAL_SUCCESS) + { + fprintf(stderr, "failed to initialize mmal vc library (%i:%s)\n", + st, mmal_status_to_string(st)); + exit(1); + } +} + +int main(int argc, const char **argv) +{ + int i; + + if (argc < 2) + { + do_usage(argc, argv); + exit(1); + } + + for (i = 0; cmds[i].name; i++) + { + if (strcasecmp(cmds[i].name, argv[1]) == 0) + { + int rc; + if (cmds[i].flags & CONNECT) + { + do_connect(); + } + rc = cmds[i].pfn(argc, argv); + + if (cmds[i].flags & CONNECT) + mmal_vc_deinit(); + return rc; + } + } + fprintf(stderr,"unknown command %s\n", argv[1]); + return -1; +} + +static int do_commands(int argc, const char **argv) +{ + int i = 0; + (void)argc; (void)argv; + while (cmds[i].name) + { + printf("%-20s %s\n", cmds[i].name, cmds[i].descr); + i++; + } + return 0; +} + +static int do_create(int argc, const char **argv) +{ + MMAL_COMPONENT_T *comp; + MMAL_STATUS_T st; + if (argc != 3) + { + printf("usage: mmal-vc-diag create \n"); + printf(" e.g. vc.camera\n"); + exit(1); + } + st = mmal_component_create(argv[2], &comp); + if (comp) + printf("Created component\n"); + else + printf("Failed to create %s: %d\n", argv[2], st); + + return 0; +} + +static int do_version(int argc, const char **argv) +{ + uint32_t maj = UINT_MAX, min = UINT_MAX, minimum; + MMAL_STATUS_T st = mmal_vc_get_version(&maj, &min, &minimum); + (void)argc; (void)argv; + if (st == MMAL_SUCCESS) + { + printf("version %d.%02d (min %d)\n", maj, min, minimum); + return 0; + } + else + { + fprintf(stderr, "error getting version (%i:%s)\n", st, mmal_status_to_string(st)); + return -1; + } +} + +#define STATS_FIELD(x) { #x, offsetof(MMAL_VC_STATS_T, x) } + +static struct { + const char *name; + unsigned offset; +} stats_fields [] = { + STATS_FIELD(buffers.rx), + STATS_FIELD(buffers.rx_zero_copy), + STATS_FIELD(buffers.rx_empty), + STATS_FIELD(buffers.rx_fails), + STATS_FIELD(buffers.tx), + STATS_FIELD(buffers.tx_zero_copy), + STATS_FIELD(buffers.tx_empty), + STATS_FIELD(buffers.tx_fails), + STATS_FIELD(buffers.tx_short_msg), + STATS_FIELD(buffers.rx_short_msg), + STATS_FIELD(service.created), + STATS_FIELD(service.pending_destroy), + STATS_FIELD(service.destroyed), + STATS_FIELD(service.failures), + STATS_FIELD(commands.bad_messages), + STATS_FIELD(commands.executed), + STATS_FIELD(commands.failed), + STATS_FIELD(commands.replies), + STATS_FIELD(commands.reply_fails), + STATS_FIELD(events.tx), + STATS_FIELD(events.tx_fails), + STATS_FIELD(worker.enqueued_messages), + STATS_FIELD(worker.dequeued_messages), + STATS_FIELD(worker.max_parameter_set_delay), + STATS_FIELD(worker.max_messages_waiting) +}; + +static int do_stats(int argc, const char **argv) +{ + MMAL_VC_STATS_T stats; + int reset_stats = strcasecmp(argv[1], "reset") == 0; + MMAL_STATUS_T st = mmal_vc_get_stats(&stats, reset_stats); + int ret; + (void)argc; (void)argv; + if (st != MMAL_SUCCESS) + { + fprintf(stderr, "error getting status (%i,%s)\n", st, mmal_status_to_string(st)); + ret = -1; + } + else + { + unsigned i; + uint32_t *ptr = (uint32_t*)&stats; + for (i=0; ievent_type) { + case MMAL_DBG_OPENED: snprintf(buf,buflen,"opened"); break; + case MMAL_DBG_CLOSED: snprintf(buf,buflen,"closed"); break; + default: break; + } +} + +static void on_bulk_ack(MMAL_DBG_ENTRY_T *entry, + char *buf, + size_t buflen) +{ + switch (entry->u.uint) + { + case VCHIQ_BULK_RECEIVE_ABORTED: snprintf(buf,buflen,"vchiq bulk rx abort"); break; + case VCHIQ_BULK_TRANSMIT_ABORTED: snprintf(buf,buflen,"vchiq bulk tx abort"); break; + case VCHIQ_BULK_TRANSMIT_DONE: snprintf(buf,buflen,"vchiq bulk tx done"); break; + case VCHIQ_BULK_RECEIVE_DONE: snprintf(buf,buflen,"vchiq bulk rx done"); break; + default: snprintf(buf,buflen,"vchiq unknown reason %d", entry->u.uint); break; + } +} + +static void on_msg(MMAL_DBG_ENTRY_T *entry, + char *buf, + size_t buflen) +{ + uint32_t id = entry->u.msg.header.msgid; + snprintf(buf,buflen,"msgid %d (%s)", id, mmal_msgname(id)); +} + +static void on_bulk(MMAL_DBG_ENTRY_T *entry, + char *buf, + size_t buflen) +{ + const char *name = entry->event_type == MMAL_DBG_BULK_TX ? "tx" : "rx"; + snprintf(buf,buflen,"bulk %s len %d", name, entry->u.bulk.len); +} + +static struct event_handler handlers[] = { + { MMAL_DBG_OPENED, on_openclose }, + { MMAL_DBG_CLOSED, on_openclose }, + { MMAL_DBG_BULK_ACK, on_bulk_ack }, + { MMAL_DBG_MSG, on_msg }, + { MMAL_DBG_BULK_TX, on_bulk }, + { MMAL_DBG_BULK_RX, on_bulk }, +}; +static int n_handlers = sizeof(handlers)/sizeof(handlers[0]); + +static void print_mmal_event_log(VC_MEM_ACCESS_HANDLE_T vc, MMAL_DBG_LOG_T *log) +{ + uint32_t i; + uint32_t n = vcos_min(log->num_entries, log->index); + uint32_t mask = log->num_entries-1; + uint32_t start = log->index < log->num_entries ? + 0 : log->index & mask; + uint32_t last_t = 0; + (void)vc; + + for (i=0; ientries[(start+i) & mask]; + char buf[256]; + int j; + uint32_t t = e->time; + printf("[%08u]: ", t-last_t); + last_t = t; + for (j=0; jevent_type) + { + handlers[j].handler(e, buf, sizeof(buf)); + printf("%s\n", buf); + break; + } + } + if (j == n_handlers ) + printf("Unknown event type %d\n", e->event_type); + } +} + +static int do_eventlog(int argc, const char **argv) +{ + VC_MEM_ACCESS_HANDLE_T vc; + VC_MEM_ADDR_T addr; /** The address of the pointer to the log */ + size_t size; + VC_MEM_ADDR_T logaddr; /** The address of the log itself */ + MMAL_DBG_LOG_T log; + + (void)argc; (void)argv; + int rc; + if ((rc = OpenVideoCoreMemory(&vc)) < 0) + { + fprintf(stderr,"Unable to open videocore memory: %d\n", rc); + return -1; + } + if (!LookupVideoCoreSymbol(vc, "mmal_dbg_log", &addr, &size)) + { + fprintf(stderr,"Could not get MMAL log address\n"); + goto fail; + } + if (!ReadVideoCoreUInt32(vc, &logaddr, addr)) + { + fprintf(stderr,"Could not read MMAL log pointer at address 0x%x\n", + addr); + goto fail; + } + if (!ReadVideoCoreMemory(vc, &log, logaddr, sizeof(log))) + { + fprintf(stderr,"Could not read MMAL log at address 0x%x\n", + logaddr); + goto fail; + } + if (log.magic != MMAL_MAGIC) + { + fprintf(stderr,"Bad magic 0x%08x in log at 0x%x\n", log.magic, logaddr); + goto fail; + } + if (log.size != sizeof(log)) + { + fprintf(stderr,"MMAL Log size mismatch (got %d, expected %d)\n", + log.size, sizeof(log)); + goto fail; + } + if (log.elemsize != sizeof(MMAL_DBG_ENTRY_T)) + { + fprintf(stderr,"MMAL log element size mismatch (got %d, expected %d)\n", + log.elemsize, sizeof(MMAL_DBG_ENTRY_T)); + goto fail; + } + + printf("reading MMAL log at 0x%x version %d magic %x\n", + logaddr, log.version, log.magic); + printf("%d events, %d entries each size %d\n", log.index, log.num_entries, + log.elemsize); + print_mmal_event_log(vc, &log); + + CloseVideoCoreMemory(vc); + return 0; +fail: + CloseVideoCoreMemory(vc); + return -1; + +} + +static int print_component_stats(const MMAL_VC_STATS_T *stats) +{ + size_t i; + if (stats->components.list_size > 64) + { + fprintf(stderr,"component array looks corrupt (list size %d\n", + stats->components.list_size); + goto fail; + } + printf("%d created, %d destroyed (%d destroying), %d create failures\n", + stats->components.created, + stats->components.destroyed, + stats->components.destroying, + stats->components.failed); + + for (i=0; i < stats->components.list_size; i++) + { + const struct MMAL_VC_COMP_STATS_T *cs = stats->components.component_list+i; + const char *state; + /* coverity[overrun-local] */ + if (cs->state != MMAL_STATS_COMP_IDLE) + { + switch (cs->state) + { + case MMAL_STATS_COMP_CREATED: state = "created"; break; + case MMAL_STATS_COMP_DESTROYING: state = "destroying"; break; + case MMAL_STATS_COMP_DESTROYED: state = "destroyed"; break; + default: state = "corrupt"; break; + } + printf("%-32s: %s: pid %d address %p pool mem alloc size %d\n", + cs->name, state, cs->pid, cs->comp, cs->pool_mem_alloc_size); + } + } + return 0; +fail: + return -1; +} + +static int do_components(int argc, const char **argv) +{ + VC_MEM_ACCESS_HANDLE_T vc; + VC_MEM_ADDR_T addr, statsaddr; + size_t size; + MMAL_VC_STATS_T stats; + int rc; + + + if (argc > 2 && (strcasecmp(argv[2], "update") == 0)) + { + MMAL_STATUS_T status; + do_connect(); + status = mmal_vc_get_stats(&stats, 0); + if (status != MMAL_SUCCESS) + { + fprintf(stderr, "Failed to update MMAL stats. error %s", + mmal_status_to_string(status)); + return -1; + } + } + else + { + if ((rc = OpenVideoCoreMemory(&vc)) < 0) + { + fprintf(stderr,"Unable to open videocore memory: %d\n", rc); + return -1; + } + if (!LookupVideoCoreSymbol(vc, "mmal_vc_stats", &addr, &size)) + { + fprintf(stderr,"Could not get MMAL stats address\n"); + goto fail; + } + if (!ReadVideoCoreUInt32(vc, &statsaddr, addr)) + { + fprintf(stderr,"Could not read MMAL stats pointer at address 0x%x\n", + addr); + goto fail; + } + if (!ReadVideoCoreMemory(vc, &stats, statsaddr, sizeof(stats))) + { + fprintf(stderr,"Could not read MMAL stats at address 0x%x\n", addr); + goto fail; + } + CloseVideoCoreMemory(vc); + } + rc = print_component_stats(&stats); + return rc; + +fail: + CloseVideoCoreMemory(vc); + return -1; +} + +static int do_mmal_stats(int argc, const char **argv) +{ + unsigned comp_index = 0; + MMAL_BOOL_T more_ports = MMAL_TRUE, reset = MMAL_FALSE; + unsigned port_index = 0; + MMAL_PORT_TYPE_T type = MMAL_PORT_TYPE_INPUT; + + if (argc >= 3) + reset = strcasecmp(argv[2], "reset") == 0; + + printf("component\t\tport\t\tbuffers\t\tfps\tdelay\n"); + while (more_ports) + { + int dir; + const char *dirnames[] = {"rx","tx"}; + MMAL_STATS_RESULT_T result; + + for (dir = MMAL_CORE_STATS_RX; dir <= MMAL_CORE_STATS_TX; dir++) + { + double framerate; + MMAL_CORE_STATISTICS_T stats; + char name[32]; + MMAL_STATUS_T status = mmal_vc_get_core_stats(&stats, + &result, + name, sizeof(name), + type, + comp_index, + port_index, + dir, + reset); + if (status != MMAL_SUCCESS) + { + fprintf(stderr, "could not get core stats: %s\n", + mmal_status_to_string(status)); + exit(1); + } + + if (result == MMAL_STATS_FOUND) + { + if (stats.first_buffer_time == stats.last_buffer_time) + framerate = 0; + else + framerate = 1.0e6*(1+stats.buffer_count)/(stats.last_buffer_time-stats.first_buffer_time); + + printf("%-20s\t%d [%s]%2s\t%-10d\t%4.1f\t%d\n", + name, port_index, + type == MMAL_PORT_TYPE_INPUT ? "in " : "out", + dirnames[dir], + stats.buffer_count, framerate, stats.max_delay); + + } + } + + switch (result) + { + case MMAL_STATS_FOUND: + port_index++; + break; + + case MMAL_STATS_COMPONENT_NOT_FOUND: + more_ports = MMAL_FALSE; + break; + + case MMAL_STATS_PORT_NOT_FOUND: + port_index = 0; + if (type == MMAL_PORT_TYPE_INPUT) + { + type = MMAL_PORT_TYPE_OUTPUT; + } + else + { + type = MMAL_PORT_TYPE_INPUT; + comp_index++; + } + break; + default: + fprintf(stderr, "bad result from query: %d\n", result); + vcos_assert(0); + exit(1); + } + } + return 0; +} + +static int do_imageconv_stats(int argc, const char **argv) +{ + VC_MEM_ACCESS_HANDLE_T vc; + VC_MEM_ADDR_T addr, statsaddr; + size_t size; + IMAGECONV_STATS_T stats; + long convert_time; + double frame_rate; + int rc; + int reset_stats = 0; + + if (argc > 2) + reset_stats = strcasecmp(argv[2], "reset") == 0; + + if ((rc = OpenVideoCoreMemory(&vc)) < 0) + { + fprintf(stderr,"Unable to open videocore memory: %d\n", rc); + return -1; + } + if (!LookupVideoCoreSymbol(vc, "imageconv_stats", &addr, &size)) + { + fprintf(stderr,"Could not get imageconv stats address\n"); + goto fail; + } + if (!ReadVideoCoreUInt32(vc, &statsaddr, addr)) + { + fprintf(stderr, "Could not read imageconv stats address\n"); + goto fail; + } + + if (reset_stats) + { + memset(&stats, 0, sizeof(stats)); + stats.magic = IMAGECONV_STATS_MAGIC; + if (!WriteVideoCoreMemory(vc, &stats, statsaddr, sizeof(stats))) + { + fprintf(stderr, "Could not write stats at 0x%x\n", statsaddr); + goto fail; + } + } + + if (!ReadVideoCoreMemory(vc, &stats, statsaddr, sizeof(stats))) + { + fprintf(stderr, "Could not read stats at 0x%x\n", statsaddr); + goto fail; + } + + if (stats.magic != IMAGECONV_STATS_MAGIC) + { + fprintf(stderr, "Bad magic 0x%x\n", stats.magic); + goto fail; + } + + if (stats.conversions) + convert_time = stats.time_spent / stats.conversions; + else + convert_time = 0; + + if (stats.conversions) + frame_rate = 1000000.0 * stats.conversions / + (stats.last_image_ts - stats.first_image_ts); + else + frame_rate = 0; + + printf("%-25s:\t%d\n", "conversions", stats.conversions); + printf("%-25s:\t%d\n", "size requests", stats.size_requests); + printf("%-25s:\t%d\n", "max vrf delay", stats.max_vrf_delay); + printf("%-25s:\t%d\n", "vrf wait time", stats.vrf_wait_time); + printf("%-25s:\t%d\n", "duplicate conversions", stats.duplicate_conversions); + printf("%-25s:\t%d\n", "failures", stats.failures); + printf("%-25s:\t%ld\n", "convert time / image (us)", convert_time); + printf("%-25s:\t%.1f\n", "client frame_rate", frame_rate); + printf("%-25s:\t%d us\n", "max delay to consume", stats.max_delay); + + CloseVideoCoreMemory(vc); + return 0; +fail: + CloseVideoCoreMemory(vc); + return -1; + +} + +/* Autosuspend test. Create a component, but kill process + * shortly after startup. + */ + +static int autosusp_signal; + +static void autosusp_timeout_handler(int cause, siginfo_t *how, void *ucontext) +{ + (void)how; (void)ucontext; (void)cause; + printf("Sending signal %d\n", autosusp_signal); + kill(getpid(), autosusp_signal); +} + +static int do_autosusptest(int argc, const char **argv) +{ + long timeout; + struct timeval interval; + MMAL_STATUS_T status; + + if (argc != 4) + { + printf("usage: %s autosusp \n", + argv[0]); + printf(" e.g. 650 9\n"); + exit(1); + } + timeout = 1000 * atoi(argv[2]); + autosusp_signal = atoi(argv[3]); + + if ((status=mmal_vc_use()) != MMAL_SUCCESS) + { + fprintf(stderr,"mmal_vc_use failed: %d\n", status); + exit(1); + } + + /* install a signal handler for the alarm */ + struct sigaction sa; + memset(&sa, 0, sizeof(struct sigaction)); + sa.sa_sigaction = autosusp_timeout_handler; + sigemptyset(&sa.sa_mask); + sa.sa_flags = SA_SIGINFO; + if (sigaction(SIGALRM, &sa, 0)) + { + perror("sigaction"); + exit(1); + } + + /* when to expire */ + interval.tv_sec = timeout / 1000000; + interval.tv_usec = timeout % 1000000; + + struct itimerval alarm_spec = { + .it_interval = {0,0}, + .it_value = interval + }; + + int rc = setitimer(ITIMER_REAL, &alarm_spec, NULL); + if (rc < 0) + { + perror("setitimer failed"); + exit(1); + } + + usleep(timeout + 1000000); + printf("%s: not killed by timer\n", argv[0]); + mmal_vc_release(); + + return 0; +} + +static int do_camerainfo(int argc, const char **argv) +{ + MMAL_COMPONENT_T *comp; + MMAL_STATUS_T st; + MMAL_PARAMETER_CAMERA_INFO_T mmal_camera_config_info; + unsigned i; + (void)argc; + (void)argv; + + st = mmal_component_create("vc.camera_info", &comp); + if (st != MMAL_SUCCESS) + { + fprintf(stderr, "Failed to create camera_info: %d\n", st); + exit(1); + } + + mmal_camera_config_info.hdr.id = MMAL_PARAMETER_CAMERA_INFO; + mmal_camera_config_info.hdr.size = sizeof(mmal_camera_config_info); + st = mmal_port_parameter_get(comp->control, &mmal_camera_config_info.hdr); + if (st != MMAL_SUCCESS) + { + fprintf(stderr, "%s: get param failed:%d", __FUNCTION__, st); + exit(1); + } + + printf("cameras : %d\n", mmal_camera_config_info.num_cameras); + printf("flashes : %d\n", mmal_camera_config_info.num_flashes); + + for (i=0; i 2) + mmal_vc_host_log(argv[2]); + return 0; +} diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/vc/mmal_vc_msgnames.c b/external_src/raspicam-0.1.3/dependencies/mmal/vc/mmal_vc_msgnames.c new file mode 100644 index 0000000..ba53d45 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/vc/mmal_vc_msgnames.c @@ -0,0 +1,77 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 "mmal_vc_msgnames.h" +#include "mmal_vc_msgs.h" + +/** Convert a message id to a name. + */ +const char *mmal_msgname(uint32_t id) +{ +#define MSGNAME(x) { MMAL_WORKER_##x, #x } + static struct { + uint32_t id; + const char *name; + } msgnames[] = { + MSGNAME(QUIT), + MSGNAME(SERVICE_CLOSED), + MSGNAME(GET_VERSION), + MSGNAME(COMPONENT_CREATE), + MSGNAME(COMPONENT_DESTROY), + MSGNAME(COMPONENT_ENABLE), + MSGNAME(COMPONENT_DISABLE), + MSGNAME(PORT_INFO_GET), + MSGNAME(PORT_INFO_SET), + MSGNAME(PORT_ACTION), + MSGNAME(BUFFER_FROM_HOST), + MSGNAME(BUFFER_TO_HOST), + MSGNAME(GET_STATS), + MSGNAME(PORT_PARAMETER_SET), + MSGNAME(PORT_PARAMETER_GET), + MSGNAME(EVENT_TO_HOST), + MSGNAME(GET_CORE_STATS_FOR_PORT), + MSGNAME(OPAQUE_ALLOCATOR), + MSGNAME(CONSUME_MEM), + MSGNAME(LMK), + MSGNAME(OPAQUE_ALLOCATOR_DESC), + MSGNAME(DRM_GET_LHS32), + MSGNAME(DRM_GET_TIME), + MSGNAME(BUFFER_FROM_HOST_ZEROLEN), + MSGNAME(PORT_FLUSH), + MSGNAME(HOST_LOG), + { 0, NULL }, + }; + vcos_static_assert(sizeof(msgnames)/sizeof(msgnames[0]) == MMAL_WORKER_MSG_LAST); + int i = 0; + while (msgnames[i].name) + { + if (msgnames[i].id == id) + return msgnames[i].name; + i++; + } + return "unknown-message"; +} diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/vc/mmal_vc_msgnames.h b/external_src/raspicam-0.1.3/dependencies/mmal/vc/mmal_vc_msgnames.h new file mode 100644 index 0000000..12a97c7 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/vc/mmal_vc_msgnames.h @@ -0,0 +1,37 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 MMAL_VC_MSGNAMES_H +#define MMAL_VC_MSGNAMES_H + +#include "interface/vcos/vcos.h" + +/** Convert a message id to a name. + */ +const char *mmal_msgname(uint32_t id); + +#endif diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/vc/mmal_vc_msgs.h b/external_src/raspicam-0.1.3/dependencies/mmal/vc/mmal_vc_msgs.h new file mode 100644 index 0000000..440ee2d --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/vc/mmal_vc_msgs.h @@ -0,0 +1,525 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 MMAL_VC_MSGS_H +#define MMAL_VC_MSGS_H + +/** @file mmal_vc_msgs.h + * + * Private message definitions, defining the message API between + * the host and VideoCore. + */ +#include "interface/vcos/vcos.h" +#include "interface/mmal/mmal.h" +#include "mmal_vc_api.h" + +#define MMAL_CONTROL_FOURCC() VCHIQ_MAKE_FOURCC('m','m','a','l') + +/* Major version indicates binary backwards compatiblity */ +#define WORKER_VER_MAJOR 16 +#define WORKER_VER_MINIMUM 10 +/* Minor version is not used normally. + */ +#define WORKER_VER_MINOR 1 +#ifndef WORKER_VER_MINIMUM +#endif + +#define VIDEOCORE_PREFIX "vc" + +#define MMAL_MAX_PORTS 8 /**< Max ports per component */ + +#define MMAL_WORKER_MAX_MSG_LEN 512 +#define MMAL_VC_CORE_STATS_NAME_MAX 32 /**< Length of the name in the core stats message */ + +/** A MMAL_CONTROL_SERVICE_T gets space for a single message. This + * is the space allocated for these messages. + */ +#define MMAL_WORKER_MSG_LEN 28 + +/** Maximum size of the format extradata. + * FIXME: should probably be made bigger and maybe be passed separately from the info. + */ +#define MMAL_FORMAT_EXTRADATA_MAX_SIZE 128 + +/** Size of space reserved in a buffer message for short messages. + */ +#define MMAL_VC_SHORT_DATA 128 + +/** Message ids sent to worker thread. + */ + +/* Please update the array in mmal_vc_msgnames.c if this is updated. + */ +typedef enum { + MMAL_WORKER_QUIT = 1, + MMAL_WORKER_SERVICE_CLOSED, + MMAL_WORKER_GET_VERSION, + MMAL_WORKER_COMPONENT_CREATE, + MMAL_WORKER_COMPONENT_DESTROY, + MMAL_WORKER_COMPONENT_ENABLE, + MMAL_WORKER_COMPONENT_DISABLE, + MMAL_WORKER_PORT_INFO_GET, + MMAL_WORKER_PORT_INFO_SET, + MMAL_WORKER_PORT_ACTION, + MMAL_WORKER_BUFFER_FROM_HOST, + MMAL_WORKER_BUFFER_TO_HOST, + MMAL_WORKER_GET_STATS, + MMAL_WORKER_PORT_PARAMETER_SET, + MMAL_WORKER_PORT_PARAMETER_GET, + MMAL_WORKER_EVENT_TO_HOST, + MMAL_WORKER_GET_CORE_STATS_FOR_PORT, + MMAL_WORKER_OPAQUE_ALLOCATOR, + /* VC debug mode only - due to security, denial of service implications */ + MMAL_WORKER_CONSUME_MEM, + MMAL_WORKER_LMK, + MMAL_WORKER_OPAQUE_ALLOCATOR_DESC, + MMAL_WORKER_DRM_GET_LHS32, + MMAL_WORKER_DRM_GET_TIME, + MMAL_WORKER_BUFFER_FROM_HOST_ZEROLEN, + MMAL_WORKER_PORT_FLUSH, + MMAL_WORKER_HOST_LOG, + MMAL_WORKER_MSG_LAST +} MMAL_WORKER_CMD_T; + +/** Every message has one of these at the start. + */ +typedef struct +{ + uint32_t magic; + uint32_t msgid; + struct MMAL_CONTROL_SERVICE_T *control_service; /** Handle to the control service */ + + union { + struct MMAL_WAITER_T *waiter; /** User-land wait structure, passed back */ + } u; + + MMAL_STATUS_T status; /** Result code, passed back */ + /* Make sure this structure is 64 bit aligned */ + uint32_t dummy; +} mmal_worker_msg_header; + +/* Make sure mmal_worker_msg_header will preserve 64 bits alignment */ +vcos_static_assert(!(sizeof(mmal_worker_msg_header) & 0x7)); + +/* Message structures sent to worker thread. + */ + +/** Tell the worker a service has closed. It should start to delete + * the associated components. + */ +typedef struct +{ + mmal_worker_msg_header header; +} mmal_worker_service_closed; +vcos_static_assert(sizeof(mmal_worker_service_closed) <= MMAL_WORKER_MSG_LEN); + +/** Send from VC to host to report our version */ +typedef struct +{ + mmal_worker_msg_header header; + uint32_t flags; + uint32_t major; + uint32_t minor; + uint32_t minimum; +} mmal_worker_version; + +/** Request component creation */ +typedef struct +{ + mmal_worker_msg_header header; + void *client_component; /** Client component */ + char name[128]; + uint32_t pid; /**< For debug */ +} mmal_worker_component_create; + +/** Reply to component-creation message. Reports back + * the number of ports. + */ +typedef struct +{ + mmal_worker_msg_header header; + MMAL_STATUS_T status; + uint32_t component_handle; /** Handle on VideoCore for component */ + uint32_t input_num; /**< Number of input ports */ + uint32_t output_num; /**< Number of output ports */ + uint32_t clock_num; /**< Number of clock ports */ +} mmal_worker_component_create_reply; +vcos_static_assert(sizeof(mmal_worker_component_create_reply) <= MMAL_WORKER_MAX_MSG_LEN); + +/** Destroys a component + */ +typedef struct +{ + mmal_worker_msg_header header; + uint32_t component_handle; /**< which component */ +} mmal_worker_component_destroy; + +/** Enables a component + */ +typedef struct +{ + mmal_worker_msg_header header; + uint32_t component_handle; /**< which component */ +} mmal_worker_component_enable; + +/** Disable a component + */ +typedef struct +{ + mmal_worker_msg_header header; + uint32_t component_handle; /**< Which component */ +} mmal_worker_component_disable; + +/** Component port info. Used to get port info. + */ +typedef struct +{ + mmal_worker_msg_header header; + uint32_t component_handle; /**< Which component */ + MMAL_PORT_TYPE_T port_type; /**< Type of port */ + uint32_t index; /**< Which port of given type to get */ +} mmal_worker_port_info_get; +vcos_static_assert(sizeof(mmal_worker_port_info_get) <= MMAL_WORKER_MAX_MSG_LEN); + +/** Component port info. Used to set port info. + */ +typedef struct +{ + mmal_worker_msg_header header; + uint32_t component_handle; /**< Which component */ + MMAL_PORT_TYPE_T port_type; /**< Type of port */ + uint32_t index; /**< Which port of given type to get */ + MMAL_PORT_T port; + MMAL_ES_FORMAT_T format; + MMAL_ES_SPECIFIC_FORMAT_T es; + uint8_t extradata[MMAL_FORMAT_EXTRADATA_MAX_SIZE]; +} mmal_worker_port_info_set; +vcos_static_assert(sizeof(mmal_worker_port_info_set) <= MMAL_WORKER_MAX_MSG_LEN); + +/** Report port info back in response to a get / set. */ +typedef struct +{ + mmal_worker_msg_header header; + MMAL_STATUS_T status; /**< Result of query */ + uint32_t component_handle; /**< Which component */ + MMAL_PORT_TYPE_T port_type; /**< Type of port */ + uint32_t index; /**< Which port of given type to get */ + int32_t found; /**< Did we find anything? */ + uint32_t port_handle; /**< Handle to use for this port */ + MMAL_PORT_T port; + MMAL_ES_FORMAT_T format; + MMAL_ES_SPECIFIC_FORMAT_T es; + uint8_t extradata[MMAL_FORMAT_EXTRADATA_MAX_SIZE]; +} mmal_worker_port_info; +vcos_static_assert(sizeof(mmal_worker_port_info) <= MMAL_WORKER_MAX_MSG_LEN); + +typedef struct +{ + mmal_worker_msg_header header; + MMAL_STATUS_T status; +} mmal_worker_reply; + +typedef struct +{ + mmal_worker_msg_header header; + MMAL_STATUS_T status; + uint8_t secret[32]; +} mmal_worker_drm_get_lhs32_reply; +vcos_static_assert(sizeof(mmal_worker_drm_get_lhs32_reply) <= MMAL_WORKER_MAX_MSG_LEN); + +typedef struct +{ + mmal_worker_msg_header header; + MMAL_STATUS_T status; + uint32_t time; +} mmal_worker_drm_get_time_reply; +vcos_static_assert(sizeof(mmal_worker_drm_get_time_reply) <= MMAL_WORKER_MAX_MSG_LEN); + +/** List of actions for a port */ +enum MMAL_WORKER_PORT_ACTIONS +{ + MMAL_WORKER_PORT_ACTION_UNKNOWN = 0, /**< Unkown action */ + MMAL_WORKER_PORT_ACTION_ENABLE, /**< Enable a port */ + MMAL_WORKER_PORT_ACTION_DISABLE, /**< Disable a port */ + MMAL_WORKER_PORT_ACTION_FLUSH, /**< Flush a port */ + MMAL_WORKER_PORT_ACTION_CONNECT, /**< Connect 2 ports together */ + MMAL_WORKER_PORT_ACTION_DISCONNECT, /**< Disconnect 2 ports connected together */ + MMAL_WORKER_PORT_ACTION_SET_REQUIREMENTS, /**< Set buffer requirements */ + MMAL_WORKER_PORT_ACTION_MAX = 0x7fffffff /**< Make the enum 32bits */ +}; + +/** Trigger an action on a port. + */ +typedef struct +{ + mmal_worker_msg_header header; + uint32_t component_handle; + uint32_t port_handle; + enum MMAL_WORKER_PORT_ACTIONS action; + + /** Action parameter */ + union { + struct { + MMAL_PORT_T port; + } enable; + struct { + uint32_t component_handle; + uint32_t port_handle; + } connect; + } param; + +} mmal_worker_port_action; +vcos_static_assert(sizeof(mmal_worker_port_action) <= MMAL_WORKER_MAX_MSG_LEN); + +#define MMAL_WORKER_PORT_PARAMETER_SPACE 96 + +#define MMAL_WORKER_PORT_PARAMETER_SET_MAX \ + (MMAL_WORKER_PORT_PARAMETER_SPACE*sizeof(uint32_t)+sizeof(MMAL_PARAMETER_HEADER_T)) + +#define MMAL_WORKER_PORT_PARAMETER_GET_MAX MMAL_WORKER_PORT_PARAMETER_SET_MAX + +/** Component port parameter set. Doesn't include space for the parameter data. + */ +typedef struct +{ + mmal_worker_msg_header header; + uint32_t component_handle; /**< Which component */ + uint32_t port_handle; /**< Which port */ + MMAL_PARAMETER_HEADER_T param; /**< Parameter ID and size */ + uint32_t space[MMAL_WORKER_PORT_PARAMETER_SPACE]; +} mmal_worker_port_param_set; +vcos_static_assert(sizeof(mmal_worker_port_param_set) <= MMAL_WORKER_MAX_MSG_LEN); + +/** Component port parameter get. + */ +typedef struct +{ + mmal_worker_msg_header header; + uint32_t component_handle; /**< Which component */ + uint32_t port_handle; /**< Which port */ + MMAL_PARAMETER_HEADER_T param; /**< Parameter ID and size */ + uint32_t space[MMAL_WORKER_PORT_PARAMETER_SPACE]; +} mmal_worker_port_param_get; +vcos_static_assert(sizeof(mmal_worker_port_param_get) <= MMAL_WORKER_MAX_MSG_LEN); + +typedef struct +{ + mmal_worker_msg_header header; + uint32_t component_handle; /**< Which component */ + uint32_t port_handle; /**< Which port */ + MMAL_PARAMETER_HEADER_T param; /**< Parameter ID and size */ +} mmal_worker_port_param_get_old; + +/** Component port parameter get reply. Doesn't include space for the parameter data. + */ +typedef struct +{ + mmal_worker_msg_header header; + MMAL_STATUS_T status; /**< Status of mmal_port_parameter_get call */ + MMAL_PARAMETER_HEADER_T param; /**< Parameter ID and size */ + uint32_t space[MMAL_WORKER_PORT_PARAMETER_SPACE]; +} mmal_worker_port_param_get_reply; +vcos_static_assert(sizeof(mmal_worker_port_param_get_reply) <= MMAL_WORKER_MAX_MSG_LEN); + +/** Buffer header driver area structure. In the private area + * of a buffer header there is a driver area where we can + * put values. This structure defines the layout of that. + */ +struct MMAL_DRIVER_BUFFER_T +{ + uint32_t magic; + uint32_t component_handle; /**< The component this buffer is from */ + uint32_t port_handle; /**< Index into array of ports for this component */ + + /** Client side uses this to get back to its context structure. */ + struct MMAL_VC_CLIENT_BUFFER_CONTEXT_T *client_context; +}; + +/** Receive a buffer from the host. + * + * @sa mmal_port_send_buffer() + */ + +typedef struct mmal_worker_buffer_from_host +{ + mmal_worker_msg_header header; + + /** Our control data, copied from the buffer header "driver area" + * @sa mmal_buffer_header_driver_data(). + */ + struct MMAL_DRIVER_BUFFER_T drvbuf; + + /** Referenced buffer control data. + * This is set if the buffer is referencing another + * buffer as is the case with passthrough ports where + * buffers on the output port reference buffers on the + * input port. */ + struct MMAL_DRIVER_BUFFER_T drvbuf_ref; + + /** the buffer header itself */ + MMAL_BUFFER_HEADER_T buffer_header; + MMAL_BUFFER_HEADER_TYPE_SPECIFIC_T buffer_header_type_specific; + + MMAL_BOOL_T is_zero_copy; + MMAL_BOOL_T has_reference; + + /** If the data is short enough, then send it in the control message rather + * than using a separate VCHIQ bulk transfer. + */ + uint32_t payload_in_message; + uint8_t short_data[MMAL_VC_SHORT_DATA]; + +} mmal_worker_buffer_from_host; +vcos_static_assert(sizeof(mmal_worker_buffer_from_host) <= MMAL_WORKER_MAX_MSG_LEN); + +/** Maximum number of event data bytes that can be passed in the message. + * More than this and the data is passed in a bulk message. + */ +#define MMAL_WORKER_EVENT_SPACE 256 + +/** Send an event buffer from the host. + * + * @sa mmal_port_send_event() + */ + +typedef struct mmal_worker_event_to_host +{ + mmal_worker_msg_header header; + + struct MMAL_COMPONENT_T *client_component; + uint32_t port_type; + uint32_t port_num; + + uint32_t cmd; + uint32_t length; + uint8_t data[MMAL_WORKER_EVENT_SPACE]; + MMAL_BUFFER_HEADER_T *delayed_buffer; /* Only used to remember buffer for bulk rx */ +} mmal_worker_event_to_host; +vcos_static_assert(sizeof(mmal_worker_event_to_host) <= MMAL_WORKER_MAX_MSG_LEN); + +typedef struct +{ + mmal_worker_msg_header header; + MMAL_VC_STATS_T stats; + uint32_t reset; +} mmal_worker_stats; +vcos_static_assert(sizeof(mmal_worker_stats) <= MMAL_WORKER_MAX_MSG_LEN); + +typedef enum { + MMAL_WORKER_OPAQUE_MEM_ALLOC, + MMAL_WORKER_OPAQUE_MEM_RELEASE, + MMAL_WORKER_OPAQUE_MEM_ACQUIRE, + MMAL_WORKER_OPAQUE_MEM_MAX = 0x7fffffff, +} MMAL_WORKER_OPAQUE_MEM_OP; + +typedef struct +{ + mmal_worker_msg_header header; + MMAL_WORKER_OPAQUE_MEM_OP op; + uint32_t handle; + MMAL_STATUS_T status; + char description[32]; +} mmal_worker_opaque_allocator; + +/* + * Per-port core statistics + */ +typedef struct +{ + mmal_worker_msg_header header; + uint32_t component_index; + uint32_t port_index; + MMAL_PORT_TYPE_T type; + MMAL_CORE_STATS_DIR dir; + MMAL_BOOL_T reset; +} mmal_worker_get_core_stats_for_port; + +typedef struct +{ + mmal_worker_msg_header header; + MMAL_STATUS_T status; + MMAL_STATS_RESULT_T result; + MMAL_CORE_STATISTICS_T stats; + char component_name[MMAL_VC_CORE_STATS_NAME_MAX]; +} mmal_worker_get_core_stats_for_port_reply; + +typedef struct +{ + mmal_worker_msg_header header; + MMAL_STATUS_T status; + /* The amount of memory to reserve */ + uint32_t size; + /* Handle to newly allocated memory or MEM_HANDLE_INVALD on failure */ + uint32_t handle; +} mmal_worker_consume_mem; +vcos_static_assert(sizeof(mmal_worker_consume_mem) <= MMAL_WORKER_MAX_MSG_LEN); + +typedef struct +{ + mmal_worker_msg_header header; + /* Message text to add to the circular buffer */ + char msg[MMAL_WORKER_MAX_MSG_LEN - sizeof(mmal_worker_msg_header)]; +} mmal_worker_host_log; +vcos_static_assert(sizeof(mmal_worker_host_log) <= MMAL_WORKER_MAX_MSG_LEN); + +typedef struct +{ + mmal_worker_msg_header header; + /* The memory allocation size to pass to lmk, as if in a response to an + * allocation for this amount of memory. */ + uint32_t alloc_size; +} mmal_worker_lmk; +vcos_static_assert(sizeof(mmal_worker_lmk) <= MMAL_WORKER_MAX_MSG_LEN); + +static inline void mmal_vc_buffer_header_to_msg(mmal_worker_buffer_from_host *msg, + MMAL_BUFFER_HEADER_T *header) +{ + msg->buffer_header.cmd = header->cmd; + msg->buffer_header.offset = header->offset; + msg->buffer_header.length = header->length; + msg->buffer_header.flags = header->flags; + msg->buffer_header.pts = header->pts; + msg->buffer_header.dts = header->dts; + msg->buffer_header.alloc_size = header->alloc_size; + msg->buffer_header.data = header->data; + msg->buffer_header_type_specific = *header->type; +} + +static inline void mmal_vc_msg_to_buffer_header(MMAL_BUFFER_HEADER_T *header, + mmal_worker_buffer_from_host *msg) +{ + header->cmd = msg->buffer_header.cmd; + header->offset = msg->buffer_header.offset; + header->length = msg->buffer_header.length; + header->flags = msg->buffer_header.flags; + header->pts = msg->buffer_header.pts; + header->dts = msg->buffer_header.dts; + *header->type = msg->buffer_header_type_specific; +} + +#endif + diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/vc/mmal_vc_opaque_alloc.c b/external_src/raspicam-0.1.3/dependencies/mmal/vc/mmal_vc_opaque_alloc.c new file mode 100644 index 0000000..b5b5ba9 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/vc/mmal_vc_opaque_alloc.c @@ -0,0 +1,87 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 "interface/mmal/vc/mmal_vc_opaque_alloc.h" +#include "mmal_vc_msgs.h" +#include "mmal_vc_client_priv.h" + +MMAL_OPAQUE_IMAGE_HANDLE_T mmal_vc_opaque_alloc_desc(const char *description) +{ + MMAL_STATUS_T ret; + MMAL_OPAQUE_IMAGE_HANDLE_T h = 0; + mmal_worker_opaque_allocator msg; + size_t len = sizeof(msg); + msg.op = MMAL_WORKER_OPAQUE_MEM_ALLOC; + vcos_safe_strcpy(msg.description, description, sizeof(msg.description), 0); + ret = mmal_vc_sendwait_message(mmal_vc_get_client(), + &msg.header, sizeof(msg), + MMAL_WORKER_OPAQUE_ALLOCATOR_DESC, + &msg, &len, MMAL_FALSE); + if (ret == MMAL_SUCCESS) + { + h = msg.handle; + } + return h; +} + +MMAL_OPAQUE_IMAGE_HANDLE_T mmal_vc_opaque_alloc(void) +{ + return mmal_vc_opaque_alloc_desc("?"); +} + +MMAL_STATUS_T mmal_vc_opaque_acquire(unsigned int handle) +{ + MMAL_STATUS_T ret; + mmal_worker_opaque_allocator msg; + size_t len = sizeof(msg); + msg.handle = handle; + msg.op = MMAL_WORKER_OPAQUE_MEM_ACQUIRE; + ret = mmal_vc_sendwait_message(mmal_vc_get_client(), + &msg.header, sizeof(msg), + MMAL_WORKER_OPAQUE_ALLOCATOR, + &msg, &len, MMAL_FALSE); + if (ret == MMAL_SUCCESS) + ret = msg.status; + return ret; +} + +MMAL_STATUS_T mmal_vc_opaque_release(unsigned int handle) +{ + MMAL_STATUS_T ret; + mmal_worker_opaque_allocator msg; + size_t len = sizeof(msg); + msg.handle = handle; + msg.op = MMAL_WORKER_OPAQUE_MEM_RELEASE; + ret = mmal_vc_sendwait_message(mmal_vc_get_client(), + &msg.header, sizeof(msg), + MMAL_WORKER_OPAQUE_ALLOCATOR, + &msg, &len, MMAL_FALSE); + if (ret == MMAL_SUCCESS) + ret = msg.status; + return ret; +} + diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/vc/mmal_vc_opaque_alloc.h b/external_src/raspicam-0.1.3/dependencies/mmal/vc/mmal_vc_opaque_alloc.h new file mode 100644 index 0000000..60a5e56 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/vc/mmal_vc_opaque_alloc.h @@ -0,0 +1,73 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 MMAL_VC_OPAQUE_ALLOC_H +#define MMAL_VC_OPAQUE_ALLOC_H + + +#include +#include "interface/mmal/mmal.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef uint32_t MMAL_OPAQUE_IMAGE_HANDLE_T; + +/** Allocate an opaque image on VideoCore. + * + * @return allocated handle, or zero if allocation failed. + */ +MMAL_OPAQUE_IMAGE_HANDLE_T mmal_vc_opaque_alloc(void); + +/** Allocate an opaque image on VideoCore, providing a description. + * @return allocated handle, or zero if allocation failed. + */ +MMAL_OPAQUE_IMAGE_HANDLE_T mmal_vc_opaque_alloc_desc(const char *description); + +/** Release an opaque image. + * + * @param handle handle allocated earlier + * @return MMAL_SUCCESS or error code if handle not found + */ +MMAL_STATUS_T mmal_vc_opaque_release(MMAL_OPAQUE_IMAGE_HANDLE_T h); + +/** Acquire an additional reference to an opaque image. + * + * @param handle handle allocated earlier + * @return MMAL_SUCCESS or error code if handle not found + */ +MMAL_STATUS_T mmal_vc_opaque_acquire(MMAL_OPAQUE_IMAGE_HANDLE_T h); + + +#ifdef __cplusplus +} +#endif + + +#endif + diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/vc/mmal_vc_shm.c b/external_src/raspicam-0.1.3/dependencies/mmal/vc/mmal_vc_shm.c new file mode 100644 index 0000000..19222ca --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/vc/mmal_vc_shm.c @@ -0,0 +1,235 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 "interface/mmal/mmal_logging.h" +#include "interface/mmal/mmal.h" +#include "interface/vcos/vcos.h" + +#include "interface/mmal/vc/mmal_vc_shm.h" + +#ifdef ENABLE_MMAL_VCSM +# include "user-vcsm.h" +#endif /* ENABLE_MMAL_VCSM */ + +#define MMAL_VC_PAYLOAD_ELEM_MAX 512 + +typedef struct MMAL_VC_PAYLOAD_ELEM_T +{ + struct MMAL_VC_PAYLOAD_ELEM_T *next; + void *handle; + void *vc_handle; + uint8_t *mem; + MMAL_BOOL_T in_use; +} MMAL_VC_PAYLOAD_ELEM_T; + +typedef struct MMAL_VC_PAYLOAD_LIST_T +{ + MMAL_VC_PAYLOAD_ELEM_T list[MMAL_VC_PAYLOAD_ELEM_MAX]; + VCOS_MUTEX_T lock; +} MMAL_VC_PAYLOAD_LIST_T; + +static MMAL_VC_PAYLOAD_LIST_T mmal_vc_payload_list; + +static void mmal_vc_payload_list_init() +{ + vcos_mutex_create(&mmal_vc_payload_list.lock, "mmal_vc_payload_list"); +} + +static MMAL_VC_PAYLOAD_ELEM_T *mmal_vc_payload_list_get() +{ + MMAL_VC_PAYLOAD_ELEM_T *elem = 0; + unsigned int i; + + vcos_mutex_lock(&mmal_vc_payload_list.lock); + for (i = 0; i < MMAL_VC_PAYLOAD_ELEM_MAX; i++) + { + if (mmal_vc_payload_list.list[i].in_use) + continue; + elem = &mmal_vc_payload_list.list[i]; + elem->in_use = 1; + break; + } + vcos_mutex_unlock(&mmal_vc_payload_list.lock); + + return elem; +} + +static void mmal_vc_payload_list_release(MMAL_VC_PAYLOAD_ELEM_T *elem) +{ + vcos_mutex_lock(&mmal_vc_payload_list.lock); + elem->handle = elem->vc_handle = 0; + elem->mem = 0; + elem->in_use = 0; + vcos_mutex_unlock(&mmal_vc_payload_list.lock); +} + +static MMAL_VC_PAYLOAD_ELEM_T *mmal_vc_payload_list_find_mem(uint8_t *mem) +{ + MMAL_VC_PAYLOAD_ELEM_T *elem = 0; + unsigned int i; + + vcos_mutex_lock(&mmal_vc_payload_list.lock); + for (i = 0; i < MMAL_VC_PAYLOAD_ELEM_MAX; i++) + { + if (!mmal_vc_payload_list.list[i].in_use) + continue; + if (mmal_vc_payload_list.list[i].mem != mem) + continue; + elem = &mmal_vc_payload_list.list[i]; + break; + } + vcos_mutex_unlock(&mmal_vc_payload_list.lock); + + return elem; +} + +static MMAL_VC_PAYLOAD_ELEM_T *mmal_vc_payload_list_find_handle(uint8_t *mem) +{ + MMAL_VC_PAYLOAD_ELEM_T *elem = 0; + unsigned int i; + + vcos_mutex_lock(&mmal_vc_payload_list.lock); + for (i = 0; i < MMAL_VC_PAYLOAD_ELEM_MAX; i++) + { + if (!mmal_vc_payload_list.list[i].in_use) + continue; + if (mmal_vc_payload_list.list[i].vc_handle != (void *)mem) + continue; + elem = &mmal_vc_payload_list.list[i]; + break; + } + vcos_mutex_unlock(&mmal_vc_payload_list.lock); + + return elem; +} + +/** Initialise the shared memory system */ +MMAL_STATUS_T mmal_vc_shm_init(void) +{ +#ifdef ENABLE_MMAL_VCSM + if (vcsm_init() != 0) + { + LOG_ERROR("could not initialize vc shared memory service"); + return MMAL_EIO; + } +#endif /* ENABLE_MMAL_VCSM */ + + mmal_vc_payload_list_init(); + return MMAL_SUCCESS; +} + +/** Allocate a shared memory buffer */ +uint8_t *mmal_vc_shm_alloc(uint32_t size) +{ + uint8_t *mem = NULL; + + MMAL_VC_PAYLOAD_ELEM_T *payload_elem = mmal_vc_payload_list_get(); + if (!payload_elem) + { + LOG_ERROR("could not get a free slot in the payload list"); + return NULL; + } + +#ifdef ENABLE_MMAL_VCSM + unsigned int vcsm_handle = vcsm_malloc_cache(size, VCSM_CACHE_TYPE_HOST, "mmal_vc_port buffer"); + unsigned int vc_handle = vcsm_vc_hdl_from_hdl(vcsm_handle); + mem = (uint8_t *)vcsm_lock( vcsm_handle ); + if (!mem || !vc_handle) + { + LOG_ERROR("could not allocate %i bytes of shared memory (handle %x)", + (int)size, vcsm_handle); + if (mem) + vcsm_unlock_hdl(vcsm_handle); + if (vcsm_handle) + vcsm_free(vcsm_handle); + mmal_vc_payload_list_release(payload_elem); + return NULL; + } + + /* The memory area is automatically mem-locked by vcsm's fault + * handler when it is next used. So leave it unlocked until it + * is needed. + */ + vcsm_unlock_hdl(vcsm_handle); + + payload_elem->mem = mem; + payload_elem->handle = (void *)vcsm_handle; + payload_elem->vc_handle = (void *)vc_handle; +#else /* ENABLE_MMAL_VCSM */ + MMAL_PARAM_UNUSED(size); + mmal_vc_payload_list_release(payload_elem); +#endif /* ENABLE_MMAL_VCSM */ + + return mem; +} + +/** Free a shared memory buffer */ +MMAL_STATUS_T mmal_vc_shm_free(uint8_t *mem) +{ + MMAL_VC_PAYLOAD_ELEM_T *payload_elem = mmal_vc_payload_list_find_mem(mem); + if (payload_elem) + { +#ifdef ENABLE_MMAL_VCSM + vcsm_free((unsigned int)payload_elem->handle); +#endif /* ENABLE_MMAL_VCSM */ + mmal_vc_payload_list_release(payload_elem); + return MMAL_SUCCESS; + } + + return MMAL_EINVAL; +} + +/** Lock a shared memory buffer */ +uint8_t *mmal_vc_shm_lock(uint8_t *mem, uint32_t workaround) +{ + /* Zero copy stuff */ + MMAL_VC_PAYLOAD_ELEM_T *elem = mmal_vc_payload_list_find_handle(mem); + MMAL_PARAM_UNUSED(workaround); + + if (elem) + mem = elem->mem; + + return mem; +} + +/** Unlock a shared memory buffer */ +uint8_t *mmal_vc_shm_unlock(uint8_t *mem, uint32_t *length, uint32_t workaround) +{ + /* Zero copy stuff */ + MMAL_VC_PAYLOAD_ELEM_T *elem = mmal_vc_payload_list_find_mem(mem); + MMAL_PARAM_UNUSED(workaround); + + if (elem) + { + *length = 0; + mem = (uint8_t *)elem->vc_handle; +#ifdef ENABLE_MMAL_VCSM + vcsm_unlock_ptr(elem->mem); +#endif /* ENABLE_MMAL_VCSM */ + } + + return mem; +} diff --git a/external_src/raspicam-0.1.3/dependencies/mmal/vc/mmal_vc_shm.h b/external_src/raspicam-0.1.3/dependencies/mmal/vc/mmal_vc_shm.h new file mode 100644 index 0000000..0aacb5b --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/mmal/vc/mmal_vc_shm.h @@ -0,0 +1,62 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 MMAL_VC_SHM_H +#define MMAL_VC_SHM_H + +/** @file + * + * Abstraction layer for MMAL VC shared memory. + * This API is only used by the MMAL VC component. + */ + +#include "mmal_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** Initialise the shared memory system */ +MMAL_STATUS_T mmal_vc_shm_init(void); + +/** Allocate a shared memory buffer */ +uint8_t *mmal_vc_shm_alloc(uint32_t size); + +/** Free a shared memory buffer */ +MMAL_STATUS_T mmal_vc_shm_free(uint8_t *mem); + +/** Lock a shared memory buffer */ +uint8_t *mmal_vc_shm_lock(uint8_t *mem, uint32_t workaround); + +/** Unlock a shared memory buffer */ +uint8_t *mmal_vc_shm_unlock(uint8_t *mem, uint32_t *length, uint32_t workaround); + + +#ifdef __cplusplus +} +#endif + +#endif /* MMAL_VC_SHM_H */ diff --git a/external_src/raspicam-0.1.3/dependencies/vcos/CMakeLists.txt b/external_src/raspicam-0.1.3/dependencies/vcos/CMakeLists.txt new file mode 100644 index 0000000..23a8d72 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/vcos/CMakeLists.txt @@ -0,0 +1,68 @@ +cmake_minimum_required (VERSION 2.8) + +get_filename_component (VIDEOCORE_ROOT "../.." ABSOLUTE) +include (${VIDEOCORE_ROOT}/makefiles/cmake/global_settings.cmake) + +set (HEADERS + vcos_assert.h + vcos_atomic_flags.h + vcos_blockpool.h + vcos_cmd.h + vcos_dlfcn.h + vcos_event_flags.h + vcos_event.h + vcos.h + vcos_init.h + vcos_inttypes.h + vcos_isr.h + vcos_legacy_isr.h + vcos_logging.h + vcos_logging_control.h + vcos_lowlevel_thread.h + vcos_mem.h + vcos_mempool.h + vcos_msgqueue.h + vcos_mutex.h + vcos_named_semaphore.h + vcos_once.h + vcos_queue.h + vcos_quickslow_mutex.h + vcos_reentrant_mutex.h + vcos_semaphore.h + vcos_stdint.h + vcos_string.h + vcos_thread_attr.h + vcos_thread.h + vcos_timer.h + vcos_tls.h + vcos_types.h +) + +foreach (header ${HEADERS}) + configure_file ("${header}" "${VCOS_HEADERS_BUILD_DIR}/${header}" COPYONLY) +endforeach () + +if (CMAKE_COMPILER_IS_GNUCC) + add_definitions (-ggdb -Werror -Wall) +endif () + +if (CMAKE_COMPILER_2005) + add_definitions (/WX /W4 /wd4127 /D_CRT_SECURE_NO_DEPRECATE) +endif () + +include_directories (${VIDEOCORE_ROOT} ${VCOS_HEADERS_BUILD_DIR}) + +add_subdirectory (${RTOS}) + +set(VCOS_EXCLUDE_TESTS TRUE) +if (NOT DEFINED VCOS_EXCLUDE_TESTS) +add_testapp_subdirectory (test) +endif (NOT DEFINED VCOS_EXCLUDE_TESTS) + +if (WIN32) + build_command (RELEASE_BUILD_CMD CONFIGURATION Release) + build_command (DEBUG_BUILD_CMD CONFIGURATION Debug) + configure_file (build_all.bat.in build_all.bat @ONLY) +endif () + +#install (FILES ${HEADERS} DESTINATION include/interface/vcos) diff --git a/external_src/raspicam-0.1.3/dependencies/vcos/generic/CMakeLists.txt b/external_src/raspicam-0.1.3/dependencies/vcos/generic/CMakeLists.txt new file mode 100644 index 0000000..c09f376 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/vcos/generic/CMakeLists.txt @@ -0,0 +1,21 @@ + +set (HEADERS + vcos_common.h + vcos_generic_blockpool.h + vcos_generic_event_flags.h + vcos_generic_named_sem.h + vcos_generic_quickslow_mutex.h + vcos_generic_reentrant_mtx.h + vcos_generic_tls.h + vcos_joinable_thread_from_plain.h + vcos_latch_from_sem.h + vcos_mem_from_malloc.h + vcos_mutexes_are_reentrant.h + vcos_thread_reaper.h +) + +foreach (header ${HEADERS}) + configure_file ("${header}" "${VCOS_HEADERS_BUILD_DIR}/generic/${header}" COPYONLY) +endforeach () + +install (FILES ${HEADERS} DESTINATION include/interface/vcos/generic) diff --git a/external_src/raspicam-0.1.3/dependencies/vcos/generic/vcos_abort.c b/external_src/raspicam-0.1.3/dependencies/vcos/generic/vcos_abort.c new file mode 100644 index 0000000..7da16ac --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/vcos/generic/vcos_abort.c @@ -0,0 +1,85 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 "interface/vcos/vcos.h" +#ifdef __VIDEOCORE__ +#include "host_support/include/vc_debug_sym.h" +#include "vcfw/vclib/vclib.h" +#endif +#include + + +int vcos_verify_bkpts = 0; +#ifdef __VIDEOCORE__ +VC_DEBUG_VAR(vcos_verify_bkpts); +#endif + +int vcos_verify_bkpts_enabled(void) +{ + return vcos_verify_bkpts; +} + +int vcos_verify_bkpts_enable(int enable) +{ + int old = vcos_verify_bkpts; + vcos_verify_bkpts = enable; + return old; +} + +/** + * Call the fatal error handler. + */ +void vcos_abort(void) +{ + VCOS_ALERT("vcos_abort: Halting"); + +#ifdef __VIDEOCORE__ + _bkpt(); +#endif + +#if defined(VCOS_HAVE_BACKTRACE) && !defined(NDEBUG) + vcos_backtrace_self(); +#endif + +#ifdef __VIDEOCORE__ + /* Flush the cache to help with postmortem RAM-dump debugging */ + vclib_cache_flush(); +#endif + +#ifdef PLATFORM_RASPBERRYPI + extern void pattern(int); + while(1) + pattern(8); +#endif + + /* Insert chosen fatal error handler here */ +#if defined __VIDEOCORE__ && !defined(NDEBUG) + while(1); /* allow us to attach a debugger after the fact and see where we came from. */ +#else + abort(); /* on vc this ends up in _exit_halt which doesn't give us any stack backtrace */ +#endif +} diff --git a/external_src/raspicam-0.1.3/dependencies/vcos/generic/vcos_cmd.c b/external_src/raspicam-0.1.3/dependencies/vcos/generic/vcos_cmd.c new file mode 100644 index 0000000..3dfbdb3 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/vcos/generic/vcos_cmd.c @@ -0,0 +1,722 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. +*/ + +/***************************************************************************** +* +* This file provides a generic command line interface which allows +* vcos internals to be manipulated and/or displayed. +* +*****************************************************************************/ + +/* ---- Include Files ---------------------------------------------------- */ + +#include "interface/vcos/vcos.h" + +#ifdef HAVE_VCOS_VERSION +#include "interface/vcos/vcos_build_info.h" +#endif + +#ifdef _VIDEOCORE +#include "vcfw/logging/logging.h" +#endif + +/* ---- Public Variables ------------------------------------------------- */ + +/* ---- Private Constants and Types -------------------------------------- */ + +#define VCOS_LOG_CATEGORY (&vcos_cmd_log_category) +VCOS_LOG_CAT_T vcos_cmd_log_category; + +/* ---- Private Variables ------------------------------------------------ */ + +static struct VCOS_CMD_GLOBALS_T +{ + VCOS_MUTEX_T lock; + VCOS_ONCE_T initialized; + + unsigned num_cmd_entries; + unsigned num_cmd_alloc; + VCOS_CMD_T *cmd_entry; + + VCOS_LOG_CAT_T *log_category; +} cmd_globals; + +#ifdef HAVE_VCOS_VERSION +/* Keep the static strings in the image from being dropped by + * the linker. + */ +extern const char *vcos_get_build_strings(unsigned id); +const char *(*vcos_keep_static_strings)(unsigned); +#endif + +/* ---- Private Function Prototypes -------------------------------------- */ + +static VCOS_STATUS_T help_cmd( VCOS_CMD_PARAM_T *param ); + +/* ---- Functions ------------------------------------------------------- */ + +/***************************************************************************** +* +* Walks through the commands looking for a particular command +* +*****************************************************************************/ + +static VCOS_CMD_T *find_cmd( VCOS_CMD_T *cmd_entry, const char *name ) +{ + VCOS_CMD_T *scan_entry = cmd_entry; + + while ( scan_entry->name != NULL ) + { + if ( vcos_strcmp( scan_entry->name, name ) == 0 ) + { + return scan_entry; + } + scan_entry++; + } + + return NULL; +} + +/***************************************************************************** +* +* Saves away +* each line individually. +* +*****************************************************************************/ + +void vcos_cmd_always_log_output( VCOS_LOG_CAT_T *log_category ) +{ + cmd_globals.log_category = log_category; +} + +/***************************************************************************** +* +* Walks through a buffer containing newline separated lines, and logs +* each line individually. +* +*****************************************************************************/ + +static void cmd_log_results( VCOS_CMD_PARAM_T *param ) +{ + char *start; + char *end; + + start = end = param->result_buf; + + while ( *start != '\0' ) + { + while (( *end != '\0' ) && ( *end != '\n' )) + end++; + + if ( *end == '\n' ) + { + *end++ = '\0'; + } + + if ( cmd_globals.log_category != NULL ) + { + if ( vcos_is_log_enabled( cmd_globals.log_category, VCOS_LOG_INFO )) + { + vcos_log_impl( cmd_globals.log_category, VCOS_LOG_INFO, "%s", start ); + } + } + else + { + vcos_log_info( "%s", start ); + } + + start = end; + } + + /* Since we logged the buffer, reset the pointer back to the beginning. */ + + param->result_ptr = param->result_buf; + param->result_buf[0] = '\0'; +} + +/***************************************************************************** +* +* Since we may have limited output space, we create a generic routine +* which tries to use the result space, but will switch over to using +* logging if the output is too large. +* +*****************************************************************************/ + +void vcos_cmd_vprintf( VCOS_CMD_PARAM_T *param, const char *fmt, va_list args ) +{ + int bytes_written; + int bytes_remaining; + + bytes_remaining = (int)(param->result_size - ( param->result_ptr - param->result_buf )); + + bytes_written = vcos_vsnprintf( param->result_ptr, bytes_remaining, fmt, args ); + + if ( cmd_globals.log_category != NULL ) + { + /* We're going to log each line as we encounter it. If the buffer + * doesn't end in a newline, then we'll wait for one first. + */ + + if ( (( bytes_written + 1 ) >= bytes_remaining ) + || ( param->result_ptr[ bytes_written - 1 ] == '\n' )) + { + cmd_log_results( param ); + } + else + { + param->result_ptr += bytes_written; + } + } + else + { + if (( bytes_written + 1 ) >= bytes_remaining ) + { + /* Output doesn't fit - switch over to logging */ + + param->use_log = 1; + + *param->result_ptr = '\0'; /* Zap the partial line that didn't fit above. */ + + cmd_log_results( param ); /* resets result_ptr */ + + bytes_written = vcos_vsnprintf( param->result_ptr, bytes_remaining, fmt, args ); + } + param->result_ptr += bytes_written; + } +} + +/***************************************************************************** +* +* Prints the output. +* +*****************************************************************************/ + +void vcos_cmd_printf( VCOS_CMD_PARAM_T *param, const char *fmt, ... ) +{ + va_list args; + + va_start( args, fmt ); + vcos_cmd_vprintf( param, fmt, args ); + va_end( args ); +} + +/***************************************************************************** +* +* Prints the arguments which were on the command line prior to ours. +* +*****************************************************************************/ + +static void print_argument_prefix( VCOS_CMD_PARAM_T *param ) +{ + int arg_idx; + + for ( arg_idx = 0; ¶m->argv_orig[arg_idx] != param->argv; arg_idx++ ) + { + vcos_cmd_printf( param, "%s ", param->argv_orig[arg_idx] ); + } +} + +/***************************************************************************** +* +* Prints an error message, prefixed by the command chain required to get +* to where we're at. +* +*****************************************************************************/ + +void vcos_cmd_error( VCOS_CMD_PARAM_T *param, const char *fmt, ... ) +{ + va_list args; + + print_argument_prefix( param ); + + va_start( args, fmt ); + vcos_cmd_vprintf( param, fmt, args ); + va_end( args ); + vcos_cmd_printf( param, "\n" ); +} + +/**************************************************************************** +* +* usage - prints command usage for an array of commands. +* +***************************************************************************/ + +static void usage( VCOS_CMD_PARAM_T *param, VCOS_CMD_T *cmd_entry ) +{ + int cmd_idx; + int nameWidth = 0; + int argsWidth = 0; + VCOS_CMD_T *scan_entry; + + vcos_cmd_printf( param, "Usage: " ); + print_argument_prefix( param ); + vcos_cmd_printf( param, "command [args ...]\n" ); + vcos_cmd_printf( param, "\n" ); + vcos_cmd_printf( param, "Where command is one of the following:\n" ); + + for ( cmd_idx = 0; cmd_entry[cmd_idx].name != NULL; cmd_idx++ ) + { + int aw; + int nw; + + scan_entry = &cmd_entry[cmd_idx]; + + nw = vcos_strlen( scan_entry->name ); + aw = vcos_strlen( scan_entry->args ); + + if ( nw > nameWidth ) + { + nameWidth = nw; + } + if ( aw > argsWidth ) + { + argsWidth = aw; + } + } + + for ( cmd_idx = 0; cmd_entry[cmd_idx].name != NULL; cmd_idx++ ) + { + scan_entry = &cmd_entry[cmd_idx]; + + vcos_cmd_printf( param, " %-*s %-*s - %s\n", + nameWidth, scan_entry->name, + argsWidth, scan_entry->args, + scan_entry->descr ); + } +} + +/**************************************************************************** +* +* Prints the usage for the current command. +* +***************************************************************************/ + +void vcos_cmd_usage( VCOS_CMD_PARAM_T *param ) +{ + VCOS_CMD_T *cmd_entry; + + cmd_entry = param->cmd_entry; + + if ( cmd_entry->sub_cmd_entry != NULL ) + { + /* This command is command with sub-commands */ + + usage( param, param->cmd_entry->sub_cmd_entry ); + } + else + { + vcos_cmd_printf( param, "Usage: " ); + print_argument_prefix( param ); + vcos_cmd_printf( param, "%s %s - %s\n", + param->argv[0], + param->cmd_entry->args, + param->cmd_entry->descr ); + } +} + +/***************************************************************************** +* +* Command to print out the help +* +* This help command is only called from the main menu. +* +*****************************************************************************/ + +static VCOS_STATUS_T help_cmd( VCOS_CMD_PARAM_T *param ) +{ + VCOS_CMD_T *found_entry; + +#if 0 + { + int arg_idx; + + vcos_log_trace( "%s: argc = %d", __func__, param->argc ); + for ( arg_idx = 0; arg_idx < param->argc; arg_idx++ ) + { + vcos_log_trace( "%s: argv[%d] = '%s'", __func__, arg_idx, param->argv[arg_idx] ); + } + } +#endif + + /* If there is an argument after the word help, then we want to print + * help for that command. + */ + + if ( param->argc == 1 ) + { + if ( param->cmd_parent_entry == cmd_globals.cmd_entry ) + { + /* Bare help - print the command usage for the root */ + + usage( param, cmd_globals.cmd_entry ); + return VCOS_SUCCESS; + } + + /* For all other cases help requires an argument */ + + vcos_cmd_error( param, "%s requires an argument", param->argv[0] ); + return VCOS_EINVAL; + } + + /* We were given an argument. */ + + if (( found_entry = find_cmd( param->cmd_parent_entry, param->argv[1] )) != NULL ) + { + /* Make it look like the command that was specified is the one that's + * currently running + */ + + param->cmd_entry = found_entry; + param->argv[0] = param->argv[1]; + param->argv++; + param->argc--; + + vcos_cmd_usage( param ); + return VCOS_SUCCESS; + } + + vcos_cmd_error( param, "- unrecognized command: '%s'", param->argv[1] ); + return VCOS_ENOENT; +} + +/***************************************************************************** +* +* Command to print out the version/build information. +* +*****************************************************************************/ + +#ifdef HAVE_VCOS_VERSION + +static VCOS_STATUS_T version_cmd( VCOS_CMD_PARAM_T *param ) +{ + static const char* copyright = "Copyright (c) 2011 Broadcom"; + + vcos_cmd_printf( param, "%s %s\n%s\nversion %s\nhost %s", + vcos_get_build_date(), + vcos_get_build_time(), + copyright, + vcos_get_build_version(), + vcos_get_build_hostname() ); + + return VCOS_SUCCESS; +} + +#endif + +/***************************************************************************** +* +* Internal commands +* +*****************************************************************************/ + +static VCOS_CMD_T cmd_help = { "help", "[command]", help_cmd, NULL, "Prints command help information" }; + +#ifdef HAVE_VCOS_VERSION +static VCOS_CMD_T cmd_version = { "version", "", version_cmd, NULL, "Prints build/version information" }; +#endif + +/***************************************************************************** +* +* Walks the command table and executes the commands +* +*****************************************************************************/ + +static VCOS_STATUS_T execute_cmd( VCOS_CMD_PARAM_T *param, VCOS_CMD_T *cmd_entry ) +{ + const char *cmdStr; + VCOS_CMD_T *found_entry; + +#if 0 + { + int arg_idx; + + vcos_cmd_printf( param, "%s: argc = %d", __func__, param->argc ); + for ( arg_idx = 0; arg_idx < param->argc; arg_idx++ ) + { + vcos_cmd_printf( param, " argv[%d] = '%s'", arg_idx, param->argv[arg_idx] ); + } + vcos_cmd_printf( param, "\n" ); + } +#endif + + if ( param->argc <= 1 ) + { + /* No command specified */ + + vcos_cmd_error( param, "%s - no command specified", param->argv[0] ); + return VCOS_EINVAL; + } + + /* argv[0] is the command/program that caused us to get invoked, so we strip + * it off. + */ + + param->argc--; + param->argv++; + param->cmd_parent_entry = cmd_entry; + + /* Not the help command, scan for the command and execute it. */ + + cmdStr = param->argv[0]; + + if (( found_entry = find_cmd( cmd_entry, cmdStr )) != NULL ) + { + if ( found_entry->sub_cmd_entry != NULL ) + { + return execute_cmd( param, found_entry->sub_cmd_entry ); + } + + param->cmd_entry = found_entry; + return found_entry->cmd_fn( param ); + } + + /* Unrecognized command - check to see if it was the help command */ + + if ( vcos_strcmp( cmdStr, cmd_help.name ) == 0 ) + { + return help_cmd( param ); + } + + vcos_cmd_error( param, "- unrecognized command: '%s'", cmdStr ); + return VCOS_ENOENT; +} + +/***************************************************************************** +* +* Initializes the command line parser. +* +*****************************************************************************/ + +static void vcos_cmd_init( void ) +{ + vcos_mutex_create( &cmd_globals.lock, "vcos_cmd" ); + + cmd_globals.num_cmd_entries = 0; + cmd_globals.num_cmd_alloc = 0; + cmd_globals.cmd_entry = NULL; + +#ifdef HAVE_VCOS_VERSION + vcos_keep_static_strings = vcos_get_build_strings; +#endif +} + +/***************************************************************************** +* +* Shuts down the command line parser. +* +*****************************************************************************/ + +void vcos_cmd_shutdown( void ) +{ + vcos_mutex_delete( &cmd_globals.lock ); + + vcos_free( cmd_globals.cmd_entry ); + cmd_globals.cmd_entry = NULL; +} + +/***************************************************************************** +* +* Command line processor. +* +*****************************************************************************/ + +VCOS_STATUS_T vcos_cmd_execute( int argc, char **argv, size_t result_size, char *result_buf ) +{ + VCOS_STATUS_T rc = VCOS_EINVAL; + VCOS_CMD_PARAM_T param; + + vcos_once( &cmd_globals.initialized, vcos_cmd_init ); + + param.argc = argc; + param.argv = param.argv_orig = argv; + + param.use_log = 0; + param.result_size = result_size; + param.result_ptr = result_buf; + param.result_buf = result_buf; + + result_buf[0] = '\0'; + + vcos_mutex_lock( &cmd_globals.lock ); + + rc = execute_cmd( ¶m, cmd_globals.cmd_entry ); + + if ( param.use_log ) + { + cmd_log_results( ¶m ); + vcos_snprintf( result_buf, result_size, "results logged" ); + } + else + if ( cmd_globals.log_category != NULL ) + { + if ( result_buf[0] != '\0' ) + { + /* There is a partial line still buffered. */ + + vcos_cmd_printf( ¶m, "\n" ); + } + } + + vcos_mutex_unlock( &cmd_globals.lock ); + + return rc; +} + +/***************************************************************************** +* +* Registers a command entry with the command line processor +* +*****************************************************************************/ + +VCOS_STATUS_T vcos_cmd_register( VCOS_CMD_T *cmd_entry ) +{ + VCOS_STATUS_T rc; + VCOS_UNSIGNED new_num_cmd_alloc; + VCOS_CMD_T *new_cmd_entry; + VCOS_CMD_T *old_cmd_entry; + VCOS_CMD_T *scan_entry; + + vcos_once( &cmd_globals.initialized, vcos_cmd_init ); + + vcos_assert( cmd_entry != NULL ); + vcos_assert( cmd_entry->name != NULL ); + + vcos_log_trace( "%s: cmd '%s'", __FUNCTION__, cmd_entry->name ); + + vcos_assert( cmd_entry->args != NULL ); + vcos_assert(( cmd_entry->cmd_fn != NULL ) || ( cmd_entry->sub_cmd_entry != NULL )); + vcos_assert( cmd_entry->descr != NULL ); + + /* We expect vcos_cmd_init to be called before vcos_logging_init, so we + * need to defer registering our logging category until someplace + * like right here. + */ + + if ( vcos_cmd_log_category.name == NULL ) + { + /* + * If you're using the command interface, you pretty much always want + * log messages from this file to show up. So we change the default + * from ERROR to be the more reasonable INFO level. + */ + + vcos_log_set_level(&vcos_cmd_log_category, VCOS_LOG_INFO); + vcos_log_register("vcos_cmd", &vcos_cmd_log_category); + + /* We register a help command so that it shows up in the usage. */ + + vcos_cmd_register( &cmd_help ); +#ifdef HAVE_VCOS_VERSION + vcos_cmd_register( &cmd_version ); +#endif + } + + vcos_mutex_lock( &cmd_globals.lock ); + + if ( cmd_globals.num_cmd_entries >= cmd_globals.num_cmd_alloc ) + { + if ( cmd_globals.num_cmd_alloc == 0 ) + { + /* We haven't allocated a table yet */ + } + + /* The number 8 is rather arbitrary. */ + + new_num_cmd_alloc = cmd_globals.num_cmd_alloc + 8; + + /* The + 1 is to ensure that we always have a NULL entry at the end. */ + + new_cmd_entry = (VCOS_CMD_T *)vcos_calloc( new_num_cmd_alloc + 1, sizeof( *cmd_entry ), "vcos_cmd_entries" ); + if ( new_cmd_entry == NULL ) + { + rc = VCOS_ENOMEM; + goto out; + } + memcpy( new_cmd_entry, cmd_globals.cmd_entry, cmd_globals.num_cmd_entries * sizeof( *cmd_entry )); + cmd_globals.num_cmd_alloc = new_num_cmd_alloc; + old_cmd_entry = cmd_globals.cmd_entry; + cmd_globals.cmd_entry = new_cmd_entry; + vcos_free( old_cmd_entry ); + } + + if ( cmd_globals.num_cmd_entries == 0 ) + { + /* This is the first command being registered */ + + cmd_globals.cmd_entry[0] = *cmd_entry; + } + else + { + /* Keep the list in alphabetical order. We start at the end and work backwards + * shuffling entries up one until we find an insertion point. + */ + + for ( scan_entry = &cmd_globals.cmd_entry[cmd_globals.num_cmd_entries - 1]; + scan_entry >= cmd_globals.cmd_entry; scan_entry-- ) + { + if ( vcos_strcmp( cmd_entry->name, scan_entry->name ) > 0 ) + { + /* We found an insertion point. */ + + break; + } + + scan_entry[1] = scan_entry[0]; + } + scan_entry[1] = *cmd_entry; + } + cmd_globals.num_cmd_entries++; + + rc = VCOS_SUCCESS; + +out: + + vcos_mutex_unlock( &cmd_globals.lock ); + return rc; +} + +/***************************************************************************** +* +* Registers multiple commands. +* +*****************************************************************************/ + +VCOS_STATUS_T vcos_cmd_register_multiple( VCOS_CMD_T *cmd_entry ) +{ + VCOS_STATUS_T status; + + while ( cmd_entry->name != NULL ) + { + if (( status = vcos_cmd_register( cmd_entry )) != VCOS_SUCCESS ) + { + return status; + } + cmd_entry++; + } + return VCOS_SUCCESS; +} + diff --git a/external_src/raspicam-0.1.3/dependencies/vcos/generic/vcos_common.h b/external_src/raspicam-0.1.3/dependencies/vcos/generic/vcos_common.h new file mode 100644 index 0000000..93949e0 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/vcos/generic/vcos_common.h @@ -0,0 +1,96 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. +*/ + +/*============================================================================= +VideoCore OS Abstraction Layer - common postamble code +=============================================================================*/ + +/** \file + * + * Postamble code included by the platform-specific header files + */ + +#define VCOS_THREAD_PRI_DEFAULT VCOS_THREAD_PRI_NORMAL + +#if !defined(VCOS_THREAD_PRI_INCREASE) +#error Which way to thread priorities go? +#endif + +#if VCOS_THREAD_PRI_INCREASE < 0 +/* smaller numbers are higher priority */ +#define VCOS_THREAD_PRI_LESS(x) ((x)VCOS_THREAD_PRI_MIN?(x)-1:VCOS_THREAD_PRI_MIN) +#else +/* bigger numbers are lower priority */ +#define VCOS_THREAD_PRI_MORE(x) ((x)VCOS_THREAD_PRI_MIN?(x)-1:VCOS_THREAD_PRI_MIN) +#endif + +/* Convenience for Brits: */ +#define VCOS_APPLICATION_INITIALISE VCOS_APPLICATION_INITIALIZE + +/* + * Check for constant definitions + */ +#ifndef VCOS_TICKS_PER_SECOND +#error VCOS_TICKS_PER_SECOND not defined +#endif + +#if !defined(VCOS_THREAD_PRI_MIN) || !defined(VCOS_THREAD_PRI_MAX) +#error Priority range not defined +#endif + +#if !defined(VCOS_THREAD_PRI_HIGHEST) || !defined(VCOS_THREAD_PRI_LOWEST) || !defined(VCOS_THREAD_PRI_NORMAL) +#error Priority ordering not defined +#endif + +#if !defined(VCOS_CAN_SET_STACK_ADDR) +#error Can stack addresses be set on this platform? Please set this macro to either 0 or 1. +#endif + +#if (_VCOS_AFFINITY_CPU0|_VCOS_AFFINITY_CPU1) & (~_VCOS_AFFINITY_MASK) +#error _VCOS_AFFINITY_CPUxxx values are not consistent with _VCOS_AFFINITY_MASK +#endif + +/** Append to the end of a singly-linked queue, O(1). Works with + * any structure where list has members 'head' and 'tail' and + * item has a 'next' pointer. + */ +#define VCOS_QUEUE_APPEND_TAIL(list, item) {\ + (item)->next = NULL;\ + if (!(list)->head) {\ + (list)->head = (list)->tail = (item); \ + } else {\ + (list)->tail->next = (item); \ + (list)->tail = (item); \ + } \ +} + +#ifndef VCOS_HAVE_TIMER +VCOSPRE_ void VCOSPOST_ vcos_timer_init(void); +#endif + diff --git a/external_src/raspicam-0.1.3/dependencies/vcos/generic/vcos_deprecated.h b/external_src/raspicam-0.1.3/dependencies/vcos/generic/vcos_deprecated.h new file mode 100644 index 0000000..0efa5c4 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/vcos/generic/vcos_deprecated.h @@ -0,0 +1,36 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. +*/ + +/* +The symbol vcos_deprecated_code may be defined at most once, by the inclusion of "vcos_deprecated.h" in vcos_init.c. +Any other inclusions of this header will cause the linker to warn about multiple definitions of vcos_deprecated_code, for example: + [ldvc] (Warning) "vcos_deprecated_code" is multiply defined in libs/vcos_threadx/vcos_init.c.o and libs/xxxxx/xxxxx.c.o +If you see a build message like this then the configuration you are building is using deprecated code. +Contact the person named in the accompanying comment for advice - do not remove the inclusion. +*/ + +int vcos_deprecated_code; diff --git a/external_src/raspicam-0.1.3/dependencies/vcos/generic/vcos_generic_blockpool.c b/external_src/raspicam-0.1.3/dependencies/vcos/generic/vcos_generic_blockpool.c new file mode 100644 index 0000000..f4241a6 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/vcos/generic/vcos_generic_blockpool.c @@ -0,0 +1,568 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. +*/ + +#define VCOS_LOG_CATEGORY (&vcos_blockpool_log) + +#include +#include +#include "interface/vcos/vcos.h" +#include "interface/vcos/generic/vcos_generic_blockpool.h" + +#define VCOS_BLOCKPOOL_FOURCC(a,b,c,d) ((a) | (b << 8) | (c << 16) | (d << 24)) +#define VCOS_BLOCKPOOL_MAGIC VCOS_BLOCKPOOL_FOURCC('v', 'b', 'p', 'l') +#define VCOS_BLOCKPOOL_SUBPOOL_MAGIC VCOS_BLOCKPOOL_FOURCC('v', 's', 'p', 'l') + +#define VCOS_BLOCKPOOL_SUBPOOL_FLAG_NONE (0) +#define VCOS_BLOCKPOOL_SUBPOOL_FLAG_OWNS_MEM (1 << 0) +#define VCOS_BLOCKPOOL_SUBPOOL_FLAG_EXTENSION (1 << 1) + +/* Uncomment to enable really verbose debug messages */ +/* #define VCOS_BLOCKPOOL_DEBUGGING */ +/* Whether to overwrite freed blocks with 0xBD */ +#ifdef VCOS_BLOCKPOOL_DEBUGGING +#define VCOS_BLOCKPOOL_OVERWRITE_ON_FREE 1 +#define VCOS_BLOCKPOOL_DEBUG_MEMSET_MAX_SIZE (UINT32_MAX) +#else +#define VCOS_BLOCKPOOL_OVERWRITE_ON_FREE 0 +#define VCOS_BLOCKPOOL_DEBUG_MEMSET_MAX_SIZE (2 * 1024 * 1024) +#endif + +#ifdef VCOS_BLOCKPOOL_DEBUGGING +#define VCOS_BLOCKPOOL_ASSERT vcos_demand +#define VCOS_BLOCKPOOL_TRACE_LEVEL VCOS_LOG_TRACE +#define VCOS_BLOCKPOOL_DEBUG_LOG(s, ...) vcos_log_trace("%s: " s, VCOS_FUNCTION, __VA_ARGS__) +#undef VCOS_BLOCKPOOL_OVERWRITE_ON_FREE +#define VCOS_BLOCKPOOL_OVERWRITE_ON_FREE 1 +#else +#define VCOS_BLOCKPOOL_ASSERT vcos_demand +#define VCOS_BLOCKPOOL_TRACE_LEVEL VCOS_LOG_ERROR +#define VCOS_BLOCKPOOL_DEBUG_LOG(s, ...) +#endif + +#define ASSERT_POOL(p) \ + VCOS_BLOCKPOOL_ASSERT((p) && (p)->magic == VCOS_BLOCKPOOL_MAGIC); + +#define ASSERT_SUBPOOL(p) \ + VCOS_BLOCKPOOL_ASSERT((p) && (p)->magic == VCOS_BLOCKPOOL_SUBPOOL_MAGIC && \ + p->start >= p->mem); + +#if defined(VCOS_LOGGING_ENABLED) +static VCOS_LOG_CAT_T vcos_blockpool_log = +VCOS_LOG_INIT("vcos_blockpool", VCOS_BLOCKPOOL_TRACE_LEVEL); +#endif + +static void vcos_generic_blockpool_subpool_init( + VCOS_BLOCKPOOL_T *pool, VCOS_BLOCKPOOL_SUBPOOL_T *subpool, + void *mem, size_t pool_size, VCOS_UNSIGNED num_blocks, int align, + uint32_t flags) +{ + VCOS_BLOCKPOOL_HEADER_T *block; + VCOS_BLOCKPOOL_HEADER_T *end; + + vcos_unused(flags); + + vcos_log_trace( + "%s: pool %p subpool %p mem %p pool_size %d " \ + "num_blocks %d align %d flags %x", + VCOS_FUNCTION, + pool, subpool, mem, (uint32_t) pool_size, + num_blocks, align, flags); + + subpool->magic = VCOS_BLOCKPOOL_SUBPOOL_MAGIC; + subpool->mem = mem; + + /* The block data pointers must be aligned according to align and the + * block header pre-preceeds the first block data. + * For large alignments there may be wasted space between subpool->mem + * and the first block header. + */ + subpool->start = (char *) subpool->mem + sizeof(VCOS_BLOCKPOOL_HEADER_T); + subpool->start = (void*) + VCOS_BLOCKPOOL_ROUND_UP((unsigned long) subpool->start, align); + subpool->start = (char *) subpool->start - sizeof(VCOS_BLOCKPOOL_HEADER_T); + + vcos_assert(subpool->start >= subpool->mem); + + vcos_log_trace("%s: mem %p subpool->start %p" \ + " pool->block_size %d pool->block_data_size %d", + VCOS_FUNCTION, mem, subpool->start, + (int) pool->block_size, (int) pool->block_data_size); + + subpool->num_blocks = num_blocks; + subpool->available_blocks = num_blocks; + subpool->free_list = NULL; + subpool->owner = pool; + + /* Initialise to a predictable bit pattern unless the pool is so big + * that the delay would be noticable. */ + if (pool_size < VCOS_BLOCKPOOL_DEBUG_MEMSET_MAX_SIZE) + memset(subpool->mem, 0xBC, pool_size); /* For debugging */ + + block = (VCOS_BLOCKPOOL_HEADER_T*) subpool->start; + end = (VCOS_BLOCKPOOL_HEADER_T*) + ((char *) subpool->start + (pool->block_size * num_blocks)); + subpool->end = end; + + /* Initialise the free list for this subpool */ + while (block < end) + { + block->owner.next = subpool->free_list; + subpool->free_list = block; + block = (VCOS_BLOCKPOOL_HEADER_T*)((char*) block + pool->block_size); + } + +} + +VCOS_STATUS_T vcos_generic_blockpool_init(VCOS_BLOCKPOOL_T *pool, + VCOS_UNSIGNED num_blocks, VCOS_UNSIGNED block_size, + void *start, VCOS_UNSIGNED pool_size, VCOS_UNSIGNED align, + VCOS_UNSIGNED flags, const char *name) +{ + VCOS_STATUS_T status = VCOS_SUCCESS; + + vcos_unused(name); + vcos_unused(flags); + + vcos_log_trace( + "%s: pool %p num_blocks %d block_size %d start %p pool_size %d name %p", + VCOS_FUNCTION, pool, num_blocks, block_size, start, pool_size, name); + + vcos_demand(pool); + vcos_demand(start); + vcos_assert((block_size > 0)); + vcos_assert(num_blocks > 0); + + if (! align) + align = VCOS_BLOCKPOOL_ALIGN_DEFAULT; + + if (align & 0x3) + { + vcos_log_error("%s: invalid alignment %d", VCOS_FUNCTION, align); + return VCOS_EINVAL; + } + + if (VCOS_BLOCKPOOL_SIZE(num_blocks, block_size, align) > pool_size) + { + vcos_log_error("%s: Pool is too small" \ + " num_blocks %d block_size %d align %d" + " pool_size %d required size %d", VCOS_FUNCTION, + num_blocks, block_size, align, + pool_size, (int) VCOS_BLOCKPOOL_SIZE(num_blocks, block_size, align)); + return VCOS_ENOMEM; + } + + status = vcos_mutex_create(&pool->mutex, "vcos blockpool mutex"); + if (status != VCOS_SUCCESS) + return status; + + pool->block_data_size = block_size; + + /* TODO - create flag that if set forces the header to be in its own cache + * line */ + pool->block_size = VCOS_BLOCKPOOL_ROUND_UP(pool->block_data_size + + (align >= 4096 ? 32 : 0) + + sizeof(VCOS_BLOCKPOOL_HEADER_T), align); + + pool->magic = VCOS_BLOCKPOOL_MAGIC; + pool->num_subpools = 1; + pool->num_extension_blocks = 0; + pool->align = align; + memset(pool->subpools, 0, sizeof(pool->subpools)); + + vcos_generic_blockpool_subpool_init(pool, &pool->subpools[0], start, + pool_size, num_blocks, align, VCOS_BLOCKPOOL_SUBPOOL_FLAG_NONE); + + return status; +} + +VCOS_STATUS_T vcos_generic_blockpool_create_on_heap(VCOS_BLOCKPOOL_T *pool, + VCOS_UNSIGNED num_blocks, VCOS_UNSIGNED block_size, VCOS_UNSIGNED align, + VCOS_UNSIGNED flags, const char *name) +{ + VCOS_STATUS_T status = VCOS_SUCCESS; + size_t size = VCOS_BLOCKPOOL_SIZE(num_blocks, block_size, align); + void* mem = vcos_malloc(size, name); + + vcos_log_trace("%s: num_blocks %d block_size %d name %s", + VCOS_FUNCTION, num_blocks, block_size, name); + + if (! mem) + return VCOS_ENOMEM; + + status = vcos_generic_blockpool_init(pool, num_blocks, + block_size, mem, size, align, flags, name); + + if (status != VCOS_SUCCESS) + goto fail; + + pool->subpools[0].flags |= VCOS_BLOCKPOOL_SUBPOOL_FLAG_OWNS_MEM; + return status; + +fail: + free(mem); + return status; +} + +VCOS_STATUS_T vcos_generic_blockpool_extend(VCOS_BLOCKPOOL_T *pool, + VCOS_UNSIGNED num_extensions, VCOS_UNSIGNED num_blocks) +{ + VCOS_UNSIGNED i; + ASSERT_POOL(pool); + + vcos_log_trace("%s: pool %p num_extensions %d num_blocks %d", + VCOS_FUNCTION, pool, num_extensions, num_blocks); + + /* Extend may only be called once */ + if (pool->num_subpools > 1) + return VCOS_EACCESS; + + if (num_extensions < 1 || + num_extensions > VCOS_BLOCKPOOL_MAX_SUBPOOLS - 1) + return VCOS_EINVAL; + + if (num_blocks < 1) + return VCOS_EINVAL; + + pool->num_subpools += num_extensions; + pool->num_extension_blocks = num_blocks; + + /* Mark these subpools as valid but unallocated */ + for (i = 1; i < pool->num_subpools; ++i) + { + pool->subpools[i].magic = VCOS_BLOCKPOOL_SUBPOOL_MAGIC; + pool->subpools[i].start = NULL; + pool->subpools[i].mem = NULL; + } + + return VCOS_SUCCESS; +} + +void *vcos_generic_blockpool_alloc(VCOS_BLOCKPOOL_T *pool) +{ + VCOS_UNSIGNED i; + void* ret = NULL; + VCOS_BLOCKPOOL_SUBPOOL_T *subpool = NULL; + + ASSERT_POOL(pool); + vcos_mutex_lock(&pool->mutex); + + /* Starting with the main pool try and find a free block */ + for (i = 0; i < pool->num_subpools; ++i) + { + if (pool->subpools[i].start && pool->subpools[i].available_blocks > 0) + { + subpool = &pool->subpools[i]; + break; /* Found a subpool with free blocks */ + } + } + + if (! subpool) + { + /* All current subpools are full, try to allocate a new one */ + for (i = 1; i < pool->num_subpools; ++i) + { + if (! pool->subpools[i].start) + { + VCOS_BLOCKPOOL_SUBPOOL_T *s = &pool->subpools[i]; + size_t size = VCOS_BLOCKPOOL_SIZE(pool->num_extension_blocks, + pool->block_data_size, pool->align); + void *mem = vcos_malloc(size, pool->name); + if (mem) + { + vcos_log_trace("%s: Allocated subpool %d", VCOS_FUNCTION, i); + vcos_generic_blockpool_subpool_init(pool, s, mem, size, + pool->num_extension_blocks, + pool->align, + VCOS_BLOCKPOOL_SUBPOOL_FLAG_OWNS_MEM | + VCOS_BLOCKPOOL_SUBPOOL_FLAG_EXTENSION); + subpool = s; + break; /* Created a subpool */ + } + else + { + vcos_log_warn("%s: Failed to allocate subpool", VCOS_FUNCTION); + } + } + } + } + + if (subpool) + { + /* Remove from free list */ + VCOS_BLOCKPOOL_HEADER_T* nb = subpool->free_list; + + vcos_assert(subpool->free_list); + subpool->free_list = nb->owner.next; + + /* Owner is pool so free can be called without passing pool + * as a parameter */ + nb->owner.subpool = subpool; + + ret = nb + 1; /* Return pointer to block data */ + --(subpool->available_blocks); + } + vcos_mutex_unlock(&pool->mutex); + VCOS_BLOCKPOOL_DEBUG_LOG("pool %p subpool %p ret %p", pool, subpool, ret); + + if (ret) + { + vcos_assert(ret > subpool->start); + vcos_assert(ret < subpool->end); + } + return ret; +} + +void *vcos_generic_blockpool_calloc(VCOS_BLOCKPOOL_T *pool) +{ + void* ret = vcos_generic_blockpool_alloc(pool); + if (ret) + memset(ret, 0, pool->block_data_size); + return ret; +} + +void vcos_generic_blockpool_free(void *block) +{ + VCOS_BLOCKPOOL_DEBUG_LOG("block %p", block); + if (block) + { + VCOS_BLOCKPOOL_HEADER_T* hdr = (VCOS_BLOCKPOOL_HEADER_T*) block - 1; + VCOS_BLOCKPOOL_SUBPOOL_T *subpool = hdr->owner.subpool; + VCOS_BLOCKPOOL_T *pool = NULL; + + ASSERT_SUBPOOL(subpool); + pool = subpool->owner; + ASSERT_POOL(pool); + + vcos_mutex_lock(&pool->mutex); + vcos_assert((unsigned) subpool->available_blocks < subpool->num_blocks); + + /* Change ownership of block to be the free list */ + hdr->owner.next = subpool->free_list; + subpool->free_list = hdr; + ++(subpool->available_blocks); + + if (VCOS_BLOCKPOOL_OVERWRITE_ON_FREE) + memset(block, 0xBD, pool->block_data_size); /* For debugging */ + + if ( (subpool->flags & VCOS_BLOCKPOOL_SUBPOOL_FLAG_EXTENSION) && + subpool->available_blocks == subpool->num_blocks) + { + VCOS_BLOCKPOOL_DEBUG_LOG("%s: freeing subpool %p mem %p", VCOS_FUNCTION, + subpool, subpool->mem); + /* Free the sub-pool if it was dynamically allocated */ + vcos_free(subpool->mem); + subpool->mem = NULL; + subpool->start = NULL; + } + vcos_mutex_unlock(&pool->mutex); + } +} + +VCOS_UNSIGNED vcos_generic_blockpool_available_count(VCOS_BLOCKPOOL_T *pool) +{ + VCOS_UNSIGNED ret = 0; + VCOS_UNSIGNED i; + + ASSERT_POOL(pool); + vcos_mutex_lock(&pool->mutex); + for (i = 0; i < pool->num_subpools; ++i) + { + VCOS_BLOCKPOOL_SUBPOOL_T *subpool = &pool->subpools[i]; + ASSERT_SUBPOOL(subpool); + + /* Assume the malloc of sub pool would succeed */ + if (subpool->start) + ret += subpool->available_blocks; + else + ret += pool->num_extension_blocks; + } + vcos_mutex_unlock(&pool->mutex); + return ret; +} + +VCOS_UNSIGNED vcos_generic_blockpool_used_count(VCOS_BLOCKPOOL_T *pool) +{ + VCOS_UNSIGNED ret = 0; + VCOS_UNSIGNED i; + + ASSERT_POOL(pool); + vcos_mutex_lock(&pool->mutex); + + for (i = 0; i < pool->num_subpools; ++i) + { + VCOS_BLOCKPOOL_SUBPOOL_T *subpool = &pool->subpools[i]; + ASSERT_SUBPOOL(subpool); + if (subpool->start) + ret += (subpool->num_blocks - subpool->available_blocks); + } + vcos_mutex_unlock(&pool->mutex); + return ret; +} + +void vcos_generic_blockpool_delete(VCOS_BLOCKPOOL_T *pool) +{ + vcos_log_trace("%s: pool %p", VCOS_FUNCTION, pool); + + if (pool) + { + VCOS_UNSIGNED i; + + ASSERT_POOL(pool); + for (i = 0; i < pool->num_subpools; ++i) + { + VCOS_BLOCKPOOL_SUBPOOL_T *subpool = &pool->subpools[i]; + ASSERT_SUBPOOL(subpool); + if (subpool->mem) + { + /* For debugging */ + memset(subpool->mem, + 0xBE, + VCOS_BLOCKPOOL_SIZE(subpool->num_blocks, + pool->block_data_size, pool->align)); + + if (subpool->flags & VCOS_BLOCKPOOL_SUBPOOL_FLAG_OWNS_MEM) + vcos_free(subpool->mem); + subpool->mem = NULL; + subpool->start = NULL; + } + } + vcos_mutex_delete(&pool->mutex); + memset(pool, 0xBE, sizeof(VCOS_BLOCKPOOL_T)); /* For debugging */ + } +} + +uint32_t vcos_generic_blockpool_elem_to_handle(void *block) +{ + uint32_t ret = -1; + uint32_t index = -1; + VCOS_BLOCKPOOL_HEADER_T *hdr = NULL; + VCOS_BLOCKPOOL_T *pool = NULL; + VCOS_BLOCKPOOL_SUBPOOL_T *subpool = NULL; + uint32_t subpool_id; + + vcos_assert(block); + hdr = (VCOS_BLOCKPOOL_HEADER_T*) block - 1; + subpool = hdr->owner.subpool; + ASSERT_SUBPOOL(subpool); + + pool = subpool->owner; + ASSERT_POOL(pool); + vcos_mutex_lock(&pool->mutex); + + /* The handle is the index into the array of blocks combined + * with the subpool id. + */ + index = ((size_t) hdr - (size_t) subpool->start) / pool->block_size; + vcos_assert(index < subpool->num_blocks); + + subpool_id = ((char*) subpool - (char*) &pool->subpools[0]) / + sizeof(VCOS_BLOCKPOOL_SUBPOOL_T); + + vcos_assert(subpool_id < VCOS_BLOCKPOOL_MAX_SUBPOOLS); + vcos_assert(subpool_id < pool->num_subpools); + ret = VCOS_BLOCKPOOL_HANDLE_CREATE(index, subpool_id); + + vcos_log_trace("%s: index %d subpool_id %d handle 0x%08x", + VCOS_FUNCTION, index, subpool_id, ret); + + vcos_mutex_unlock(&pool->mutex); + return ret; +} + +void *vcos_generic_blockpool_elem_from_handle( + VCOS_BLOCKPOOL_T *pool, uint32_t handle) +{ + VCOS_BLOCKPOOL_SUBPOOL_T *subpool; + uint32_t subpool_id; + uint32_t index; + void *ret = NULL; + + + ASSERT_POOL(pool); + vcos_mutex_lock(&pool->mutex); + subpool_id = VCOS_BLOCKPOOL_HANDLE_GET_SUBPOOL(handle); + + if (subpool_id < pool->num_subpools) + { + index = VCOS_BLOCKPOOL_HANDLE_GET_INDEX(handle); + subpool = &pool->subpools[subpool_id]; + if (pool->subpools[subpool_id].magic == VCOS_BLOCKPOOL_SUBPOOL_MAGIC && + pool->subpools[subpool_id].mem && index < subpool->num_blocks) + { + VCOS_BLOCKPOOL_HEADER_T *hdr = (VCOS_BLOCKPOOL_HEADER_T*) + ((size_t) subpool->start + (index * pool->block_size)); + + if (hdr->owner.subpool == subpool) /* Check block is allocated */ + ret = hdr + 1; + } + } + vcos_mutex_unlock(&pool->mutex); + + vcos_log_trace("%s: pool %p handle 0x%08x elem %p", VCOS_FUNCTION, pool, + handle, ret); + return ret; +} + +uint32_t vcos_generic_blockpool_is_valid_elem( + VCOS_BLOCKPOOL_T *pool, const void *block) +{ + uint32_t ret = 0; + const char *pool_end; + VCOS_UNSIGNED i = 0; + + ASSERT_POOL(pool); + if (((size_t) block) & 0x3) + return 0; + + vcos_mutex_lock(&pool->mutex); + + for (i = 0; i < pool->num_subpools; ++i) + { + VCOS_BLOCKPOOL_SUBPOOL_T *subpool = &pool->subpools[i]; + ASSERT_SUBPOOL(subpool); + + if (subpool->mem && subpool->start) + { + pool_end = (const char*)subpool->start + + (subpool->num_blocks * pool->block_size); + + if ((const char*)block > (const char*)subpool->start && + (const char*)block < pool_end) + { + const VCOS_BLOCKPOOL_HEADER_T *hdr = ( + const VCOS_BLOCKPOOL_HEADER_T*) block - 1; + + /* If the block has a header where the owner points to the pool then + * it's a valid block. */ + ret = (hdr->owner.subpool == subpool && subpool->owner == pool); + break; + } + } + } + vcos_mutex_unlock(&pool->mutex); + return ret; +} diff --git a/external_src/raspicam-0.1.3/dependencies/vcos/generic/vcos_generic_blockpool.h b/external_src/raspicam-0.1.3/dependencies/vcos/generic/vcos_generic_blockpool.h new file mode 100644 index 0000000..4c387a3 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/vcos/generic/vcos_generic_blockpool.h @@ -0,0 +1,294 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. +*/ + +/*============================================================================= +VideoCore OS Abstraction Layer - event flags implemented via a semaphore +=============================================================================*/ + +#ifndef VCOS_GENERIC_BLOCKPOOL_H +#define VCOS_GENERIC_BLOCKPOOL_H + +/** + * \file + * + * This provides a generic, thread safe implementation of a VCOS block pool + * fixed size memory allocator. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "vcos_types.h" + +/** Bits 0 to (VCOS_BLOCKPOOL_SUBPOOL_BITS - 1) are used to store the + * subpool id. */ +#define VCOS_BLOCKPOOL_SUBPOOL_BITS 3 +#define VCOS_BLOCKPOOL_MAX_SUBPOOLS (1 << VCOS_BLOCKPOOL_SUBPOOL_BITS) + +/* Make zero an invalid handle at the cost of decreasing the maximum + * number of blocks (2^28) by 1. Alternatively, a spare bit could be + * used to indicated valid blocks but there are likely to be better + * uses for spare bits. e.g. allowing more subpools + */ +#define INDEX_OFFSET 1 + +#define VCOS_BLOCKPOOL_HANDLE_GET_INDEX(h) \ + (((h) >> VCOS_BLOCKPOOL_SUBPOOL_BITS) - INDEX_OFFSET) + +#define VCOS_BLOCKPOOL_HANDLE_GET_SUBPOOL(h) \ + ((h) & ((1 << VCOS_BLOCKPOOL_SUBPOOL_BITS) - 1)) + +#define VCOS_BLOCKPOOL_HANDLE_CREATE(i,s) \ + ((((i) + INDEX_OFFSET) << VCOS_BLOCKPOOL_SUBPOOL_BITS) | (s)) + +#define VCOS_BLOCKPOOL_INVALID_HANDLE 0 +#define VCOS_BLOCKPOOL_ALIGN_DEFAULT sizeof(unsigned long) +#define VCOS_BLOCKPOOL_FLAG_NONE 0 + +typedef struct VCOS_BLOCKPOOL_HEADER_TAG +{ + /* Blocks either refer to to the pool if they are allocated + * or the free list if they are available. + */ + union { + struct VCOS_BLOCKPOOL_HEADER_TAG *next; + struct VCOS_BLOCKPOOL_SUBPOOL_TAG* subpool; + } owner; +} VCOS_BLOCKPOOL_HEADER_T; + +typedef struct VCOS_BLOCKPOOL_SUBPOOL_TAG +{ + /** VCOS_BLOCKPOOL_SUBPOOL_MAGIC */ + uint32_t magic; + VCOS_BLOCKPOOL_HEADER_T* free_list; + /* The start of the pool memory */ + void *mem; + /* Address of the first block header */ + void *start; + /* The end of the subpool */ + void *end; + /** The number of blocks in this sub-pool */ + VCOS_UNSIGNED num_blocks; + /** Current number of available blocks in this sub-pool */ + VCOS_UNSIGNED available_blocks; + /** Pointers to the pool that owns this sub-pool */ + struct VCOS_BLOCKPOOL_TAG* owner; + /** Define properties such as memory ownership */ + uint32_t flags; +} VCOS_BLOCKPOOL_SUBPOOL_T; + +typedef struct VCOS_BLOCKPOOL_TAG +{ + /** VCOS_BLOCKPOOL_MAGIC */ + uint32_t magic; + /** Thread safety for Alloc, Free, Delete, Stats */ + VCOS_MUTEX_T mutex; + /** Alignment of block data pointers */ + VCOS_UNSIGNED align; + /** Flags for future use e.g. cache options */ + VCOS_UNSIGNED flags; + /** The size of the block data */ + size_t block_data_size; + /** Block size inc overheads */ + size_t block_size; + /** Name for debugging */ + const char *name; + /* The number of subpools that may be used */ + VCOS_UNSIGNED num_subpools; + /** Number of blocks in each dynamically allocated subpool */ + VCOS_UNSIGNED num_extension_blocks; + /** Array of subpools. Subpool zero is is not deleted until the pool is + * destroed. If the index of the pool is < num_subpools and + * subpool[index.mem] is null then the subpool entry is valid but + * "not currently allocated" */ + VCOS_BLOCKPOOL_SUBPOOL_T subpools[VCOS_BLOCKPOOL_MAX_SUBPOOLS]; +} VCOS_BLOCKPOOL_T; + +#define VCOS_BLOCKPOOL_ROUND_UP(x,s) (((x) + ((s) - 1)) & ~((s) - 1)) +/** + * Calculates the size in bytes required for a block pool containing + * num_blocks of size block_size plus any overheads. + * + * The block pool header (VCOS_BLOCKPOOL_T) is allocated separately + * + * Overheads: + * block_size + header must be rounded up to meet the required alignment + * The start of the first block may need to be up to align bytes + * into the given buffer because statically allocated buffers within structures + * are not guaranteed to be aligned as required. + */ +#define VCOS_BLOCKPOOL_SIZE(num_blocks, block_size, align) \ + ((VCOS_BLOCKPOOL_ROUND_UP((block_size) + (align >= 4096 ? 32 : 0) + sizeof(VCOS_BLOCKPOOL_HEADER_T), \ + (align)) * (num_blocks)) + (align)) + +/** + * Sanity check to verify whether a handle is potentially a blockpool handle + * when the pool pointer is not available. + * + * If the pool pointer is availabe use vcos_blockpool_elem_to_handle instead. + * + * @param handle the handle to verify + * @param max_blocks the expected maximum number of block in the pool + * that the handle belongs to. + */ +#define VCOS_BLOCKPOOL_IS_VALID_HANDLE_FORMAT(handle, max_blocks) \ + ((handle) != VCOS_BLOCKPOOL_INVALID_HANDLE \ + && VCOS_BLOCKPOOL_HANDLE_GET_INDEX((handle)) < (max_blocks)) + +VCOSPRE_ + VCOS_STATUS_T VCOSPOST_ vcos_generic_blockpool_init(VCOS_BLOCKPOOL_T *pool, + VCOS_UNSIGNED num_blocks, VCOS_UNSIGNED block_size, + void *start, VCOS_UNSIGNED pool_size, + VCOS_UNSIGNED align, VCOS_UNSIGNED flags, + const char *name); + +VCOSPRE_ + VCOS_STATUS_T VCOSPOST_ vcos_generic_blockpool_create_on_heap( + VCOS_BLOCKPOOL_T *pool, VCOS_UNSIGNED num_blocks, + VCOS_UNSIGNED block_size, + VCOS_UNSIGNED align, VCOS_UNSIGNED flags, + const char *name); + +VCOSPRE_ + VCOS_STATUS_T VCOSPOST_ vcos_generic_blockpool_extend(VCOS_BLOCKPOOL_T *pool, + VCOS_UNSIGNED num_extensions, VCOS_UNSIGNED num_blocks); + +VCOSPRE_ void VCOSPOST_ *vcos_generic_blockpool_alloc(VCOS_BLOCKPOOL_T *pool); + +VCOSPRE_ void VCOSPOST_ *vcos_generic_blockpool_calloc(VCOS_BLOCKPOOL_T *pool); + +VCOSPRE_ void VCOSPOST_ vcos_generic_blockpool_free(void *block); + +VCOSPRE_ + VCOS_UNSIGNED VCOSPOST_ vcos_generic_blockpool_available_count( + VCOS_BLOCKPOOL_T *pool); + +VCOSPRE_ + VCOS_UNSIGNED VCOSPOST_ vcos_generic_blockpool_used_count( + VCOS_BLOCKPOOL_T *pool); + +VCOSPRE_ void VCOSPOST_ vcos_generic_blockpool_delete(VCOS_BLOCKPOOL_T *pool); + +VCOSPRE_ uint32_t VCOSPOST_ vcos_generic_blockpool_elem_to_handle(void *block); + +VCOSPRE_ void VCOSPOST_ + *vcos_generic_blockpool_elem_from_handle( + VCOS_BLOCKPOOL_T *pool, uint32_t handle); + +VCOSPRE_ uint32_t VCOSPOST_ + vcos_generic_blockpool_is_valid_elem( + VCOS_BLOCKPOOL_T *pool, const void *block); +#if defined(VCOS_INLINE_BODIES) + +VCOS_INLINE_IMPL +VCOS_STATUS_T vcos_blockpool_init(VCOS_BLOCKPOOL_T *pool, + VCOS_UNSIGNED num_blocks, VCOS_UNSIGNED block_size, + void *start, VCOS_UNSIGNED pool_size, + VCOS_UNSIGNED align, VCOS_UNSIGNED flags, const char *name) +{ + return vcos_generic_blockpool_init(pool, num_blocks, block_size, + start, pool_size, align, flags, name); +} + +VCOS_INLINE_IMPL +VCOS_STATUS_T vcos_blockpool_create_on_heap(VCOS_BLOCKPOOL_T *pool, + VCOS_UNSIGNED num_blocks, VCOS_UNSIGNED block_size, + VCOS_UNSIGNED align, VCOS_UNSIGNED flags, const char *name) +{ + return vcos_generic_blockpool_create_on_heap( + pool, num_blocks, block_size, align, flags, name); +} + +VCOS_INLINE_IMPL + VCOS_STATUS_T VCOSPOST_ vcos_blockpool_extend(VCOS_BLOCKPOOL_T *pool, + VCOS_UNSIGNED num_extensions, VCOS_UNSIGNED num_blocks) +{ + return vcos_generic_blockpool_extend(pool, num_extensions, num_blocks); +} + +VCOS_INLINE_IMPL +void *vcos_blockpool_alloc(VCOS_BLOCKPOOL_T *pool) +{ + return vcos_generic_blockpool_alloc(pool); +} + +VCOS_INLINE_IMPL +void *vcos_blockpool_calloc(VCOS_BLOCKPOOL_T *pool) +{ + return vcos_generic_blockpool_calloc(pool); +} + +VCOS_INLINE_IMPL +void vcos_blockpool_free(void *block) +{ + vcos_generic_blockpool_free(block); +} + +VCOS_INLINE_IMPL +VCOS_UNSIGNED vcos_blockpool_available_count(VCOS_BLOCKPOOL_T *pool) +{ + return vcos_generic_blockpool_available_count(pool); +} + +VCOS_INLINE_IMPL +VCOS_UNSIGNED vcos_blockpool_used_count(VCOS_BLOCKPOOL_T *pool) +{ + return vcos_generic_blockpool_used_count(pool); +} + +VCOS_INLINE_IMPL +void vcos_blockpool_delete(VCOS_BLOCKPOOL_T *pool) +{ + vcos_generic_blockpool_delete(pool); +} + +VCOS_INLINE_IMPL +uint32_t vcos_blockpool_elem_to_handle(void *block) +{ + return vcos_generic_blockpool_elem_to_handle(block); +} + +VCOS_INLINE_IMPL +void *vcos_blockpool_elem_from_handle(VCOS_BLOCKPOOL_T *pool, uint32_t handle) +{ + return vcos_generic_blockpool_elem_from_handle(pool, handle); +} + +VCOS_INLINE_IMPL +uint32_t vcos_blockpool_is_valid_elem(VCOS_BLOCKPOOL_T *pool, const void *block) +{ + return vcos_generic_blockpool_is_valid_elem(pool, block); +} +#endif /* VCOS_INLINE_BODIES */ + + +#ifdef __cplusplus +} +#endif +#endif /* VCOS_GENERIC_BLOCKPOOL_H */ + diff --git a/external_src/raspicam-0.1.3/dependencies/vcos/generic/vcos_generic_event_flags.c b/external_src/raspicam-0.1.3/dependencies/vcos/generic/vcos_generic_event_flags.c new file mode 100644 index 0000000..9a7c1bb --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/vcos/generic/vcos_generic_event_flags.c @@ -0,0 +1,320 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. +*/ + +/*============================================================================= +VideoCore OS Abstraction Layer - event flags implemented via mutexes +=============================================================================*/ + +#include "interface/vcos/vcos.h" +#include "interface/vcos/generic/vcos_generic_event_flags.h" + +#include + +/** A structure created by a thread that waits on the event flags + * for a particular combination of flags to arrive. + */ +typedef struct VCOS_EVENT_WAITER_T +{ + VCOS_UNSIGNED requested_events; /**< The events wanted */ + VCOS_UNSIGNED actual_events; /**< Actual events found */ + VCOS_UNSIGNED op; /**< The event operation to be used */ + VCOS_STATUS_T return_status; /**< The return status the waiter should pass back */ + VCOS_EVENT_FLAGS_T *flags; /**< Pointer to the original 'flags' structure */ + VCOS_THREAD_T *thread; /**< Thread waiting */ + struct VCOS_EVENT_WAITER_T *next; +} VCOS_EVENT_WAITER_T; + +#ifndef NDEBUG +static int waiter_list_valid(VCOS_EVENT_FLAGS_T *flags); +#endif +static void event_flags_timer_expired(void *cxt); + +VCOS_STATUS_T vcos_generic_event_flags_create(VCOS_EVENT_FLAGS_T *flags, const char *name) +{ + VCOS_STATUS_T rc; + if ((rc=vcos_mutex_create(&flags->lock, name)) != VCOS_SUCCESS) + { + return rc; + } + + flags->events = 0; + flags->waiters.head = flags->waiters.tail = 0; + return rc; +} + +void vcos_generic_event_flags_set(VCOS_EVENT_FLAGS_T *flags, + VCOS_UNSIGNED bitmask, + VCOS_OPTION op) +{ + vcos_assert(flags); + vcos_mutex_lock(&flags->lock); + if (op == VCOS_OR) + { + flags->events |= bitmask; + } + else if (op == VCOS_AND) + { + flags->events &= bitmask; + } + else + { + vcos_assert(0); + } + + /* Now wake up any threads that have now become signalled. */ + if (flags->waiters.head != NULL) + { + VCOS_UNSIGNED consumed_events = 0; + VCOS_EVENT_WAITER_T **pcurrent_waiter = &flags->waiters.head; + VCOS_EVENT_WAITER_T *prev_waiter = NULL; + + /* Walk the chain of tasks suspend on this event flag group to determine + * if any of their requests can be satisfied. + */ + while ((*pcurrent_waiter) != NULL) + { + VCOS_EVENT_WAITER_T *curr_waiter = *pcurrent_waiter; + + /* Determine if this request has been satisfied */ + + /* First, find the event flags in common. */ + VCOS_UNSIGNED waiter_satisfied = flags->events & curr_waiter->requested_events; + + /* Second, determine if all the event flags must match */ + if (curr_waiter->op & VCOS_AND) + { + /* All requested events must be present */ + waiter_satisfied = (waiter_satisfied == curr_waiter->requested_events); + } + + /* Wake this one up? */ + if (waiter_satisfied) + { + + if (curr_waiter->op & VCOS_CONSUME) + { + consumed_events |= curr_waiter->requested_events; + } + + /* remove this block from the list, taking care at the end */ + *pcurrent_waiter = curr_waiter->next; + if (curr_waiter->next == NULL) + flags->waiters.tail = prev_waiter; + + vcos_assert(waiter_list_valid(flags)); + + curr_waiter->return_status = VCOS_SUCCESS; + curr_waiter->actual_events = flags->events; + + _vcos_thread_sem_post(curr_waiter->thread); + } + else + { + /* move to next element in the list */ + prev_waiter = *pcurrent_waiter; + pcurrent_waiter = &(curr_waiter->next); + } + } + + flags->events &= ~consumed_events; + + } + + vcos_mutex_unlock(&flags->lock); +} + +void vcos_generic_event_flags_delete(VCOS_EVENT_FLAGS_T *flags) +{ + vcos_mutex_delete(&flags->lock); +} + +extern VCOS_STATUS_T vcos_generic_event_flags_get(VCOS_EVENT_FLAGS_T *flags, + VCOS_UNSIGNED bitmask, + VCOS_OPTION op, + VCOS_UNSIGNED suspend, + VCOS_UNSIGNED *retrieved_bits) +{ + VCOS_EVENT_WAITER_T waitreq; + VCOS_STATUS_T rc = VCOS_EAGAIN; + int satisfied = 0; + + vcos_assert(flags); + + /* default retrieved bits to 0 */ + *retrieved_bits = 0; + + vcos_mutex_lock(&flags->lock); + switch (op & VCOS_EVENT_FLAG_OP_MASK) + { + case VCOS_AND: + if ((flags->events & bitmask) == bitmask) + { + *retrieved_bits = flags->events; + rc = VCOS_SUCCESS; + satisfied = 1; + if (op & VCOS_CONSUME) + flags->events &= ~bitmask; + } + break; + + case VCOS_OR: + if (flags->events & bitmask) + { + *retrieved_bits = flags->events; + rc = VCOS_SUCCESS; + satisfied = 1; + if (op & VCOS_CONSUME) + flags->events &= ~bitmask; + } + break; + + default: + vcos_assert(0); + rc = VCOS_EINVAL; + break; + } + + if (!satisfied && suspend) + { + /* Have to go to sleep. + * + * Append to tail so we get FIFO ordering. + */ + waitreq.requested_events = bitmask; + waitreq.op = op; + waitreq.return_status = VCOS_EAGAIN; + waitreq.flags = flags; + waitreq.actual_events = 0; + waitreq.thread = vcos_thread_current(); + waitreq.next = 0; + vcos_assert(waitreq.thread != (VCOS_THREAD_T*)-1); + VCOS_QUEUE_APPEND_TAIL(&flags->waiters, &waitreq); + + if (suspend != (VCOS_UNSIGNED)-1) + _vcos_task_timer_set(event_flags_timer_expired, &waitreq, suspend); + + vcos_mutex_unlock(&flags->lock); + /* go to sleep and wait to be signalled or timeout */ + + _vcos_thread_sem_wait(); + + *retrieved_bits = waitreq.actual_events; + rc = waitreq.return_status; + + /* cancel the timer - do not do this while holding the mutex as it + * might be waiting for the timeout function to complete, which will + * try to take the mutex. + */ + if (suspend != (VCOS_UNSIGNED)-1) + _vcos_task_timer_cancel(); + } + else + { + vcos_mutex_unlock(&flags->lock); + } + + return rc; +} + + +/** Called when a get call times out. Remove this thread's + * entry from the waiting queue, then resume the thread. + */ +static void event_flags_timer_expired(void *cxt) +{ + VCOS_EVENT_WAITER_T *waitreq = (VCOS_EVENT_WAITER_T *)cxt; + VCOS_EVENT_FLAGS_T *flags = waitreq->flags; + VCOS_EVENT_WAITER_T **plist; + VCOS_EVENT_WAITER_T *prev = NULL; + VCOS_THREAD_T *thread = 0; + + vcos_assert(flags); + + vcos_mutex_lock(&flags->lock); + + /* walk the list of waiting threads on this event group, and remove + * the one that has expired. + * + * FIXME: could use doubly-linked list if lots of threads are found + * to be waiting on a single event flag instance. + */ + plist = &flags->waiters.head; + while (*plist != NULL) + { + if (*plist == waitreq) + { + int at_end; + /* found it */ + thread = (*plist)->thread; + at_end = ((*plist)->next == NULL); + + /* link past */ + *plist = (*plist)->next; + if (at_end) + flags->waiters.tail = prev; + + break; + } + prev = *plist; + plist = &(*plist)->next; + } + vcos_assert(waiter_list_valid(flags)); + + vcos_mutex_unlock(&flags->lock); + + if (thread) + { + _vcos_thread_sem_post(thread); + } +} + +#ifndef NDEBUG + +static int waiter_list_valid(VCOS_EVENT_FLAGS_T *flags) +{ + int valid; + /* Either both head and tail are NULL, or neither are NULL */ + if (flags->waiters.head == NULL) + { + valid = (flags->waiters.tail == NULL); + } + else + { + valid = (flags->waiters.tail != NULL); + } + + /* If head and tail point at the same non-NULL element, then there + * is only one element in the list. + */ + if (flags->waiters.head && (flags->waiters.head == flags->waiters.tail)) + { + valid = (flags->waiters.head->next == NULL); + } + return valid; +} + +#endif diff --git a/external_src/raspicam-0.1.3/dependencies/vcos/generic/vcos_generic_event_flags.h b/external_src/raspicam-0.1.3/dependencies/vcos/generic/vcos_generic_event_flags.h new file mode 100644 index 0000000..de68388 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/vcos/generic/vcos_generic_event_flags.h @@ -0,0 +1,127 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. +*/ + +/*============================================================================= +VideoCore OS Abstraction Layer - event flags implemented via a semaphore +=============================================================================*/ + +#ifndef VCOS_GENERIC_EVENT_FLAGS_H +#define VCOS_GENERIC_EVENT_FLAGS_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "vcos_types.h" + +/** + * \file + * + * This provides event flags (as per Nucleus Event Groups) based on a + * mutex, a semaphore (per waiting thread) and a timer (per waiting + * thread). + * + * The data structure is a 32 bit unsigned int (the current set of + * flags) and a linked list of clients waiting to be 'satisfied'. + * + * The mutex merely locks access to the data structure. If a client + * calls vcos_event_flags_get() and the requested bits are not already + * present, it then sleeps on its per-thread semaphore after adding + * this semaphore to the queue waiting. It also sets up a timer. + * + * The per-thread semaphore and timer are actually stored in the + * thread context (joinable thread). In future it may become necessary + * to support non-VCOS threads by using thread local storage to + * create these objects and associate them with the thread. + */ + +struct VCOS_EVENT_WAITER_T; + +typedef struct VCOS_EVENT_FLAGS_T +{ + VCOS_UNSIGNED events; /**< Events currently set */ + VCOS_MUTEX_T lock; /**< Serialize access */ + struct + { + struct VCOS_EVENT_WAITER_T *head; /**< List of threads waiting */ + struct VCOS_EVENT_WAITER_T *tail; /**< List of threads waiting */ + } waiters; +} VCOS_EVENT_FLAGS_T; + +#define VCOS_OR 1 +#define VCOS_AND 2 +#define VCOS_CONSUME 4 +#define VCOS_OR_CONSUME (VCOS_OR | VCOS_CONSUME) +#define VCOS_AND_CONSUME (VCOS_AND | VCOS_CONSUME) +#define VCOS_EVENT_FLAG_OP_MASK (VCOS_OR|VCOS_AND) + +VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_generic_event_flags_create(VCOS_EVENT_FLAGS_T *flags, const char *name); +VCOSPRE_ void VCOSPOST_ vcos_generic_event_flags_set(VCOS_EVENT_FLAGS_T *flags, + VCOS_UNSIGNED events, + VCOS_OPTION op); +VCOSPRE_ void VCOSPOST_ vcos_generic_event_flags_delete(VCOS_EVENT_FLAGS_T *); +VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_generic_event_flags_get(VCOS_EVENT_FLAGS_T *flags, + VCOS_UNSIGNED requested_events, + VCOS_OPTION op, + VCOS_UNSIGNED suspend, + VCOS_UNSIGNED *retrieved_events); + +#ifdef VCOS_INLINE_BODIES + +VCOS_INLINE_IMPL +VCOS_STATUS_T vcos_event_flags_create(VCOS_EVENT_FLAGS_T *flags, const char *name) { + return vcos_generic_event_flags_create(flags, name); +} + +VCOS_INLINE_IMPL +void vcos_event_flags_set(VCOS_EVENT_FLAGS_T *flags, + VCOS_UNSIGNED events, + VCOS_OPTION op) { + vcos_generic_event_flags_set(flags, events, op); +} + +VCOS_INLINE_IMPL +void vcos_event_flags_delete(VCOS_EVENT_FLAGS_T *f) { + vcos_generic_event_flags_delete(f); +} + +VCOS_INLINE_IMPL +VCOS_STATUS_T vcos_event_flags_get(VCOS_EVENT_FLAGS_T *flags, + VCOS_UNSIGNED requested_events, + VCOS_OPTION op, + VCOS_UNSIGNED suspend, + VCOS_UNSIGNED *retrieved_events) { + return vcos_generic_event_flags_get(flags, requested_events, op, suspend, retrieved_events); +} + +#endif /* VCOS_INLINE_BODIES */ + +#ifdef __cplusplus +} +#endif +#endif + diff --git a/external_src/raspicam-0.1.3/dependencies/vcos/generic/vcos_generic_named_sem.c b/external_src/raspicam-0.1.3/dependencies/vcos/generic/vcos_generic_named_sem.c new file mode 100644 index 0000000..cf47962 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/vcos/generic/vcos_generic_named_sem.c @@ -0,0 +1,268 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. +*/ + +#define VCOS_LOG_CATEGORY (&vcos_named_sem_log_cat) + +#include "interface/vcos/vcos.h" +#include "interface/vcos/generic/vcos_generic_named_sem.h" +#include "interface/vcos/vcos_blockpool.h" + +#if defined(VCOS_LOGGING_ENABLED) +static VCOS_LOG_CAT_T vcos_named_sem_log_cat = +VCOS_LOG_INIT("vcos_named_sem", VCOS_LOG_ERROR); +#endif + +/** + * \file + * + * Named semaphores, primarily for VCFW. + * + * Does not actually work across processes; merely emulate the API. + * + * The client initialises a VCOS_NAMED_SEMAPHORE_T, but this merely + * points at the real underlying VCOS_NAMED_SEMAPHORE_IMPL_T. + * + * semaphore_t ---\ + * ----- semaphore_impl_t + * semaphore_t ---/ + * / + * semaphore_t -/ + * + */ + +/* Maintain a block pool of semaphore implementations */ +#define NUM_SEMS 16 + +/* Allow the pool to expand to MAX_SEMS in size */ +#define MAX_SEMS 512 + +/** Each actual real semaphore is stored in one of these. Clients just + * get a structure with a pointer to this in it. + * + * It also contains a doubly linked list tracking the semaphores in-use. + */ +typedef struct VCOS_NAMED_SEMAPHORE_IMPL_T +{ + VCOS_SEMAPHORE_T sem; /**< Actual underlying semaphore */ + char name[VCOS_NAMED_SEMAPHORE_NAMELEN]; /**< Name of semaphore, copied */ + unsigned refs; /**< Reference count */ + struct VCOS_NAMED_SEMAPHORE_IMPL_T *next; /**< Next in the in-use list */ + struct VCOS_NAMED_SEMAPHORE_IMPL_T *prev; /**< Previous in the in-use list */ +} VCOS_NAMED_SEMAPHORE_IMPL_T; + +static VCOS_MUTEX_T lock; +static VCOS_NAMED_SEMAPHORE_IMPL_T* sems_in_use = NULL; +static int sems_in_use_count = 0; +static int sems_total_ref_count = 0; + +static VCOS_BLOCKPOOL_T sems_pool; +static char pool_mem[VCOS_BLOCKPOOL_SIZE( + NUM_SEMS, sizeof(VCOS_NAMED_SEMAPHORE_IMPL_T), VCOS_BLOCKPOOL_ALIGN_DEFAULT)]; + +VCOS_STATUS_T _vcos_named_semaphore_init() +{ + VCOS_STATUS_T status; + + status = vcos_blockpool_init(&sems_pool, + NUM_SEMS, sizeof(VCOS_NAMED_SEMAPHORE_IMPL_T), + pool_mem, sizeof(pool_mem), + VCOS_BLOCKPOOL_ALIGN_DEFAULT, 0, "vcos named semaphores"); + + if (status != VCOS_SUCCESS) + goto fail_blockpool; + + status = vcos_blockpool_extend(&sems_pool, VCOS_BLOCKPOOL_MAX_SUBPOOLS - 1, + (MAX_SEMS - NUM_SEMS) / (VCOS_BLOCKPOOL_MAX_SUBPOOLS - 1)); + if (status != VCOS_SUCCESS) + goto fail_extend; + + status = vcos_mutex_create(&lock, "vcosnmsem"); + if (status != VCOS_SUCCESS) + goto fail_mutex; + + return status; + +fail_mutex: +fail_extend: + vcos_blockpool_delete(&sems_pool); +fail_blockpool: + return status; +} + +void _vcos_named_semaphore_deinit(void) +{ + vcos_blockpool_delete(&sems_pool); + vcos_mutex_delete(&lock); + sems_in_use = NULL; +} + +VCOS_STATUS_T +vcos_generic_named_semaphore_create(VCOS_NAMED_SEMAPHORE_T *sem, + const char *name, VCOS_UNSIGNED count) +{ + VCOS_STATUS_T status = VCOS_ENOSPC; + int name_len, cmp = -1; + VCOS_NAMED_SEMAPHORE_IMPL_T *impl; + VCOS_NAMED_SEMAPHORE_IMPL_T *new_impl; + + vcos_log_trace("%s: sem %p name %s count %d", __FUNCTION__, + sem, (name ? name : "null"), count); + + vcos_assert(name); + + vcos_mutex_lock(&lock); + name_len = vcos_strlen(name); + if (name_len >= VCOS_NAMED_SEMAPHORE_NAMELEN) + { + vcos_assert(0); + status = VCOS_EINVAL; + goto end; + } + + /* do we already have this semaphore? */ + impl = sems_in_use; + while (impl && (cmp = vcos_strcmp(name, impl->name)) < 0) + impl = impl->next; + + if (impl && cmp == 0) + { + /* Semaphore is already in use so just increase the ref count */ + impl->refs++; + sems_total_ref_count++; + sem->actual = impl; + sem->sem = &impl->sem; + status = VCOS_SUCCESS; + vcos_log_trace( + "%s: ref count %d name %s total refs %d num sems %d", + __FUNCTION__, impl->refs, impl->name, + sems_total_ref_count, sems_in_use_count); + goto end; + } + + /* search for unused semaphore */ + new_impl = vcos_blockpool_calloc(&sems_pool); + if (new_impl) + { + status = vcos_semaphore_create(&new_impl->sem, name, count); + if (status == VCOS_SUCCESS) + { + new_impl->refs = 1; + sems_total_ref_count++; + sems_in_use_count++; + memcpy(new_impl->name, name, name_len + 1); /* already checked length! */ + sem->actual = new_impl; + sem->sem = &new_impl->sem; + + /* Insert into the sorted list + * impl is either NULL or the first element where + * name > impl->name. + */ + if (impl) + { + new_impl->prev = impl->prev; + impl->prev = new_impl; + new_impl->next = impl; + + if (new_impl->prev) + new_impl->prev->next = new_impl; + } + else + { + /* Appending to the tail of the list / empty list */ + VCOS_NAMED_SEMAPHORE_IMPL_T *tail = sems_in_use; + while(tail && tail->next) + tail = tail->next; + + if (tail) + { + tail->next = new_impl; + new_impl->prev = tail; + } + } + + if (sems_in_use == impl) + { + /* Inserted at head or list was empty */ + sems_in_use = new_impl; + } + + vcos_log_trace( + "%s: new ref actual %p prev %p next %p count %d name %s " \ + "total refs %d num sems %d", + __FUNCTION__, + new_impl, new_impl->prev, new_impl->next, + new_impl->refs, new_impl->name, + sems_total_ref_count, sems_in_use_count); + } + } + +end: + vcos_mutex_unlock(&lock); + if (status != VCOS_SUCCESS) + { + vcos_log_error("%s: failed to create named semaphore name %s status %d " \ + "total refs %d num sems %d", + __FUNCTION__, (name ? name : "NULL"), status, + sems_total_ref_count, sems_in_use_count); + } + return status; +} + +void vcos_named_semaphore_delete(VCOS_NAMED_SEMAPHORE_T *sem) +{ + VCOS_NAMED_SEMAPHORE_IMPL_T *actual = sem->actual; + vcos_mutex_lock(&lock); + + /* if this fires, the semaphore has already been deleted */ + vcos_assert(actual->refs); + + vcos_log_trace( + "%s: actual %p ref count %d name %s prev %p next %p total refs %d num sems %d", + __FUNCTION__, actual, actual->refs, actual->name, + actual->prev, actual->next, + sems_total_ref_count, sems_in_use_count); + + sems_total_ref_count--; + if (--actual->refs == 0) + { + sems_in_use_count--; + if (actual->prev) + actual->prev->next = actual->next; + + if (actual->next) + actual->next->prev = actual->prev; + + if (sems_in_use == actual) + sems_in_use = actual->next; + + vcos_semaphore_delete(&actual->sem); + sem->actual = NULL; + sem->sem = NULL; + vcos_blockpool_free(actual); + } + vcos_mutex_unlock(&lock); +} diff --git a/external_src/raspicam-0.1.3/dependencies/vcos/generic/vcos_generic_named_sem.h b/external_src/raspicam-0.1.3/dependencies/vcos/generic/vcos_generic_named_sem.h new file mode 100644 index 0000000..725cffc --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/vcos/generic/vcos_generic_named_sem.h @@ -0,0 +1,101 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. +*/ + +/*============================================================================= +VideoCore OS Abstraction Layer - named semaphores +=============================================================================*/ + +#ifndef VCOS_GENERIC_NAMED_SEM_H +#define VCOS_GENERIC_NAMED_SEM_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "vcos_types.h" + +/** + * \file + * + * Generic support for named semaphores, using regular ones. This is only + * suitable for emulating them on an embedded MMUless system, since there is + * no support for opening semaphores across process boundaries. + * + */ + +#define VCOS_NAMED_SEMAPHORE_NAMELEN 64 + +/* In theory we could use the name facility provided within Nucleus. However, this + * is hard to do as semaphores are constantly being created and destroyed; we + * would need to stop everything while allocating the memory for the semaphore + * list and then walking it. So keep our own list. + */ +typedef struct VCOS_NAMED_SEMAPHORE_T +{ + struct VCOS_NAMED_SEMAPHORE_IMPL_T *actual; /**< There are 'n' named semaphores per 1 actual semaphore */ + VCOS_SEMAPHORE_T *sem; /**< Pointer to actual underlying semaphore */ +} VCOS_NAMED_SEMAPHORE_T; + +VCOSPRE_ VCOS_STATUS_T VCOSPOST_ +vcos_generic_named_semaphore_create(VCOS_NAMED_SEMAPHORE_T *sem, const char *name, VCOS_UNSIGNED count); + +VCOSPRE_ void VCOSPOST_ vcos_named_semaphore_delete(VCOS_NAMED_SEMAPHORE_T *sem); + +VCOSPRE_ VCOS_STATUS_T VCOSPOST_ _vcos_named_semaphore_init(void); +VCOSPRE_ void VCOSPOST_ _vcos_named_semaphore_deinit(void); + +#if defined(VCOS_INLINE_BODIES) + +VCOS_INLINE_IMPL +VCOS_STATUS_T vcos_named_semaphore_create(VCOS_NAMED_SEMAPHORE_T *sem, const char *name, VCOS_UNSIGNED count) { + return vcos_generic_named_semaphore_create(sem, name, count); +} + +VCOS_INLINE_IMPL +void vcos_named_semaphore_wait(VCOS_NAMED_SEMAPHORE_T *sem) { + vcos_semaphore_wait(sem->sem); +} + +VCOS_INLINE_IMPL +VCOS_STATUS_T vcos_named_semaphore_trywait(VCOS_NAMED_SEMAPHORE_T *sem) { + return vcos_semaphore_trywait(sem->sem); +} + +VCOS_INLINE_IMPL +void vcos_named_semaphore_post(VCOS_NAMED_SEMAPHORE_T *sem) { + vcos_semaphore_post(sem->sem); +} + + +#endif + +#ifdef __cplusplus +} +#endif +#endif + + diff --git a/external_src/raspicam-0.1.3/dependencies/vcos/generic/vcos_generic_quickslow_mutex.h b/external_src/raspicam-0.1.3/dependencies/vcos/generic/vcos_generic_quickslow_mutex.h new file mode 100644 index 0000000..1b2b5f9 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/vcos/generic/vcos_generic_quickslow_mutex.h @@ -0,0 +1,95 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. +*/ + +/*============================================================================= +VideoCore OS Abstraction Layer - reentrant mutexes created from regular ones. +=============================================================================*/ + +#ifndef VCOS_GENERIC_QUICKSLOW_MUTEX_H +#define VCOS_GENERIC_QUICKSLOW_MUTEX_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "vcos_types.h" + +/** + * \file + * + * Quickslow Mutexes implemented as regular ones (i.e. quick and slow modes are the same). + * + */ + +typedef VCOS_MUTEX_T VCOS_QUICKSLOW_MUTEX_T; + +#if defined(VCOS_INLINE_BODIES) +VCOS_INLINE_IMPL +VCOS_STATUS_T vcos_quickslow_mutex_create(VCOS_QUICKSLOW_MUTEX_T *m, const char *name) +{ + return vcos_mutex_create(m, name); +} + +VCOS_INLINE_IMPL +void vcos_quickslow_mutex_delete(VCOS_QUICKSLOW_MUTEX_T *m) +{ + vcos_mutex_delete(m); +} + +VCOS_INLINE_IMPL +void vcos_quickslow_mutex_lock(VCOS_QUICKSLOW_MUTEX_T *m) +{ + while (vcos_mutex_lock(m) == VCOS_EAGAIN); +} + +VCOS_INLINE_IMPL +void vcos_quickslow_mutex_unlock(VCOS_QUICKSLOW_MUTEX_T *m) +{ + vcos_mutex_unlock(m); +} + +VCOS_INLINE_IMPL +void vcos_quickslow_mutex_lock_quick(VCOS_QUICKSLOW_MUTEX_T *m) +{ + while (vcos_mutex_lock(m) == VCOS_EAGAIN); +} + +VCOS_INLINE_IMPL +void vcos_quickslow_mutex_unlock_quick(VCOS_QUICKSLOW_MUTEX_T *m) +{ + vcos_mutex_unlock(m); +} + +#endif + + +#ifdef __cplusplus +} +#endif +#endif + + diff --git a/external_src/raspicam-0.1.3/dependencies/vcos/generic/vcos_generic_reentrant_mtx.c b/external_src/raspicam-0.1.3/dependencies/vcos/generic/vcos_generic_reentrant_mtx.c new file mode 100644 index 0000000..7258cbf --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/vcos/generic/vcos_generic_reentrant_mtx.c @@ -0,0 +1,76 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 "interface/vcos/vcos.h" +#include "interface/vcos/vcos_reentrant_mutex.h" + +VCOS_STATUS_T vcos_generic_reentrant_mutex_create(VCOS_REENTRANT_MUTEX_T *m, const char *name) +{ + m->count = 0; + m->owner = 0; + return vcos_mutex_create(&m->mutex, name); +} + +void vcos_generic_reentrant_mutex_delete(VCOS_REENTRANT_MUTEX_T *m) +{ + vcos_assert(m->count == 0); + vcos_mutex_delete(&m->mutex); +} + +void vcos_generic_reentrant_mutex_lock(VCOS_REENTRANT_MUTEX_T *m) +{ + VCOS_THREAD_T *thread = vcos_thread_current(); + vcos_assert(m); + + vcos_assert(thread != 0); + + if (m->owner != thread) + { + vcos_mutex_lock(&m->mutex); + m->owner = thread; + vcos_assert(m->count == 0); + } + m->count++; +} + +void vcos_generic_reentrant_mutex_unlock(VCOS_REENTRANT_MUTEX_T *m) +{ + vcos_assert(m->count != 0); + vcos_assert(m->owner == vcos_thread_current()); + m->count--; + if (m->count == 0) + { + m->owner = 0; + vcos_mutex_unlock(&m->mutex); + } +} + + + + + + diff --git a/external_src/raspicam-0.1.3/dependencies/vcos/generic/vcos_generic_reentrant_mtx.h b/external_src/raspicam-0.1.3/dependencies/vcos/generic/vcos_generic_reentrant_mtx.h new file mode 100644 index 0000000..e8830ce --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/vcos/generic/vcos_generic_reentrant_mtx.h @@ -0,0 +1,95 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. +*/ + +/*============================================================================= +VideoCore OS Abstraction Layer - reentrant mutexes created from regular ones. +=============================================================================*/ + +#ifndef VCOS_GENERIC_REENTRANT_MUTEX_H +#define VCOS_GENERIC_REENTRANT_MUTEX_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "vcos_types.h" + +/** + * \file + * + * Reentrant Mutexes from regular ones. + * + */ + +typedef struct VCOS_REENTRANT_MUTEX_T +{ + VCOS_MUTEX_T mutex; + VCOS_THREAD_T *owner; + unsigned count; +} VCOS_REENTRANT_MUTEX_T; + +/* Extern definitions of functions that do the actual work */ + +VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_generic_reentrant_mutex_create(VCOS_REENTRANT_MUTEX_T *m, const char *name); + +VCOSPRE_ void VCOSPOST_ vcos_generic_reentrant_mutex_delete(VCOS_REENTRANT_MUTEX_T *m); + +VCOSPRE_ void VCOSPOST_ vcos_generic_reentrant_mutex_lock(VCOS_REENTRANT_MUTEX_T *m); + +VCOSPRE_ void VCOSPOST_ vcos_generic_reentrant_mutex_unlock(VCOS_REENTRANT_MUTEX_T *m); + +/* Inline forwarding functions */ + +#if defined(VCOS_INLINE_BODIES) + +VCOS_INLINE_IMPL +VCOS_STATUS_T vcos_reentrant_mutex_create(VCOS_REENTRANT_MUTEX_T *m, const char *name) { + return vcos_generic_reentrant_mutex_create(m,name); +} + +VCOS_INLINE_IMPL +void vcos_reentrant_mutex_delete(VCOS_REENTRANT_MUTEX_T *m) { + vcos_generic_reentrant_mutex_delete(m); +} + +VCOS_INLINE_IMPL +void vcos_reentrant_mutex_lock(VCOS_REENTRANT_MUTEX_T *m) { + vcos_generic_reentrant_mutex_lock(m); +} + +VCOS_INLINE_IMPL +void vcos_reentrant_mutex_unlock(VCOS_REENTRANT_MUTEX_T *m) { + vcos_generic_reentrant_mutex_unlock(m); +} +#endif + +#ifdef __cplusplus +} +#endif +#endif + + diff --git a/external_src/raspicam-0.1.3/dependencies/vcos/generic/vcos_generic_safe_string.c b/external_src/raspicam-0.1.3/dependencies/vcos/generic/vcos_generic_safe_string.c new file mode 100644 index 0000000..4a02c22 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/vcos/generic/vcos_generic_safe_string.c @@ -0,0 +1,130 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. +*/ + /***************************************************************************** + * Copyright 2012 Broadcom Corporation. All rights reserved. + * + * This program is the proprietary software of Broadcom Corporation and/or + * its licensors, and may only be used, duplicated, modified or distributed + * pursuant to the terms and conditions of a separate, written license + * agreement executed between you and Broadcom (an "Authorized License"). + * Except as set forth in an Authorized License, Broadcom grants no license + * (express or implied), right to use, or waiver of any kind with respect to + * the Software, and Broadcom expressly reserves all rights in and to the + * Software and all intellectual property rights therein. IF YOU HAVE NO + * AUTHORIZED LICENSE, THEN YOU HAVE NO RIGHT TO USE THIS SOFTWARE IN ANY + * WAY, AND SHOULD IMMEDIATELY NOTIFY BROADCOM AND DISCONTINUE ALL USE OF + * THE SOFTWARE. + * + * Except as expressly set forth in the Authorized License, + * 1. This program, including its structure, sequence and organization, + * constitutes the valuable trade secrets of Broadcom, and you shall use + * all reasonable efforts to protect the confidentiality thereof, and to + * use this information only in connection with your use of Broadcom + * integrated circuit products. + * 2. TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS" + * AND WITH ALL FAULTS AND BROADCOM MAKES NO PROMISES, REPRESENTATIONS OR + * WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH + * RESPECT TO THE SOFTWARE. BROADCOM SPECIFICALLY DISCLAIMS ANY AND ALL + * IMPLIED WARRANTIES OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS + * FOR A PARTICULAR PURPOSE, LACK OF VIRUSES, ACCURACY OR COMPLETENESS, + * QUIET ENJOYMENT, QUIET POSSESSION OR CORRESPONDENCE TO DESCRIPTION. YOU + * ASSUME THE ENTIRE RISK ARISING OUT OF USE OR PERFORMANCE OF THE SOFTWARE. + * 3. TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL BROADCOM OR ITS + * LICENSORS BE LIABLE FOR (i) CONSEQUENTIAL, INCIDENTAL, SPECIAL, INDIRECT, + * OR EXEMPLARY DAMAGES WHATSOEVER ARISING OUT OF OR IN ANY WAY RELATING TO + * YOUR USE OF OR INABILITY TO USE THE SOFTWARE EVEN IF BROADCOM HAS BEEN + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGES; OR (ii) ANY AMOUNT IN EXCESS + * OF THE AMOUNT ACTUALLY PAID FOR THE SOFTWARE ITSELF OR U.S. $1, WHICHEVER + * IS GREATER. THESE LIMITATIONS SHALL APPLY NOTWITHSTANDING ANY FAILURE OF + * ESSENTIAL PURPOSE OF ANY LIMITED REMEDY. + *****************************************************************************/ + +#include "interface/vcos/vcos.h" + +#if defined( __KERNEL__ ) +#include +#include +#else +#include +#endif + +#include + +/** Like vsnprintf, except it places the output at the specified offset. + * Output is truncated to fit in buflen bytes, and is guaranteed to be NUL-terminated. + * Returns the string length before/without truncation. + */ +size_t vcos_safe_vsprintf(char *buf, size_t buflen, size_t offset, const char *fmt, va_list ap) +{ + size_t space = (offset < buflen) ? (buflen - offset) : 0; + + offset += vcos_vsnprintf(buf ? (buf + offset) : NULL, space, fmt, ap); + + return offset; +} + +/** Like snprintf, except it places the output at the specified offset. + * Output is truncated to fit in buflen bytes, and is guaranteed to be NUL-terminated. + * Returns the string length before/without truncation. + */ +size_t vcos_safe_sprintf(char *buf, size_t buflen, size_t offset, const char *fmt, ...) +{ + size_t space = (offset < buflen) ? (buflen - offset) : 0; + va_list ap; + + va_start(ap, fmt); + + offset += vcos_vsnprintf(buf ? (buf + offset) : NULL, space, fmt, ap); + + va_end(ap); + + return offset; +} + +/** Copies string src to dst at the specified offset. + * Output is truncated to fit in dstlen bytes, i.e. the string is at most + * (buflen - 1) characters long. Unlike strncpy, exactly one NUL is written + * to dst, which is always NUL-terminated. + * Returns the string length before/without truncation. + */ +size_t vcos_safe_strcpy(char *dst, const char *src, size_t dstlen, size_t offset) +{ + if (offset < dstlen) + { + const char *p = src; + char *endp = dst + dstlen -1; + + dst += offset; + + for (; *p!='\0' && dst != endp; dst++, p++) + *dst = *p; + *dst = '\0'; + } + offset += strlen(src); + + return offset; +} diff --git a/external_src/raspicam-0.1.3/dependencies/vcos/generic/vcos_generic_tls.h b/external_src/raspicam-0.1.3/dependencies/vcos/generic/vcos_generic_tls.h new file mode 100644 index 0000000..6460ae7 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/vcos/generic/vcos_generic_tls.h @@ -0,0 +1,164 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. +*/ + +/*============================================================================= +VideoCore OS Abstraction Layer - generic thread local storage +=============================================================================*/ + +#ifndef VCOS_GENERIC_TLS_H +#define VCOS_GENERIC_TLS_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "interface/vcos/vcos_types.h" + +/** + * \file + * + * Do an emulation of Thread Local Storage. The platform needs to + * provide a way to set and get a per-thread pointer which is + * where the TLS data itself is stored. + * + * + * Each thread that wants to join in this scheme needs to call + * vcos_tls_thread_register(). + * + * The platform needs to support the macros/functions + * _vcos_tls_thread_ptr_set() and _vcos_tls_thread_ptr_get(). + */ + +#ifndef VCOS_WANT_TLS_EMULATION +#error Should not be included unless TLS emulation is defined +#endif + +/** Number of slots to reserve per thread. This results in an overhead + * of this many words per thread. + */ +#define VCOS_TLS_MAX_SLOTS 4 + +/** TLS key. Allocating one of these reserves the client one of the + * available slots. + */ +typedef VCOS_UNSIGNED VCOS_TLS_KEY_T; + +/** TLS per-thread structure. Each thread gets one of these + * if TLS emulation (rather than native TLS support) is + * being used. + */ +typedef struct VCOS_TLS_THREAD_T +{ + void *slots[VCOS_TLS_MAX_SLOTS]; +} VCOS_TLS_THREAD_T; + +/* + * Internal APIs + */ + +/** Register this thread's TLS storage area. */ +VCOSPRE_ void VCOSPOST_ vcos_tls_thread_register(VCOS_TLS_THREAD_T *); + +/** Create a new TLS key */ +VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_generic_tls_create(VCOS_TLS_KEY_T *key); + +/** Delete a TLS key */ +VCOSPRE_ void VCOSPOST_ vcos_generic_tls_delete(VCOS_TLS_KEY_T tls); + +/** Initialise the TLS library */ +VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_tls_init(void); + +/** Deinitialise the TLS library */ +VCOSPRE_ void VCOSPOST_ vcos_tls_deinit(void); + +#if defined(VCOS_INLINE_BODIES) + +#undef VCOS_ASSERT_LOGGING_DISABLE +#define VCOS_ASSERT_LOGGING_DISABLE 1 + +/* + * Implementations of public API functions + */ + +/** Set the given value. Since everything is per-thread, there is no need + * for any locking. + */ +VCOS_INLINE_IMPL +VCOS_STATUS_T vcos_tls_set(VCOS_TLS_KEY_T tls, void *v) { + VCOS_TLS_THREAD_T *tlsdata = _vcos_tls_thread_ptr_get(); + vcos_assert(tlsdata); /* Fires if this thread has not been registered */ + if (tlsslots[tls] = v; + return VCOS_SUCCESS; + } + else + { + vcos_assert(0); + return VCOS_EINVAL; + } +} + +/** Get the given value. No locking required. + */ +VCOS_INLINE_IMPL +void *vcos_tls_get(VCOS_TLS_KEY_T tls) { + VCOS_TLS_THREAD_T *tlsdata = _vcos_tls_thread_ptr_get(); + vcos_assert(tlsdata); /* Fires if this thread has not been registered */ + if (tlsslots[tls]; + } + else + { + vcos_assert(0); + return NULL; + } +} + +VCOS_INLINE_IMPL +VCOS_STATUS_T vcos_tls_create(VCOS_TLS_KEY_T *key) { + return vcos_generic_tls_create(key); +} + +VCOS_INLINE_IMPL +void vcos_tls_delete(VCOS_TLS_KEY_T tls) { + vcos_generic_tls_delete(tls); +} + +#undef VCOS_ASSERT_LOGGING_DISABLE +#define VCOS_ASSERT_LOGGING_DISABLE 0 + +#endif /* VCOS_INLINE_BODIES */ + +#ifdef __cplusplus +} +#endif + +#endif + + diff --git a/external_src/raspicam-0.1.3/dependencies/vcos/generic/vcos_init.c b/external_src/raspicam-0.1.3/dependencies/vcos/generic/vcos_init.c new file mode 100644 index 0000000..6f4c1bb --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/vcos/generic/vcos_init.c @@ -0,0 +1,84 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. +*/ + +/* +The following header is included in order to provide one instance of the symbol vcos_deprecated_code. +Any other inclusions of this header (or "vcos_deprecated_code.inc" for assembly language) will cause the linker to warn +about multiple definitions of vcos_deprecated_code. +The idea is to include this header file for the source files which are deprecated. +Therefore the above warnning in a build indicates that the build is using deprecated code! +Contact the person named in the accompanying comment for advice - do not remove the inclusion. +*/ +#include "vcos_deprecated.h" + +#include "interface/vcos/vcos.h" + +static int init_refcount; + +VCOS_STATUS_T vcos_init(void) +{ + VCOS_STATUS_T st = VCOS_SUCCESS; + + vcos_global_lock(); + + if (init_refcount++ == 0) + st = vcos_platform_init(); + + vcos_global_unlock(); + + return st; +} + +void vcos_deinit(void) +{ + vcos_global_lock(); + + vcos_assert(init_refcount > 0); + + if (init_refcount > 0 && --init_refcount == 0) + vcos_platform_deinit(); + + vcos_global_unlock(); +} + +#if defined(__GNUC__) && (__GNUC__ > 2) + +void vcos_ctor(void) __attribute__((constructor, used)); + +void vcos_ctor(void) +{ + vcos_init(); +} + +void vcos_dtor(void) __attribute__((destructor, used)); + +void vcos_dtor(void) +{ + vcos_deinit(); +} + +#endif diff --git a/external_src/raspicam-0.1.3/dependencies/vcos/generic/vcos_joinable_thread_from_plain.h b/external_src/raspicam-0.1.3/dependencies/vcos/generic/vcos_joinable_thread_from_plain.h new file mode 100644 index 0000000..4471168 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/vcos/generic/vcos_joinable_thread_from_plain.h @@ -0,0 +1,229 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. +*/ + +/*============================================================================= +VideoCore OS Abstraction Layer - implementation: joinable thread from plain +=============================================================================*/ + +/** \file + * + * Header file for platforms creating the joinable thread from a lowlevel + * thread. + * + * In addition to the actual thread, the following are also created: + * + * - a semaphore to wait on when joining the thread + * - a semaphore to support counted suspend/resume (used by event group) + * - a per-thread timer (used by event group, but could be removed) + */ + +#ifndef VCOS_JOINABLE_THREAD_FROM_PLAIN_H +#define VCOS_JOINABLE_THREAD_FROM_PLAIN_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef VCOS_SEMAPHORE_H +#include "interface/vcos/vcos_semaphore.h" +#endif +#ifndef VCOS_LOWLEVEL_THREAD_H +#include "interface/vcos/vcos_lowlevel_thread.h" +#endif +#ifndef VCOS_TIMER_H +#include "interface/vcos/vcos_timer.h" +#endif + +#ifdef VCOS_WANT_TLS_EMULATION +#include "interface/vcos/generic/vcos_generic_tls.h" +#endif + +#define VCOS_THREAD_MAGIC 0x56436a74 + +#define VCOS_THREAD_VALID(t) (t->magic == VCOS_THREAD_MAGIC) +#define VCOS_HAVE_THREAD_AT_EXIT 1 + +/** Thread attribute structure. Clients should not manipulate this directly, but + * should instead use the provided functions. + */ +typedef struct VCOS_THREAD_ATTR_T +{ + void *ta_stackaddr; + VCOS_UNSIGNED ta_stacksz; + VCOS_UNSIGNED ta_priority; + VCOS_UNSIGNED ta_affinity; + VCOS_UNSIGNED ta_timeslice; + VCOS_UNSIGNED legacy; + VCOS_UNSIGNED ta_autostart; +} VCOS_THREAD_ATTR_T; + +/** Each thread gets a timer, which is for internal VCOS use. + */ +typedef struct _VCOS_THREAD_TIMER_T +{ + VCOS_TIMER_T timer; + void (*pfn)(void *); + void *cxt; +} _VCOS_THREAD_TIMER_T; + +typedef void (*VCOS_THREAD_EXIT_HANDLER_T)(void *); +/** Called at thread exit. + */ +typedef struct VCOS_THREAD_EXIT_T +{ + VCOS_THREAD_EXIT_HANDLER_T pfn; + void *cxt; +} VCOS_THREAD_EXIT_T; +#define VCOS_MAX_EXIT_HANDLERS 8 + +/* The name field isn't used for anything, so we can just copy the + * the pointer. Nucleus makes its own copy. + */ +typedef const char * VCOS_LLTHREAD_T_NAME; +#define _VCOS_LLTHREAD_NAME(dst,src) (dst)=(src) + +/* + * Simulated TLS support + */ + + +/** Thread structure. + * + * \warning Do not access the members of this structure directly! + */ +typedef struct VCOS_THREAD_T +{ + VCOS_LLTHREAD_T thread; /**< The underlying thread */ + char name[16]; /**< The name */ + unsigned int magic; /**< For debug */ + void *exit_data; /**< Exit data passed out in vcos_joinable_thread_exit() */ + void *stack; /**< Stack, if not supplied by caller */ + VCOS_SEMAPHORE_T wait; /**< Semaphore to wait on at join */ + VCOS_SEMAPHORE_T suspend; /**< Semaphore to wait on for counted suspend */ + int16_t joined; /**< Joined yet? For debug. */ + VCOS_UNSIGNED legacy; /**< Use (argc,argv) for entry point arguments */ + void *(*entry)(void*); /**< Entry point */ + void *arg; /**< Argument passed to entry point */ + void *(*term)(void*); /**< Termination function, used by reaper */ + void *term_arg; /**< Argument passed to termination function */ + _VCOS_THREAD_TIMER_T _timer; /**< Internal timer, mainly for event groups */ +#ifdef VCOS_WANT_TLS_EMULATION + VCOS_TLS_THREAD_T _tls; /**< TLS data when native TLS not available, or NULL */ +#endif + /** Array of functions to call at thread exit */ + VCOS_THREAD_EXIT_T at_exit[VCOS_MAX_EXIT_HANDLERS]; + + struct VCOS_THREAD_T *next; /**< For linked lists of threads */ +} VCOS_THREAD_T; + +#if defined(VCOS_INLINE_BODIES) + +VCOS_INLINE_IMPL +void vcos_thread_attr_setstack(VCOS_THREAD_ATTR_T *attrs, void *addr, VCOS_UNSIGNED stacksz) { + attrs->ta_stackaddr = addr; + attrs->ta_stacksz = stacksz; +} + +VCOS_INLINE_IMPL +void vcos_thread_attr_setstacksize(VCOS_THREAD_ATTR_T *attrs, VCOS_UNSIGNED stacksz) { + attrs->ta_stacksz = stacksz; +} + +VCOS_INLINE_IMPL +void vcos_thread_attr_setpriority(VCOS_THREAD_ATTR_T *attrs, VCOS_UNSIGNED pri) { + attrs->ta_priority = pri; +} + +VCOS_INLINE_IMPL +void vcos_thread_attr_setaffinity(VCOS_THREAD_ATTR_T *attrs, VCOS_UNSIGNED affinity) { + attrs->ta_affinity = affinity; +} + +VCOS_INLINE_IMPL +void vcos_thread_attr_settimeslice(VCOS_THREAD_ATTR_T *attrs, VCOS_UNSIGNED ts) { + attrs->ta_timeslice = ts; +} + +VCOS_INLINE_IMPL +void _vcos_thread_attr_setlegacyapi(VCOS_THREAD_ATTR_T *attrs, VCOS_UNSIGNED legacy) { + attrs->legacy = legacy; +} + +VCOS_INLINE_IMPL +void vcos_thread_attr_setautostart(VCOS_THREAD_ATTR_T *attrs, VCOS_UNSIGNED autostart) { + attrs->ta_autostart = autostart; +} + +VCOS_INLINE_IMPL +VCOS_THREAD_T *vcos_thread_current(void) { + VCOS_THREAD_T *ret = (VCOS_THREAD_T*)vcos_llthread_current(); + /*If we're called from a non-vcos thread, this assert will fail. + *XXX FIXME why is this commented out? + *vcos_assert(ret->magic == VCOS_THREAD_MAGIC); + */ + return ret; +} + +VCOS_INLINE_IMPL +int vcos_thread_running(VCOS_THREAD_T *thread) { + return vcos_llthread_running(&thread->thread); +} + +VCOS_INLINE_IMPL +void vcos_thread_resume(VCOS_THREAD_T *thread) { + vcos_llthread_resume(&thread->thread); +} + +#endif /* VCOS_INLINE_BODIES */ + +/** + * \brief Create a VCOS_THREAD_T for the current thread. This is so we can have + * VCOS_THREAD_Ts even for threads not originally created by VCOS (eg the + * thread that calls vcos_init) + */ +extern VCOS_STATUS_T _vcos_thread_create_attach(VCOS_THREAD_T *thread, + const char *name); + +/** + * \brief Deletes the VCOS_THREAD_T, but does not wait for the underlying + * thread to exit. This will cleanup everything created by + * _vcos_thread_create_attach + */ +extern void _vcos_thread_delete(VCOS_THREAD_T *thread); + +/** Register a function to be called when the current thread exits. + */ +extern VCOS_STATUS_T vcos_thread_at_exit(void (*pfn)(void*), void *cxt); + +/** Deregister a previously registered at-exit function. + */ +extern void vcos_thread_deregister_at_exit(void (*pfn)(void*), void *cxt); + +#ifdef __cplusplus +} +#endif +#endif /* VCOS_JOINABLE_THREAD_FROM_PLAIN_H */ diff --git a/external_src/raspicam-0.1.3/dependencies/vcos/generic/vcos_latch_from_sem.h b/external_src/raspicam-0.1.3/dependencies/vcos/generic/vcos_latch_from_sem.h new file mode 100644 index 0000000..94f4b13 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/vcos/generic/vcos_latch_from_sem.h @@ -0,0 +1,68 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. +*/ + +/*============================================================================= +VideoCore OS Abstraction Layer - Construct a latch from a semaphore +=============================================================================*/ + +/** FIXME: rename to vcos_mutex_from_sem.c + */ + +typedef struct VCOS_MUTEX_T { + VCOS_SEMAPHORE_T sem; + struct VCOS_THREAD_T *owner; +} VCOS_MUTEX_T; + +extern VCOS_STATUS_T vcos_generic_mutex_create(VCOS_MUTEX_T *latch, const char *name); +extern void vcos_generic_mutex_delete(VCOS_MUTEX_T *latch); +extern VCOS_STATUS_T vcos_generic_mutex_lock(VCOS_MUTEX_T *latch); +extern void vcos_generic_mutex_unlock(VCOS_MUTEX_T *latch); + +#if defined(VCOS_INLINE_BODIES) + +VCOS_INLINE_IMPL +VCOS_STATUS_T vcos_mutex_create(VCOS_MUTEX_T *latch, const char *name) { + return vcos_generic_mutex_create(latch,name); +} + +VCOS_INLINE_IMPL +void vcos_mutex_delete(VCOS_MUTEX_T *latch) { + vcos_generic_mutex_delete(latch); +} + +VCOS_INLINE_IMPL +VCOS_STATUS_T vcos_mutex_lock(VCOS_MUTEX_T *latch) { + return vcos_generic_mutex_lock(latch); +} + +VCOS_INLINE_IMPL +void vcos_mutex_unlock(VCOS_MUTEX_T *latch) { + vcos_generic_mutex_unlock(latch); +} + +#endif /* VCOS_INLINE_BODIES */ + diff --git a/external_src/raspicam-0.1.3/dependencies/vcos/generic/vcos_logcat.c b/external_src/raspicam-0.1.3/dependencies/vcos/generic/vcos_logcat.c new file mode 100644 index 0000000..5dd5fbd --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/vcos/generic/vcos_logcat.c @@ -0,0 +1,587 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. +*/ + +/*============================================================================= +Categorized logging for VCOS - a generic implementation. +=============================================================================*/ + +#include "interface/vcos/vcos.h" +#include "interface/vcos/vcos_ctype.h" +#include "interface/vcos/vcos_string.h" +#include "interface/vcos/vcos_inttypes.h" + +static VCOS_MUTEX_T lock; +static int warned_loglevel; /* only warn about invalid log level once */ +static VCOS_VLOG_IMPL_FUNC_T vcos_vlog_impl_func = vcos_vlog_default_impl; + +#define VCOS_LOG_CATEGORY (&dflt_log_category) +static VCOS_LOG_CAT_T dflt_log_category; +VCOS_LOG_CAT_T *vcos_logging_categories = NULL; +static int inited; + +#if VCOS_HAVE_CMD + +/* + * For kernel or videocore purposes, we generally want the log command. For + * user-space apps, they might want to provide their own log command, so we + * don't include the built in on. + * + * So pthreads/vcos_platform.h defines VCOS_WANT_LOG_CMD to be 0. It is + * undefined elsewhere. + */ + +# if !defined( VCOS_WANT_LOG_CMD ) +# define VCOS_WANT_LOG_CMD 1 +# endif +#else +# define VCOS_WANT_LOG_CMD 0 +#endif + +/* For now, do not link logging categories into linked lists + * as it breaks when people unload shared libraries without + * getting the counts right. + */ +#ifdef __VIDEOCORE__ +#define REGISTER_CATEGORIES 1 +#else +#define REGISTER_CATEGORIES 0 +#endif + +#if VCOS_WANT_LOG_CMD + +/***************************************************************************** +* +* Does a vcos_assert(0), which is useful to test logging. +* +*****************************************************************************/ + +VCOS_STATUS_T vcos_log_assert_cmd( VCOS_CMD_PARAM_T *param ) +{ + (void)param; + +#if defined( NDEBUG ) && !defined( VCOS_RELEASE_ASSERTS ) + vcos_log_error( "vcos_asserts have been compiled out" ); + vcos_cmd_printf( param, "vcos_asserts have been compiled out - did a vcos_log_error instead\n" ); +#else + vcos_assert(0); + vcos_cmd_printf( param, "Executed vcos_assert(0)\n" ); +#endif + + return VCOS_SUCCESS; +} + +/***************************************************************************** +* +* Sets a vcos logging level +* +*****************************************************************************/ + +VCOS_STATUS_T vcos_log_set_cmd( VCOS_CMD_PARAM_T *param ) +{ + VCOS_LOG_CAT_T *cat; + char *name; + char *levelStr; + VCOS_LOG_LEVEL_T level; + VCOS_STATUS_T status; + + if ( param->argc != 3 ) + { + vcos_cmd_usage( param ); + return VCOS_EINVAL; + } + + name = param->argv[1]; + levelStr = param->argv[2]; + + if ( vcos_string_to_log_level( levelStr, &level ) != VCOS_SUCCESS ) + { + vcos_cmd_printf( param, "Unrecognized logging level: '%s'\n", levelStr ); + return VCOS_EINVAL; + } + + vcos_mutex_lock(&lock); + + status = VCOS_SUCCESS; + for ( cat = vcos_logging_categories; cat != NULL; cat = cat->next ) + { + if ( vcos_strcmp( name, cat->name ) == 0 ) + { + cat->level = level; + vcos_cmd_printf( param, "Category %s level set to %s\n", name, levelStr ); + break; + } + } + if ( cat == NULL ) + { + vcos_cmd_printf( param, "Unrecognized category: '%s'\n", name ); + status = VCOS_ENOENT; + } + + vcos_mutex_unlock(&lock); + + return status; +} + +/***************************************************************************** +* +* Prints out the current settings for a given category (or all cvategories) +* +*****************************************************************************/ + +VCOS_STATUS_T vcos_log_status_cmd( VCOS_CMD_PARAM_T *param ) +{ + VCOS_LOG_CAT_T *cat; + VCOS_STATUS_T status; + + vcos_mutex_lock(&lock); + + if ( param->argc == 1) + { + int nw; + int nameWidth = 0; + + /* Print information about all of the categories. */ + + for ( cat = vcos_logging_categories; cat != NULL; cat = cat->next ) + { + nw = (int)strlen( cat->name ); + + if ( nw > nameWidth ) + { + nameWidth = nw; + } + } + + for ( cat = vcos_logging_categories; cat != NULL; cat = cat->next ) + { + vcos_cmd_printf( param, "%-*s - %s\n", nameWidth, cat->name, vcos_log_level_to_string( cat->level )); + } + } + else + { + /* Print information about a particular category */ + + for ( cat = vcos_logging_categories; cat != NULL; cat = cat->next ) + { + if ( vcos_strcmp( cat->name, param->argv[1] ) == 0 ) + { + vcos_cmd_printf( param, "%s - %s\n", cat->name, vcos_log_level_to_string( cat->level )); + break; + } + } + if ( cat == NULL ) + { + vcos_cmd_printf( param, "Unrecognized logging category: '%s'\n", param->argv[1] ); + status = VCOS_ENOENT; + goto out; + } + } + + status = VCOS_SUCCESS; +out: + vcos_mutex_unlock(&lock); + + return status; +} + +/***************************************************************************** +* +* Prints out the current settings for a given category (or all cvategories) +* +*****************************************************************************/ + +VCOS_STATUS_T vcos_log_test_cmd( VCOS_CMD_PARAM_T *param ) +{ + if ( param->argc == 1 ) + { + static int seq_num = 100; + + /* No additional arguments - generate a message with an incrementing number */ + + vcos_log_error( "Test message %d", seq_num ); + + seq_num++; + vcos_cmd_printf( param, "Logged 'Test message %d'\n", seq_num ); + } + else + { + int arg_idx; + + /* Arguments supplied - log these */ + + for ( arg_idx = 0; arg_idx < param->argc; arg_idx++ ) + { + vcos_log_error( "argv[%d] = '%s'", arg_idx, param->argv[arg_idx] ); + } + vcos_cmd_printf( param, "Logged %d line(s) of test data\n", param->argc ); + } + return VCOS_SUCCESS; +} + +/***************************************************************************** +* +* Internal commands +* +*****************************************************************************/ + +static VCOS_CMD_T log_cmd_entry[] = +{ + { "assert", "", vcos_log_assert_cmd, NULL, "Does a vcos_assert(0) to test logging" }, + { "set", "category level", vcos_log_set_cmd, NULL, "Sets the vcos logging level for a category" }, + { "status", "[category]", vcos_log_status_cmd, NULL, "Prints the vcos log status for a (or all) categories" }, + { "test", "[arbitrary text]", vcos_log_test_cmd, NULL, "Does a vcos_log to test logging" }, + + { NULL, NULL, NULL, NULL, NULL } +}; + +static VCOS_CMD_T cmd_log = + { "log", "command [args]", NULL, log_cmd_entry, "Commands related to vcos logging" }; + +#endif + +void vcos_logging_init(void) +{ + if (inited) + { + /* FIXME: should print a warning or something here */ + return; + } + vcos_mutex_create(&lock, "vcos_log"); + + vcos_log_platform_init(); + + vcos_log_register("default", &dflt_log_category); + +#if VCOS_WANT_LOG_CMD + vcos_cmd_register( &cmd_log ); +#endif + + vcos_assert(!inited); + inited = 1; +} + +/** Read an alphanumeric token, returning True if we succeeded. + */ + +static int read_tok(char *tok, size_t toklen, const char **pstr, char sep) +{ + const char *str = *pstr; + size_t n = 0; + char ch; + + /* skip past any whitespace */ + while (str[0] && isspace((int)(str[0]))) + str++; + + while ((ch = *str) != '\0' && + ch != sep && + (isalnum((int)ch) || (ch == '_')) && + n != toklen-1) + { + tok[n++] = ch; + str++; + } + + /* did it work out? */ + if (ch == '\0' || ch == sep) + { + if (ch) str++; /* move to next token if not at end */ + /* yes */ + tok[n] = '\0'; + *pstr = str; + return 1; + } + else + { + /* no */ + return 0; + } +} + +const char *vcos_log_level_to_string( VCOS_LOG_LEVEL_T level ) +{ + switch (level) + { + case VCOS_LOG_UNINITIALIZED: return "uninit"; + case VCOS_LOG_NEVER: return "never"; + case VCOS_LOG_ERROR: return "error"; + case VCOS_LOG_WARN: return "warn"; + case VCOS_LOG_INFO: return "info"; + case VCOS_LOG_TRACE: return "trace"; + } + return "???"; +} + +VCOS_STATUS_T vcos_string_to_log_level( const char *str, VCOS_LOG_LEVEL_T *level ) +{ + if (strcmp(str,"error") == 0) + *level = VCOS_LOG_ERROR; + else if (strcmp(str,"never") == 0) + *level = VCOS_LOG_NEVER; + else if (strcmp(str,"warn") == 0) + *level = VCOS_LOG_WARN; + else if (strcmp(str,"warning") == 0) + *level = VCOS_LOG_WARN; + else if (strcmp(str,"info") == 0) + *level = VCOS_LOG_INFO; + else if (strcmp(str,"trace") == 0) + *level = VCOS_LOG_TRACE; + else + return VCOS_EINVAL; + + return VCOS_SUCCESS; +} + +static int read_level(VCOS_LOG_LEVEL_T *level, const char **pstr, char sep) +{ + char buf[16]; + int ret = 1; + if (read_tok(buf,sizeof(buf),pstr,sep)) + { + if (vcos_string_to_log_level(buf,level) != VCOS_SUCCESS) + { + vcos_log("Invalid trace level '%s'\n", buf); + ret = 0; + } + } + else + { + ret = 0; + } + return ret; +} + +void vcos_log_register(const char *name, VCOS_LOG_CAT_T *category) +{ + const char *env; + VCOS_LOG_CAT_T *i; + + category->name = name; + if ( category->level == VCOS_LOG_UNINITIALIZED ) + { + category->level = VCOS_LOG_ERROR; + } + category->flags.want_prefix = (category != &dflt_log_category ); + + if (!REGISTER_CATEGORIES) + return; + + vcos_mutex_lock(&lock); + + /* is it already registered? */ + for (i = vcos_logging_categories; i ; i = i->next ) + { + if (i == category) + { + i->refcount++; + break; + } + } + + if (!i) + { + /* not yet registered */ + category->next = vcos_logging_categories; + vcos_logging_categories = category; + category->refcount++; + + vcos_log_platform_register(category); + } + + vcos_mutex_unlock(&lock); + + /* Check to see if this log level has been enabled. Look for + * (,)* + * + * VC_LOGLEVEL=ilcs:info,vchiq:warn + */ + + env = _VCOS_LOG_LEVEL(); + if (env) + { + do + { + char env_name[64]; + VCOS_LOG_LEVEL_T level; + if (read_tok(env_name, sizeof(env_name), &env, ':') && + read_level(&level, &env, ',')) + { + if (strcmp(env_name, name) == 0) + { + category->level = level; + break; + } + } + else + { + if (!warned_loglevel) + { + vcos_log("VC_LOGLEVEL format invalid at %s\n", env); + warned_loglevel = 1; + } + return; + } + } while (env[0] != '\0'); + } + + vcos_log_info( "Registered log category '%s' with level %s", + category->name, + vcos_log_level_to_string( category->level )); +} + +void vcos_log_unregister(VCOS_LOG_CAT_T *category) +{ + VCOS_LOG_CAT_T **pcat; + + if (!REGISTER_CATEGORIES) + return; + + vcos_mutex_lock(&lock); + category->refcount--; + if (category->refcount == 0) + { + pcat = &vcos_logging_categories; + while (*pcat != category) + { + if (!*pcat) + break; /* possibly deregistered twice? */ + if ((*pcat)->next == NULL) + { + vcos_assert(0); /* already removed! */ + vcos_mutex_unlock(&lock); + return; + } + pcat = &(*pcat)->next; + } + if (*pcat) + *pcat = category->next; + + vcos_log_platform_unregister(category); + } + vcos_mutex_unlock(&lock); +} + +VCOSPRE_ const VCOS_LOG_CAT_T * VCOSPOST_ vcos_log_get_default_category(void) +{ + return &dflt_log_category; +} + +void vcos_set_log_options(const char *opt) +{ + (void)opt; +} + +void vcos_log_dump_mem_impl( const VCOS_LOG_CAT_T *cat, + const char *label, + uint32_t addr, + const void *voidMem, + size_t numBytes ) +{ + const uint8_t *mem = (const uint8_t *)voidMem; + size_t offset; + char lineBuf[ 100 ]; + char *s; + + while ( numBytes > 0 ) + { + s = lineBuf; + + for ( offset = 0; offset < 16; offset++ ) + { + if ( offset < numBytes ) + { + s += vcos_snprintf( s, 4, "%02x ", mem[ offset ]); + } + else + { + s += vcos_snprintf( s, 4, " " ); + } + } + + for ( offset = 0; offset < 16; offset++ ) + { + if ( offset < numBytes ) + { + uint8_t ch = mem[ offset ]; + + if (( ch < ' ' ) || ( ch > '~' )) + { + ch = '.'; + } + *s++ = (char)ch; + } + } + *s++ = '\0'; + + if (( label != NULL ) && ( *label != '\0' )) + { + vcos_log_impl( cat, VCOS_LOG_INFO, "%s: %08" PRIx32 ": %s", label, addr, lineBuf ); + } + else + { + vcos_log_impl( cat, VCOS_LOG_INFO, "%08" PRIx32 ": %s", addr, lineBuf ); + } + + addr += 16; + mem += 16; + if ( numBytes > 16 ) + { + numBytes -= 16; + } + else + { + numBytes = 0; + } + } + +} + +void vcos_log_impl(const VCOS_LOG_CAT_T *cat, VCOS_LOG_LEVEL_T _level, const char *fmt, ...) +{ + va_list ap; + va_start(ap,fmt); + vcos_vlog_impl( cat, _level, fmt, ap ); + va_end(ap); +} + +void vcos_vlog_impl(const VCOS_LOG_CAT_T *cat, VCOS_LOG_LEVEL_T _level, const char *fmt, va_list args) +{ + vcos_vlog_impl_func( cat, _level, fmt, args ); +} + +void vcos_set_vlog_impl( VCOS_VLOG_IMPL_FUNC_T vlog_impl_func ) +{ + if ( vlog_impl_func == NULL ) + { + vcos_vlog_impl_func = vcos_vlog_default_impl; + } + else + { + vcos_vlog_impl_func = vlog_impl_func; + } +} + diff --git a/external_src/raspicam-0.1.3/dependencies/vcos/generic/vcos_mem_from_malloc.c b/external_src/raspicam-0.1.3/dependencies/vcos/generic/vcos_mem_from_malloc.c new file mode 100644 index 0000000..02f9f28 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/vcos/generic/vcos_mem_from_malloc.c @@ -0,0 +1,98 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. +*/ + +/*============================================================================= +VideoCore OS Abstraction Layer - memory alloc implementation +=============================================================================*/ + +#include "interface/vcos/vcos.h" + +#ifndef _vcos_platform_malloc +#include +#define _vcos_platform_malloc malloc +#define _vcos_platform_free free +#endif + +typedef struct malloc_header_s { + uint32_t guardword; + uint32_t size; + const char *description; + void *ptr; +} MALLOC_HEADER_T; + + +#define MIN_ALIGN sizeof(MALLOC_HEADER_T) + +#define GUARDWORDHEAP 0xa55a5aa5 + +void *vcos_generic_mem_alloc_aligned(VCOS_UNSIGNED size, VCOS_UNSIGNED align, const char *desc) +{ + int local_align = align == 0 ? 1 : align; + int required_size = size + local_align + sizeof(MALLOC_HEADER_T); + void *ptr = _vcos_platform_malloc(required_size); + void *ret = NULL; + MALLOC_HEADER_T *h; + + if (ptr) + { + ret = (void *)VCOS_ALIGN_UP(((char *)ptr)+sizeof(MALLOC_HEADER_T), local_align); + h = ((MALLOC_HEADER_T *)ret)-1; + h->size = size; + h->description = desc; + h->guardword = GUARDWORDHEAP; + h->ptr = ptr; + } + + return ret; +} + +void *vcos_generic_mem_alloc(VCOS_UNSIGNED size, const char *desc) +{ + return vcos_generic_mem_alloc_aligned(size,MIN_ALIGN,desc); +} + +void *vcos_generic_mem_calloc(VCOS_UNSIGNED count, VCOS_UNSIGNED sz, const char *desc) +{ + uint32_t size = count*sz; + void *ptr = vcos_generic_mem_alloc_aligned(size,MIN_ALIGN,desc); + if (ptr) + { + memset(ptr, 0, size); + } + return ptr; +} + +void vcos_generic_mem_free(void *ptr) +{ + MALLOC_HEADER_T *h; + if (! ptr) return; + + h = ((MALLOC_HEADER_T *)ptr)-1; + vcos_assert(h->guardword == GUARDWORDHEAP); + _vcos_platform_free(h->ptr); +} + diff --git a/external_src/raspicam-0.1.3/dependencies/vcos/generic/vcos_mem_from_malloc.h b/external_src/raspicam-0.1.3/dependencies/vcos/generic/vcos_mem_from_malloc.h new file mode 100644 index 0000000..401a4fc --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/vcos/generic/vcos_mem_from_malloc.h @@ -0,0 +1,74 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. +*/ + +/*============================================================================= +Create the vcos_malloc API from the regular system malloc/free +=============================================================================*/ + +/** + * \file + * + * Create the vcos malloc API from a regular system malloc/free library. + * + * The API lets callers specify an alignment. + * + * Under VideoCore this is not needed, as we can simply use the rtos_malloc routines. + * But on host platforms that won't be the case. + * + */ + +VCOSPRE_ void * VCOSPOST_ vcos_generic_mem_alloc(VCOS_UNSIGNED sz, const char *desc); +VCOSPRE_ void * VCOSPOST_ vcos_generic_mem_calloc(VCOS_UNSIGNED count, VCOS_UNSIGNED sz, const char *descr); +VCOSPRE_ void VCOSPOST_ vcos_generic_mem_free(void *ptr); +VCOSPRE_ void * VCOSPOST_ vcos_generic_mem_alloc_aligned(VCOS_UNSIGNED sz, VCOS_UNSIGNED align, const char *desc); + +#ifdef VCOS_INLINE_BODIES + +VCOS_INLINE_IMPL +void *vcos_malloc(VCOS_UNSIGNED size, const char *description) { + return vcos_generic_mem_alloc(size, description); +} + +VCOS_INLINE_IMPL +void *vcos_calloc(VCOS_UNSIGNED num, VCOS_UNSIGNED size, const char *description) { + return vcos_generic_mem_calloc(num, size, description); +} + +VCOS_INLINE_IMPL +void vcos_free(void *ptr) { + vcos_generic_mem_free(ptr); +} + +VCOS_INLINE_IMPL +void * vcos_malloc_aligned(VCOS_UNSIGNED size, VCOS_UNSIGNED align, const char *description) { + return vcos_generic_mem_alloc_aligned(size, align, description); +} + + +#endif /* VCOS_INLINE_BODIES */ + + diff --git a/external_src/raspicam-0.1.3/dependencies/vcos/generic/vcos_msgqueue.c b/external_src/raspicam-0.1.3/dependencies/vcos/generic/vcos_msgqueue.c new file mode 100644 index 0000000..b8e558b --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/vcos/generic/vcos_msgqueue.c @@ -0,0 +1,389 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 "vcos.h" +#include "vcos_msgqueue.h" +#include +#include +#include + +#define MAGIC VCOS_MSGQ_MAGIC + +/* Probably a good idea for MSG_T to be multiple of 8 so that doubles + * are naturally aligned without problem. + */ +vcos_static_assert((sizeof(VCOS_MSG_T) & 7) == 0); + +static void vcos_msgq_pool_on_reply(VCOS_MSG_WAITER_T *waiter, + VCOS_MSG_T *msg); +static void vcos_msgq_queue_waiter_on_reply(VCOS_MSG_WAITER_T *waiter, + VCOS_MSG_T *msg); + +/** Simple reply protocol. The client creates a semaphore and waits + * for it. No queuing of multiple replies is possible but nothing needs + * to be setup in advance. Because creating semaphores is very fast on + * VideoCore there's no need to do anything elaborate to optimize create + * time - this might need revisiting on other platforms. + */ + +typedef struct +{ + VCOS_MSG_WAITER_T waiter; + VCOS_SEMAPHORE_T waitsem; +} VCOS_MSG_SIMPLE_WAITER_T; + +static void vcos_msgq_simple_waiter_on_reply(VCOS_MSG_WAITER_T *waiter, + VCOS_MSG_T *msg) +{ + VCOS_MSG_SIMPLE_WAITER_T *self; + (void)msg; + self = (VCOS_MSG_SIMPLE_WAITER_T*)waiter; + vcos_semaphore_post(&self->waitsem); +} + +static VCOS_STATUS_T vcos_msgq_simple_waiter_init(VCOS_MSG_SIMPLE_WAITER_T *waiter) +{ + VCOS_STATUS_T status; + status = vcos_semaphore_create(&waiter->waitsem, "waiter", 0); + waiter->waiter.on_reply = vcos_msgq_simple_waiter_on_reply; + return status; +} + +static void vcos_msgq_simple_waiter_deinit(VCOS_MSG_SIMPLE_WAITER_T *waiter) +{ + vcos_semaphore_delete(&waiter->waitsem); +} + +/* + * Message queues + */ + +static VCOS_STATUS_T vcos_msgq_create_internal(VCOS_MSGQUEUE_T *q, const char *name) +{ + VCOS_STATUS_T st; + + memset(q, 0, sizeof(*q)); + + q->waiter.on_reply = vcos_msgq_queue_waiter_on_reply; + st = vcos_semaphore_create(&q->sem, name, 0); + if (st != VCOS_SUCCESS) + goto fail_sem; + + st = vcos_mutex_create(&q->lock, name); + if (st != VCOS_SUCCESS) + goto fail_mtx; + + return st; + +fail_mtx: + vcos_semaphore_delete(&q->sem); +fail_sem: + return st; +} + +static void vcos_msgq_delete_internal(VCOS_MSGQUEUE_T *q) +{ + vcos_semaphore_delete(&q->sem); + vcos_mutex_delete(&q->lock); +} + +VCOS_STATUS_T vcos_msgq_create(VCOS_MSGQUEUE_T *q, const char *name) +{ + VCOS_STATUS_T st; + + st = vcos_msgq_create_internal(q, name); + + return st; +} + +void vcos_msgq_delete(VCOS_MSGQUEUE_T *q) +{ + vcos_msgq_delete_internal(q); +} + +/* append a message to a message queue */ +static _VCOS_INLINE void msgq_append(VCOS_MSGQUEUE_T *q, VCOS_MSG_T *msg) +{ + vcos_mutex_lock(&q->lock); + if (q->head == NULL) + { + q->head = q->tail = msg; + } + else + { + q->tail->next = msg; + q->tail = msg; + } + vcos_mutex_unlock(&q->lock); +} + +/* + * A waiter for a message queue. Just appends the message to the + * queue, waking up the waiting thread. + */ +static void vcos_msgq_queue_waiter_on_reply(VCOS_MSG_WAITER_T *waiter, + VCOS_MSG_T *msg) +{ + VCOS_MSGQUEUE_T *queue = (VCOS_MSGQUEUE_T*)waiter; + msgq_append(queue, msg); + vcos_semaphore_post(&queue->sem); +} + +/* initialise this library */ + +VCOS_STATUS_T vcos_msgq_init(void) +{ + return VCOS_SUCCESS; +} + +void vcos_msgq_deinit(void) +{ +} + +static _VCOS_INLINE +void vcos_msg_send_helper(VCOS_MSG_WAITER_T *waiter, + VCOS_MSGQUEUE_T *dest, + uint32_t code, + VCOS_MSG_T *msg) +{ + vcos_assert(msg); + vcos_assert(dest); + + msg->code = code; + if (waiter) + msg->waiter = waiter; + msg->next = NULL; + msg->src_thread = vcos_thread_current(); + + msgq_append(dest, msg); + vcos_semaphore_post(&dest->sem); +} + +/* wait on a queue for a message */ +VCOS_MSG_T *vcos_msg_wait(VCOS_MSGQUEUE_T *queue) +{ + VCOS_MSG_T *msg; + vcos_semaphore_wait(&queue->sem); + vcos_mutex_lock(&queue->lock); + + msg = queue->head; + vcos_assert(msg); /* should always be a message here! */ + + queue->head = msg->next; + if (queue->head == NULL) + queue->tail = NULL; + + vcos_mutex_unlock(&queue->lock); + return msg; +} + +/* peek on a queue for a message */ +VCOS_MSG_T *vcos_msg_peek(VCOS_MSGQUEUE_T *queue) +{ + VCOS_MSG_T *msg; + vcos_mutex_lock(&queue->lock); + + msg = queue->head; + + /* if there's a message, remove it from the queue */ + if (msg) + { + queue->head = msg->next; + if (queue->head == NULL) + queue->tail = NULL; + + /* keep the semaphore count consistent */ + + /* coverity[lock_order] + * the semaphore must have a non-zero count so cannot block here. + */ + vcos_semaphore_wait(&queue->sem); + } + + vcos_mutex_unlock(&queue->lock); + return msg; +} + +void vcos_msg_send(VCOS_MSGQUEUE_T *dest, uint32_t code, VCOS_MSG_T *msg) +{ + vcos_assert(msg->magic == MAGIC); + vcos_msg_send_helper(NULL, dest, code, msg); +} + +/** Send on to the target queue, then wait on a simple waiter for the reply + */ +VCOS_STATUS_T vcos_msg_sendwait(VCOS_MSGQUEUE_T *dest, uint32_t code, VCOS_MSG_T *msg) +{ + VCOS_STATUS_T st; + VCOS_MSG_SIMPLE_WAITER_T waiter; + + vcos_assert(msg->magic == MAGIC); + + /* if this fires, you've set a waiter up but are now about to obliterate it + * with the 'wait for a reply' waiter. + */ + vcos_assert(msg->waiter == NULL); + + if ((st=vcos_msgq_simple_waiter_init(&waiter)) != VCOS_SUCCESS) + return st; + + vcos_msg_send_helper(&waiter.waiter, dest, code, msg); + vcos_semaphore_wait(&waiter.waitsem); + vcos_msgq_simple_waiter_deinit(&waiter); + + return VCOS_SUCCESS; +} + +/** Send a reply to a message + */ +void vcos_msg_reply(VCOS_MSG_T *msg) +{ + vcos_assert(msg->magic == MAGIC); + msg->code |= MSG_REPLY_BIT; + if (msg->waiter) + { + msg->waiter->on_reply(msg->waiter, msg); + } + else + { + VCOS_ALERT("%s: reply to non-reply message id %d", + VCOS_FUNCTION, + msg->code); + vcos_assert(0); + } +} + +void vcos_msg_set_source(VCOS_MSG_T *msg, VCOS_MSGQUEUE_T *queue) +{ + vcos_assert(msg); + vcos_assert(msg->magic == MAGIC); + vcos_assert(queue); + msg->waiter = &queue->waiter; +} + +/* + * Message pools + */ + +VCOS_STATUS_T vcos_msgq_pool_create(VCOS_MSGQ_POOL_T *pool, + size_t count, + size_t payload_size, + const char *name) +{ + VCOS_STATUS_T status; + int bp_size = payload_size + sizeof(VCOS_MSG_T); + status = vcos_blockpool_create_on_heap(&pool->blockpool, + count, bp_size, + VCOS_BLOCKPOOL_ALIGN_DEFAULT, + 0, + name); + if (status != VCOS_SUCCESS) + goto fail_pool; + + status = vcos_semaphore_create(&pool->sem, name, count); + if (status != VCOS_SUCCESS) + goto fail_sem; + + pool->waiter.on_reply = vcos_msgq_pool_on_reply; + pool->magic = MAGIC; + return status; + +fail_sem: + vcos_blockpool_delete(&pool->blockpool); +fail_pool: + return status; +} + +void vcos_msgq_pool_delete(VCOS_MSGQ_POOL_T *pool) +{ + vcos_blockpool_delete(&pool->blockpool); + vcos_semaphore_delete(&pool->sem); +} + +/** Called when a message from a pool is replied-to. Just returns + * the message back to the blockpool. + */ +static void vcos_msgq_pool_on_reply(VCOS_MSG_WAITER_T *waiter, + VCOS_MSG_T *msg) +{ + vcos_unused(waiter); + vcos_assert(msg->magic == MAGIC); + vcos_msgq_pool_free(msg); +} + +VCOS_MSG_T *vcos_msgq_pool_alloc(VCOS_MSGQ_POOL_T *pool) +{ + VCOS_MSG_T *msg; + if (vcos_semaphore_trywait(&pool->sem) == VCOS_SUCCESS) + { + msg = vcos_blockpool_calloc(&pool->blockpool); + vcos_assert(msg); + msg->magic = MAGIC; + msg->waiter = &pool->waiter; + msg->pool = pool; + } + else + { + msg = NULL; + } + return msg; +} + +void vcos_msgq_pool_free(VCOS_MSG_T *msg) +{ + if (msg) + { + VCOS_MSGQ_POOL_T *pool; + vcos_assert(msg->pool); + + pool = msg->pool; + vcos_assert(msg->pool->magic == MAGIC); + + vcos_blockpool_free(msg); + vcos_semaphore_post(&pool->sem); + } +} + +VCOS_MSG_T *vcos_msgq_pool_wait(VCOS_MSGQ_POOL_T *pool) +{ + VCOS_MSG_T *msg; + vcos_semaphore_wait(&pool->sem); + msg = vcos_blockpool_calloc(&pool->blockpool); + vcos_assert(msg); + msg->magic = MAGIC; + msg->waiter = &pool->waiter; + msg->pool = pool; + return msg; +} + +void vcos_msg_init(VCOS_MSG_T *msg) +{ + msg->magic = MAGIC; + msg->next = NULL; + msg->waiter = NULL; + msg->pool = NULL; +} diff --git a/external_src/raspicam-0.1.3/dependencies/vcos/generic/vcos_mutexes_are_reentrant.h b/external_src/raspicam-0.1.3/dependencies/vcos/generic/vcos_mutexes_are_reentrant.h new file mode 100644 index 0000000..976b61a --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/vcos/generic/vcos_mutexes_are_reentrant.h @@ -0,0 +1,88 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. +*/ + +/*============================================================================= +VideoCore OS Abstraction Layer - reentrant mutexes mapped directly to regular ones +=============================================================================*/ + +#ifndef VCOS_GENERIC_REENTRANT_MUTEX_H +#define VCOS_GENERIC_REENTRANT_MUTEX_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "interface/vcos/vcos_types.h" +#include "interface/vcos/vcos_mutex.h" + +/** + * \file + * + * Reentrant Mutexes directly using the native re-entrant mutex. + * + */ + +typedef VCOS_MUTEX_T VCOS_REENTRANT_MUTEX_T; + +/* Inline forwarding functions */ + +#if defined(VCOS_INLINE_BODIES) + +VCOS_INLINE_IMPL +VCOS_STATUS_T vcos_reentrant_mutex_create(VCOS_REENTRANT_MUTEX_T *m, const char *name) { + return vcos_mutex_create(m,name); +} + +VCOS_INLINE_IMPL +void vcos_reentrant_mutex_delete(VCOS_REENTRANT_MUTEX_T *m) { + vcos_mutex_delete(m); +} + +VCOS_INLINE_IMPL +void vcos_reentrant_mutex_lock(VCOS_REENTRANT_MUTEX_T *m) { + vcos_mutex_lock(m); +} + +VCOS_INLINE_IMPL +void vcos_reentrant_mutex_unlock(VCOS_REENTRANT_MUTEX_T *m) { + vcos_mutex_unlock(m); +} + +VCOS_INLINE_IMPL +int vcos_reentrant_mutex_is_locked(VCOS_REENTRANT_MUTEX_T *m) { + return vcos_mutex_is_locked(m); +} + +#endif + +#ifdef __cplusplus +} +#endif +#endif + + + diff --git a/external_src/raspicam-0.1.3/dependencies/vcos/generic/vcos_thread_reaper.h b/external_src/raspicam-0.1.3/dependencies/vcos/generic/vcos_thread_reaper.h new file mode 100644 index 0000000..4190dba --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/vcos/generic/vcos_thread_reaper.h @@ -0,0 +1,55 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. +*/ + +/*============================================================================= +VideoCore OS Abstraction Layer - thread reaping +=============================================================================*/ + +#ifndef VCOS_THREAD_REAPER_H +#define VCOS_THREAD_REAPER_H + +#define VCOS_HAVE_THREAD_REAPER + +/** Initialise the thread reaper. + */ +VCOS_STATUS_T vcos_thread_reaper_init(void); + +/** Reap a thread. Arranges for the thread to be automatically + * joined. + * + * @sa vcos_thread_join(). + * + * @param thread the thread to terminate + * @param on_terminated called after the thread has exited + * @param cxt pass back to the callback + * + */ +void vcos_thread_reap(VCOS_THREAD_T *thread, void (*on_terminated)(void*), void *cxt); + +#endif + + diff --git a/external_src/raspicam-0.1.3/dependencies/vcos/glibc/vcos_backtrace.c b/external_src/raspicam-0.1.3/dependencies/vcos/glibc/vcos_backtrace.c new file mode 100644 index 0000000..3bb8aa3 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/vcos/glibc/vcos_backtrace.c @@ -0,0 +1,56 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 +#ifdef HAVE_CMAKE_CONFIG +#include "cmake_config.h" +#endif +#ifdef HAVE_EXECINFO_H +#include +#endif +#include +#include +#include + +void vcos_backtrace_self(void) +{ +#ifdef HAVE_EXECINFO_H + void *stack[64]; + int depth = backtrace(stack, sizeof(stack)/sizeof(stack[0])); + char **names = backtrace_symbols(stack, depth); + int i; + if (names) + { + for (i=0; i + +void *vcos_dlopen(const char *name, int mode) +{ + return dlopen(name, mode); +} + +void (*vcos_dlsym(void *handle, const char *name))(void) +{ + return dlsym(handle, name); +} + +int vcos_dlclose (void *handle) +{ + return dlclose(handle); +} + +int vcos_dlerror(int *err, char *buf, size_t buflen) +{ + /* not really threadsafe! */ + const char *errmsg = dlerror(); + + vcos_assert(buflen > 0); + + if (errmsg) + { + *err = -1; + strncpy(buf, errmsg, buflen); + buf[buflen-1] = '\0'; + } + else + { + *err = 0; + buf[0] = '\0'; + } + return 0; +} + + + + diff --git a/external_src/raspicam-0.1.3/dependencies/vcos/pthreads/vcos_futex_mutex.h b/external_src/raspicam-0.1.3/dependencies/vcos/pthreads/vcos_futex_mutex.h new file mode 100644 index 0000000..3c44720 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/vcos/pthreads/vcos_futex_mutex.h @@ -0,0 +1,102 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. +*/ + +/*============================================================================= +FIXME: This code should be moved to 'linux', it is linux-specific and not generic +on 'pthreads'. +============================================================================*/ + +#ifndef VCOS_MUTEX_FROM_FUTEX_H +#define VCOS_MUTEX_FROM_FUTEX_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "interface/vcos/vcos_types.h" +#include "vcos_platform.h" + +typedef struct VCOS_FUTEX_T +{ + volatile int value; +} VCOS_FUTEX_T; + +typedef VCOS_FUTEX_T VCOS_MUTEX_T; + +VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_futex_init(VCOS_FUTEX_T *futex); +VCOSPRE_ void VCOSPOST_ vcos_futex_delete(VCOS_FUTEX_T *futex); +VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_futex_lock(VCOS_FUTEX_T *futex); +VCOSPRE_ void VCOSPOST_ vcos_futex_unlock(VCOS_FUTEX_T *futex); +VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_futex_trylock(VCOS_FUTEX_T *futex); + +#if defined(VCOS_INLINE_BODIES) + +VCOS_INLINE_IMPL +VCOS_STATUS_T vcos_mutex_create(VCOS_MUTEX_T *latch, const char *name) { + vcos_unused(name); + return vcos_futex_init(latch); +} + +VCOS_INLINE_IMPL +void vcos_mutex_delete(VCOS_MUTEX_T *latch) { + vcos_futex_delete(latch); +} + +VCOS_INLINE_IMPL +VCOS_STATUS_T vcos_mutex_lock(VCOS_MUTEX_T *latch) { + return vcos_futex_lock(latch); +} + +VCOS_INLINE_IMPL +void vcos_mutex_unlock(VCOS_MUTEX_T *latch) { + vcos_futex_unlock(latch); +} + +VCOS_INLINE_IMPL +int vcos_mutex_is_locked(VCOS_MUTEX_T *latch) { + int rc = latch->value; + if (!rc) { + /* it wasn't locked */ + return 0; + } + else { + return 1; /* it was locked */ + } +} + +VCOS_INLINE_IMPL +VCOS_STATUS_T vcos_mutex_trylock(VCOS_MUTEX_T *m) { + return vcos_futex_trylock(m); +} + +#endif /* VCOS_INLINE_BODIES */ + +#ifdef __cplusplus +} +#endif +#endif /* VCOS_MUTEX_FROM_FUTEX_H */ + diff --git a/external_src/raspicam-0.1.3/dependencies/vcos/pthreads/vcos_platform.h b/external_src/raspicam-0.1.3/dependencies/vcos/pthreads/vcos_platform.h new file mode 100755 index 0000000..01d5c01 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/vcos/pthreads/vcos_platform.h @@ -0,0 +1,746 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. +*/ + +/*============================================================================= +VideoCore OS Abstraction Layer - pthreads types +=============================================================================*/ + +/* Do not include this file directly - instead include it via vcos.h */ + +/** @file + * + * Pthreads implementation of VCOS. + * + */ + +#ifndef VCOS_PLATFORM_H +#define VCOS_PLATFORM_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define VCOS_HAVE_RTOS 1 +#define VCOS_HAVE_SEMAPHORE 1 +#define VCOS_HAVE_EVENT 1 +#define VCOS_HAVE_QUEUE 0 +#define VCOS_HAVE_LEGACY_ISR 0 +#define VCOS_HAVE_TIMER 1 +#define VCOS_HAVE_CANCELLATION_SAFE_TIMER 1 +#define VCOS_HAVE_MEMPOOL 0 +#define VCOS_HAVE_ISR 0 +#define VCOS_HAVE_ATOMIC_FLAGS 1 +#define VCOS_HAVE_THREAD_AT_EXIT 1 +#define VCOS_HAVE_ONCE 1 +#define VCOS_HAVE_BLOCK_POOL 1 +#define VCOS_HAVE_FILE 0 +#define VCOS_HAVE_PROC 0 +#define VCOS_HAVE_CFG 0 +#define VCOS_HAVE_ALIEN_THREADS 1 +#define VCOS_HAVE_CMD 1 +#define VCOS_HAVE_EVENT_FLAGS 1 +#define VCOS_WANT_LOG_CMD 0 /* User apps should do their own thing */ + +#define VCOS_ALWAYS_WANT_LOGGING + +#ifdef __linux__ +#define VCOS_HAVE_BACKTRACE 1 +#endif + +#define VCOS_SO_EXT ".so" + +/* Linux/pthreads seems to have different timer characteristics */ +#define VCOS_TIMER_MARGIN_EARLY 0 +#define VCOS_TIMER_MARGIN_LATE 15 + +typedef sem_t VCOS_SEMAPHORE_T; +typedef uint32_t VCOS_UNSIGNED; +typedef uint32_t VCOS_OPTION; +typedef pthread_key_t VCOS_TLS_KEY_T; +typedef pthread_once_t VCOS_ONCE_T; + +typedef struct VCOS_LLTHREAD_T +{ + pthread_t thread; // Must be first field. +} VCOS_LLTHREAD_T; + +/* VCOS_CASSERT(offsetof(VCOS_LLTHREAD_T, thread) == 0); */ + +#ifndef VCOS_USE_VCOS_FUTEX +typedef pthread_mutex_t VCOS_MUTEX_T; +#else +#include "vcos_futex_mutex.h" +#endif /* VCOS_USE_VCOS_FUTEX */ + +typedef struct +{ + VCOS_MUTEX_T mutex; + sem_t sem; +} VCOS_EVENT_T; + +#define VCOS_ONCE_INIT PTHREAD_ONCE_INIT + +typedef struct VCOS_TIMER_T +{ + pthread_t thread; /**< id of the timer thread */ + + pthread_mutex_t lock; /**< lock protecting all other members of the struct */ + pthread_cond_t settings_changed; /**< cond. var. for informing the timer thread about changes*/ + int quit; /**< non-zero if the timer thread is requested to quit*/ + + struct timespec expires; /**< absolute time of next expiration, or 0 if disarmed*/ + + void (*orig_expiration_routine)(void*);/**< the expiration routine provided by the user of the timer*/ + void *orig_context; /**< the context for exp. routine provided by the user*/ + +} VCOS_TIMER_T; + +/** Thread attribute structure. Don't use pthread_attr directly, as + * the calls can fail, and inits must match deletes. + */ +typedef struct VCOS_THREAD_ATTR_T +{ + void *ta_stackaddr; + VCOS_UNSIGNED ta_stacksz; + VCOS_UNSIGNED ta_priority; + VCOS_UNSIGNED ta_affinity; + VCOS_UNSIGNED ta_timeslice; + VCOS_UNSIGNED legacy; +} VCOS_THREAD_ATTR_T; + +/** Called at thread exit. + */ +typedef struct VCOS_THREAD_EXIT_T +{ + void (*pfn)(void *); + void *cxt; +} VCOS_THREAD_EXIT_T; +#define VCOS_MAX_EXIT_HANDLERS 4 + +typedef struct VCOS_THREAD_T +{ + pthread_t thread; /**< The thread itself */ + VCOS_THREAD_ENTRY_FN_T entry; /**< The thread entry point */ + void *arg; /**< The argument to be passed to entry */ + VCOS_SEMAPHORE_T suspend; /**< For support event groups and similar - a per thread semaphore */ + + VCOS_TIMER_T task_timer; + int task_timer_created; /**< non-zero if the task timer has already been created*/ + void (*orig_task_timer_expiration_routine)(void*); + void *orig_task_timer_context; + + VCOS_UNSIGNED legacy; + char name[16]; /**< Record the name of this thread, for diagnostics */ + VCOS_UNSIGNED dummy; /**< Dummy thread created for non-vcos created threads */ + + /** Callback invoked at thread exit time */ + VCOS_THREAD_EXIT_T at_exit[VCOS_MAX_EXIT_HANDLERS]; +} VCOS_THREAD_T; + +#ifdef VCOS_PTHREADS_WANT_HISR_EMULATION + +typedef struct +{ + VCOS_THREAD_T thread; + char stack[1024]; + VCOS_SEMAPHORE_T waitsem; +} VCOS_HISR_T; + +#endif + +#define VCOS_SUSPEND -1 +#define VCOS_NO_SUSPEND 0 + +#define VCOS_START 1 +#define VCOS_NO_START 0 + +#define VCOS_THREAD_PRI_MIN (sched_get_priority_min(SCHED_OTHER)) +#define VCOS_THREAD_PRI_MAX (sched_get_priority_max(SCHED_OTHER)) + +#define VCOS_THREAD_PRI_INCREASE (1) +#define VCOS_THREAD_PRI_HIGHEST VCOS_THREAD_PRI_MAX +#define VCOS_THREAD_PRI_LOWEST VCOS_THREAD_PRI_MIN +#define VCOS_THREAD_PRI_NORMAL ((VCOS_THREAD_PRI_MAX+VCOS_THREAD_PRI_MIN)/2) +#define VCOS_THREAD_PRI_BELOW_NORMAL (VCOS_THREAD_PRI_NORMAL-VCOS_THREAD_PRI_INCREASE) +#define VCOS_THREAD_PRI_ABOVE_NORMAL (VCOS_THREAD_PRI_NORMAL+VCOS_THREAD_PRI_INCREASE) +#define VCOS_THREAD_PRI_REALTIME VCOS_THREAD_PRI_MAX + +#define _VCOS_AFFINITY_DEFAULT 0 +#define _VCOS_AFFINITY_CPU0 0x100 +#define _VCOS_AFFINITY_CPU1 0x200 +#define _VCOS_AFFINITY_MASK 0x300 +#define VCOS_CAN_SET_STACK_ADDR 0 + +#define VCOS_TICKS_PER_SECOND _vcos_get_ticks_per_second() + +#include "generic/vcos_generic_event_flags.h" +#include "generic/vcos_generic_blockpool.h" +#include "generic/vcos_mem_from_malloc.h" + +/** Convert errno values into the values recognized by vcos */ +VCOSPRE_ VCOS_STATUS_T vcos_pthreads_map_error(int error); +VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_pthreads_map_errno(void); + +/** Register a function to be called when the current thread exits. + */ +extern VCOS_STATUS_T vcos_thread_at_exit(void (*pfn)(void*), void *cxt); + +extern uint32_t _vcos_get_ticks_per_second(void); + +/** + * Set to 1 by default when ANDROID is defined. Allows runtime + * switching for console apps. + */ +extern int vcos_use_android_log; + +typedef struct { + VCOS_MUTEX_T mutex; + uint32_t flags; +} VCOS_ATOMIC_FLAGS_T; + +#if defined(VCOS_INLINE_BODIES) + +#undef VCOS_ASSERT_LOGGING_DISABLE +#define VCOS_ASSERT_LOGGING_DISABLE 1 + + +/* + * Counted Semaphores + */ +VCOS_INLINE_IMPL +VCOS_STATUS_T vcos_semaphore_wait(VCOS_SEMAPHORE_T *sem) { + int ret; + /* gdb causes sem_wait() to EINTR when a breakpoint is hit, retry here */ + while ((ret = sem_wait(sem)) == -1 && errno == EINTR) + continue; + vcos_assert(ret==0); + return VCOS_SUCCESS; +} + +VCOS_INLINE_IMPL +VCOS_STATUS_T vcos_semaphore_trywait(VCOS_SEMAPHORE_T *sem) { + int ret; + while ((ret = sem_trywait(sem)) == -1 && errno == EINTR) + continue; + if (ret == 0) + return VCOS_SUCCESS; + else if (errno == EAGAIN) + return VCOS_EAGAIN; + else { + vcos_assert(0); + return VCOS_EINVAL; + } +} + +/** + * \brief Wait on a semaphore with a timeout. + * + * Note that this function may not be implemented on all + * platforms, and may not be efficient on all platforms + * (see comment in vcos_semaphore_wait) + * + * Try to obtain the semaphore. If it is already taken, return + * VCOS_EAGAIN. + * @param sem Semaphore to wait on + * @param timeout Number of milliseconds to wait before + * returning if the semaphore can't be acquired. + * @return VCOS_SUCCESS - semaphore was taken. + * VCOS_EAGAIN - could not take semaphore (i.e. timeout + * expired) + * VCOS_EINVAL - Some other error (most likely bad + * parameters). + */ +VCOS_INLINE_IMPL +VCOS_STATUS_T vcos_semaphore_wait_timeout(VCOS_SEMAPHORE_T *sem, VCOS_UNSIGNED timeout) { + struct timespec ts; + int ret; + if (clock_gettime(CLOCK_REALTIME, &ts) == -1) + return VCOS_EINVAL; + ts.tv_sec += timeout/1000; + ts.tv_nsec += (timeout%1000)*1000*1000; + if (ts.tv_nsec > 1000000000) { + ts.tv_sec++; + ts.tv_nsec -= 1000000000; + } + + while (1) { + ret = sem_timedwait( sem, &ts ); + if (ret == 0) { + return VCOS_SUCCESS; + } else { + if (errno == EINTR) { + continue; + } else if (errno == ETIMEDOUT) { + return VCOS_EAGAIN; + } else { + vcos_assert(0); + return VCOS_EINVAL; + } + } + } +} + +VCOS_INLINE_IMPL +VCOS_STATUS_T vcos_semaphore_create(VCOS_SEMAPHORE_T *sem, + const char *name, + VCOS_UNSIGNED initial_count) { + int rc = sem_init(sem, 0, initial_count); + (void)name; + if (rc != -1) return VCOS_SUCCESS; + else return vcos_pthreads_map_errno(); +} + +VCOS_INLINE_IMPL +void vcos_semaphore_delete(VCOS_SEMAPHORE_T *sem) { + int rc = sem_destroy(sem); + vcos_assert(rc != -1); + (void)rc; +} + +VCOS_INLINE_IMPL +VCOS_STATUS_T vcos_semaphore_post(VCOS_SEMAPHORE_T *sem) { + int rc = sem_post(sem); + vcos_assert(rc == 0); + (void)rc; + return VCOS_SUCCESS; +} + +/*********************************************************** + * + * Threads + * + ***********************************************************/ + + +extern VCOS_THREAD_T *vcos_dummy_thread_create(void); +extern pthread_key_t _vcos_thread_current_key; +extern uint64_t vcos_getmicrosecs64_internal(void); + +VCOS_INLINE_IMPL +uint32_t vcos_getmicrosecs(void) { return (uint32_t)vcos_getmicrosecs64_internal(); } + +VCOS_INLINE_IMPL +uint64_t vcos_getmicrosecs64(void) { return vcos_getmicrosecs64_internal(); } + +VCOS_INLINE_IMPL +VCOS_THREAD_T *vcos_thread_current(void) { + void *ret = pthread_getspecific(_vcos_thread_current_key); + if (ret == NULL) + { + ret = vcos_dummy_thread_create(); + } + +#ifdef __cplusplus + return static_cast(ret); +#else + return (VCOS_THREAD_T *)ret; +#endif +} + +VCOS_INLINE_IMPL +void vcos_sleep(uint32_t ms) { + struct timespec ts; + ts.tv_sec = ms/1000; + ts.tv_nsec = ms % 1000 * (1000000); + nanosleep(&ts, NULL); +} + +VCOS_INLINE_IMPL +void vcos_thread_attr_setstack(VCOS_THREAD_ATTR_T *attr, void *addr, VCOS_UNSIGNED sz) { + attr->ta_stackaddr = addr; + attr->ta_stacksz = sz; +} + +VCOS_INLINE_IMPL +void vcos_thread_attr_setstacksize(VCOS_THREAD_ATTR_T *attr, VCOS_UNSIGNED sz) { + attr->ta_stacksz = sz; +} + +VCOS_INLINE_IMPL +void vcos_thread_attr_setpriority(VCOS_THREAD_ATTR_T *attr, VCOS_UNSIGNED pri) { + (void)attr; + (void)pri; +} + +VCOS_INLINE_IMPL +void vcos_thread_set_priority(VCOS_THREAD_T *thread, VCOS_UNSIGNED p) { + /* not implemented */ + (void)thread; + (void)p; +} + +VCOS_INLINE_IMPL +VCOS_UNSIGNED vcos_thread_get_priority(VCOS_THREAD_T *thread) { + /* not implemented */ + (void)thread; + return 0; +} + +VCOS_INLINE_IMPL +void vcos_thread_set_affinity(VCOS_THREAD_T *thread, VCOS_UNSIGNED affinity) { + /* not implemented */ + vcos_unused(thread); + vcos_unused(affinity); +} + + +VCOS_INLINE_IMPL +void vcos_thread_attr_setaffinity(VCOS_THREAD_ATTR_T *attrs, VCOS_UNSIGNED affinity) { + attrs->ta_affinity = affinity; +} + +VCOS_INLINE_IMPL +void vcos_thread_attr_settimeslice(VCOS_THREAD_ATTR_T *attrs, VCOS_UNSIGNED ts) { + attrs->ta_timeslice = ts; +} + +VCOS_INLINE_IMPL +void _vcos_thread_attr_setlegacyapi(VCOS_THREAD_ATTR_T *attrs, VCOS_UNSIGNED legacy) { + attrs->legacy = legacy; +} + +VCOS_INLINE_IMPL +void vcos_thread_attr_setautostart(VCOS_THREAD_ATTR_T *attrs, VCOS_UNSIGNED autostart) { + (void)attrs; + (void)autostart; +} + +VCOS_INLINE_IMPL +VCOS_LLTHREAD_T *vcos_llthread_current(void) { + return (VCOS_LLTHREAD_T *)pthread_self(); +} + +/* + * Mutexes + */ + +#ifndef VCOS_USE_VCOS_FUTEX + +VCOS_INLINE_IMPL +VCOS_STATUS_T vcos_mutex_create(VCOS_MUTEX_T *latch, const char *name) { + int rc = pthread_mutex_init(latch, NULL); + (void)name; + if (rc == 0) return VCOS_SUCCESS; + else return vcos_pthreads_map_errno(); +} + +VCOS_INLINE_IMPL +void vcos_mutex_delete(VCOS_MUTEX_T *latch) { + int rc = pthread_mutex_destroy(latch); + (void)rc; + vcos_assert(rc==0); +} + +VCOS_INLINE_IMPL +VCOS_STATUS_T vcos_mutex_lock(VCOS_MUTEX_T *latch) { + int rc = pthread_mutex_lock(latch); + vcos_assert(rc==0); + (void)rc; + return VCOS_SUCCESS; +} + +VCOS_INLINE_IMPL +void vcos_mutex_unlock(VCOS_MUTEX_T *latch) { + int rc = pthread_mutex_unlock(latch); + (void)rc; + vcos_assert(rc==0); +} + +VCOS_INLINE_IMPL +int vcos_mutex_is_locked(VCOS_MUTEX_T *m) { + int rc = pthread_mutex_trylock(m); + if (rc == 0) { + pthread_mutex_unlock(m); + /* it wasn't locked */ + return 0; + } + else { + return 1; /* it was locked */ + } +} + +VCOS_INLINE_IMPL +VCOS_STATUS_T vcos_mutex_trylock(VCOS_MUTEX_T *m) { + int rc = pthread_mutex_trylock(m); + (void)rc; + return (rc == 0) ? VCOS_SUCCESS : VCOS_EAGAIN; +} + +#endif /* VCOS_USE_VCOS_FUTEX */ + +/* + * Events + */ + +VCOS_INLINE_IMPL +VCOS_STATUS_T vcos_event_create(VCOS_EVENT_T *event, const char *debug_name) +{ + VCOS_STATUS_T status; + + int rc = sem_init(&event->sem, 0, 0); + if (rc != 0) return vcos_pthreads_map_errno(); + + status = vcos_mutex_create(&event->mutex, debug_name); + if (status != VCOS_SUCCESS) { + sem_destroy(&event->sem); + return status; + } + + return VCOS_SUCCESS; +} + +VCOS_INLINE_IMPL +void vcos_event_signal(VCOS_EVENT_T *event) +{ + int ok = 0; + int value; + + if (vcos_mutex_lock(&event->mutex) != VCOS_SUCCESS) + goto fail_mtx; + + if (sem_getvalue(&event->sem, &value) != 0) + goto fail_sem; + + if (value == 0) + if (sem_post(&event->sem) != 0) + goto fail_sem; + + ok = 1; +fail_sem: + vcos_mutex_unlock(&event->mutex); +fail_mtx: + vcos_assert(ok); +} + +VCOS_INLINE_IMPL +VCOS_STATUS_T vcos_event_wait(VCOS_EVENT_T *event) +{ + int ret; + /* gdb causes sem_wait() to EINTR when a breakpoint is hit, retry here */ + while ((ret = sem_wait(&event->sem)) == -1 && errno == EINTR) + continue; + vcos_assert(ret==0); + return ret == 0 ? VCOS_SUCCESS : (VCOS_STATUS_T)errno; +} + +VCOS_INLINE_IMPL +VCOS_STATUS_T vcos_event_try(VCOS_EVENT_T *event) +{ + int ret; + while ((ret = sem_trywait(&event->sem)) == -1 && errno == EINTR) + continue; + + if (ret == -1 && errno == EAGAIN) + return VCOS_EAGAIN; + else + return VCOS_SUCCESS; +} + +VCOS_INLINE_IMPL +void vcos_event_delete(VCOS_EVENT_T *event) +{ + int rc = sem_destroy(&event->sem); + vcos_assert(rc != -1); + (void)rc; + + vcos_mutex_delete(&event->mutex); +} + +VCOS_INLINE_IMPL +VCOS_UNSIGNED vcos_process_id_current(void) { + return (VCOS_UNSIGNED) getpid(); +} + +VCOS_INLINE_IMPL +int vcos_strcasecmp(const char *s1, const char *s2) { + return strcasecmp(s1,s2); +} + +VCOS_INLINE_IMPL +int vcos_strncasecmp(const char *s1, const char *s2, size_t n) { + return strncasecmp(s1,s2,n); +} + +VCOS_INLINE_IMPL +int vcos_in_interrupt(void) { + return 0; +} + +/* For support event groups - per thread semaphore */ +VCOS_INLINE_IMPL +void _vcos_thread_sem_wait(void) { + VCOS_THREAD_T *t = vcos_thread_current(); + vcos_semaphore_wait(&t->suspend); +} + +VCOS_INLINE_IMPL +void _vcos_thread_sem_post(VCOS_THREAD_T *target) { + vcos_semaphore_post(&target->suspend); +} + +VCOS_INLINE_IMPL +VCOS_STATUS_T vcos_tls_create(VCOS_TLS_KEY_T *key) { + int st = pthread_key_create(key, NULL); + return st == 0 ? VCOS_SUCCESS: VCOS_ENOMEM; +} + +VCOS_INLINE_IMPL +void vcos_tls_delete(VCOS_TLS_KEY_T tls) { + pthread_key_delete(tls); +} + +VCOS_INLINE_IMPL +VCOS_STATUS_T vcos_tls_set(VCOS_TLS_KEY_T tls, void *v) { + pthread_setspecific(tls, v); + return VCOS_SUCCESS; +} + +VCOS_INLINE_IMPL +void *vcos_tls_get(VCOS_TLS_KEY_T tls) { + return pthread_getspecific(tls); +} + +#if VCOS_HAVE_ATOMIC_FLAGS + +/* + * Atomic flags + */ + +/* TODO implement properly... */ + +VCOS_INLINE_IMPL +VCOS_STATUS_T vcos_atomic_flags_create(VCOS_ATOMIC_FLAGS_T *atomic_flags) +{ + atomic_flags->flags = 0; + return vcos_mutex_create(&atomic_flags->mutex, "VCOS_ATOMIC_FLAGS_T"); +} + +VCOS_INLINE_IMPL +void vcos_atomic_flags_or(VCOS_ATOMIC_FLAGS_T *atomic_flags, uint32_t flags) +{ + vcos_mutex_lock(&atomic_flags->mutex); + atomic_flags->flags |= flags; + vcos_mutex_unlock(&atomic_flags->mutex); +} + +VCOS_INLINE_IMPL +uint32_t vcos_atomic_flags_get_and_clear(VCOS_ATOMIC_FLAGS_T *atomic_flags) +{ + uint32_t flags; + vcos_mutex_lock(&atomic_flags->mutex); + flags = atomic_flags->flags; + atomic_flags->flags = 0; + vcos_mutex_unlock(&atomic_flags->mutex); + return flags; +} + +VCOS_INLINE_IMPL +void vcos_atomic_flags_delete(VCOS_ATOMIC_FLAGS_T *atomic_flags) +{ + vcos_mutex_delete(&atomic_flags->mutex); +} + +#endif + +#if defined(linux) || defined(_HAVE_SBRK) + +/* not exactly the free memory, but a measure of it */ + +VCOS_INLINE_IMPL +unsigned long vcos_get_free_mem(void) { + return (unsigned long)sbrk(0); +} + +#endif + +#ifdef VCOS_PTHREADS_WANT_HISR_EMULATION +VCOS_STATUS_T vcos_legacy_hisr_create(VCOS_HISR_T *hisr, const char *name, + void (*entry)(void), + VCOS_UNSIGNED pri, + void *stack, VCOS_UNSIGNED stack_size); + +void vcos_legacy_hisr_activate(VCOS_HISR_T *hisr); + +void vcos_legacy_hisr_delete(VCOS_HISR_T *hisr); + +#endif + +#undef VCOS_ASSERT_LOGGING_DISABLE +#define VCOS_ASSERT_LOGGING_DISABLE 0 + +#endif /* VCOS_INLINE_BODIES */ + +#define vcos_log_platform_init() _vcos_log_platform_init() +VCOSPRE_ void VCOSPOST_ _vcos_log_platform_init(void); + +VCOS_INLINE_DECL void _vcos_thread_sem_wait(void); +VCOS_INLINE_DECL void _vcos_thread_sem_post(VCOS_THREAD_T *); + +#define VCOS_APPLICATION_ARGC vcos_get_argc() +#define VCOS_APPLICATION_ARGV vcos_get_argv() + +#include "generic/vcos_generic_reentrant_mtx.h" +#include "generic/vcos_generic_named_sem.h" +#include "generic/vcos_generic_quickslow_mutex.h" +#include "generic/vcos_common.h" + +#define _VCOS_LOG_LEVEL() getenv("VC_LOGLEVEL") + +VCOS_STATIC_INLINE +char *vcos_strdup(const char *str) +{ + return strdup(str); +} + +typedef void (*VCOS_ISR_HANDLER_T)(VCOS_UNSIGNED vecnum); + +#define VCOS_DL_LAZY RTLD_LAZY +#define VCOS_DL_NOW RTLD_NOW +#define VCOS_DL_LOCAL RTLD_LOCAL +#define VCOS_DL_GLOBAL RTLD_GLOBAL + +#ifdef __cplusplus +} +#endif +#endif /* VCOS_PLATFORM_H */ + diff --git a/external_src/raspicam-0.1.3/dependencies/vcos/pthreads/vcos_platform_types.h b/external_src/raspicam-0.1.3/dependencies/vcos/pthreads/vcos_platform_types.h new file mode 100644 index 0000000..1a8734b --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/vcos/pthreads/vcos_platform_types.h @@ -0,0 +1,71 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. +*/ + +/*============================================================================= +VideoCore OS Abstraction Layer - platform-specific types and defines +=============================================================================*/ + +#ifndef VCOS_PLATFORM_TYPES_H +#define VCOS_PLATFORM_TYPES_H + +#include "vcos_inttypes.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define VCOSPRE_ extern +#define VCOSPOST_ + +#if defined(__GNUC__) && (( __GNUC__ > 2 ) || (( __GNUC__ == 2 ) && ( __GNUC_MINOR__ >= 3 ))) +#define VCOS_FORMAT_ATTR_(ARCHETYPE, STRING_INDEX, FIRST_TO_CHECK) __attribute__ ((format (ARCHETYPE, STRING_INDEX, FIRST_TO_CHECK))) +#else +#define VCOS_FORMAT_ATTR_(ARCHETYPE, STRING_INDEX, FIRST_TO_CHECK) +#endif + +#if defined(__linux__) && !defined(NDEBUG) && defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) + #define VCOS_BKPT ({ __asm volatile ("int3":::"memory"); }) +#endif +/*#define VCOS_BKPT vcos_abort() */ + +#define VCOS_ASSERT_LOGGING 1 +#define VCOS_ASSERT_LOGGING_DISABLE 0 + +extern void +vcos_pthreads_logging_assert(const char *file, const char *func, unsigned int line, const char *fmt, ...); + +#define VCOS_ASSERT_MSG(...) ((VCOS_ASSERT_LOGGING && !VCOS_ASSERT_LOGGING_DISABLE) ? vcos_pthreads_logging_assert(__FILE__, __func__, __LINE__, __VA_ARGS__) : (void)0) + +#define VCOS_INLINE_BODIES +#define VCOS_INLINE_DECL extern __inline__ +#define VCOS_INLINE_IMPL static __inline__ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external_src/raspicam-0.1.3/dependencies/vcos/pthreads/vcos_pthreads.c b/external_src/raspicam-0.1.3/dependencies/vcos/pthreads/vcos_pthreads.c new file mode 100644 index 0000000..fdc8bc4 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/vcos/pthreads/vcos_pthreads.c @@ -0,0 +1,902 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. +*/ + +/*#define VCOS_INLINE_BODIES */ +#include "interface/vcos/vcos.h" +#include "interface/vcos/vcos_msgqueue.h" +#include +#include +#include +#include +#include +#include + +/* Cygwin doesn't always have prctl.h and it doesn't have PR_SET_NAME */ +#if defined( __linux__ ) +# if !defined(HAVE_PRCTL) +# define HAVE_PRCTL +# endif +#include +#endif + +#ifdef HAVE_CMAKE_CONFIG +#include "cmake_config.h" +#endif + +#ifdef HAVE_MTRACE +#include +#endif + +#if defined(ANDROID) +#include +#endif + +#ifndef VCOS_DEFAULT_STACK_SIZE +#define VCOS_DEFAULT_STACK_SIZE 4096 +#endif + +static int vcos_argc; +static const char **vcos_argv; + +typedef void (*LEGACY_ENTRY_FN_T)(int, void *); + +static VCOS_THREAD_ATTR_T default_attrs = { + .ta_stacksz = VCOS_DEFAULT_STACK_SIZE, +}; + +/** Singleton global lock used for vcos_global_lock/unlock(). */ +static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; + +#ifdef ANDROID +static VCOS_MUTEX_T printf_lock; +#endif + +/* Create a per-thread key for faking up vcos access + * on non-vcos threads. + */ +pthread_key_t _vcos_thread_current_key; + +static VCOS_UNSIGNED _vcos_thread_current_key_created = 0; +static VCOS_ONCE_T current_thread_key_once; /* init just once */ + +static void vcos_thread_cleanup(VCOS_THREAD_T *thread) +{ + vcos_semaphore_delete(&thread->suspend); + if (thread->task_timer_created) + { + vcos_timer_delete(&thread->task_timer); + } +} + +static void vcos_dummy_thread_cleanup(void *cxt) +{ + VCOS_THREAD_T *thread = cxt; + if (thread->dummy) + { + int i; + /* call termination functions */ + for (i=0; thread->at_exit[i].pfn != NULL; i++) + { + thread->at_exit[i].pfn(thread->at_exit[i].cxt); + } + vcos_thread_cleanup(thread); + vcos_free(thread); + } +} + +static void current_thread_key_init(void) +{ + vcos_assert(!_vcos_thread_current_key_created); + pthread_key_create (&_vcos_thread_current_key, vcos_dummy_thread_cleanup); + _vcos_thread_current_key_created = 1; +} + + +/* A VCOS wrapper for the thread which called vcos_init. */ +static VCOS_THREAD_T vcos_thread_main; + +static void *vcos_thread_entry(void *arg) +{ + int i; + void *ret; + VCOS_THREAD_T *thread = (VCOS_THREAD_T *)arg; + + vcos_assert(thread != NULL); + thread->dummy = 0; + + pthread_setspecific(_vcos_thread_current_key, thread); +#if defined( HAVE_PRCTL ) && defined( PR_SET_NAME ) + /* cygwin doesn't have PR_SET_NAME */ + prctl( PR_SET_NAME, (unsigned long)thread->name, 0, 0, 0 ); +#endif + if (thread->legacy) + { + LEGACY_ENTRY_FN_T fn = (LEGACY_ENTRY_FN_T)thread->entry; + (*fn)(0, thread->arg); + ret = 0; + } + else + { + ret = (*thread->entry)(thread->arg); + } + + /* call termination functions */ + for (i=0; thread->at_exit[i].pfn != NULL; i++) + { + thread->at_exit[i].pfn(thread->at_exit[i].cxt); + } + + return ret; +} + +static void _task_timer_expiration_routine(void *cxt) +{ + VCOS_THREAD_T *thread = (VCOS_THREAD_T *)cxt; + + vcos_assert(thread->orig_task_timer_expiration_routine); + thread->orig_task_timer_expiration_routine(thread->orig_task_timer_context); + thread->orig_task_timer_expiration_routine = NULL; +} + +VCOS_STATUS_T vcos_thread_create(VCOS_THREAD_T *thread, + const char *name, + VCOS_THREAD_ATTR_T *attrs, + VCOS_THREAD_ENTRY_FN_T entry, + void *arg) +{ + VCOS_STATUS_T st; + pthread_attr_t pt_attrs; + VCOS_THREAD_ATTR_T *local_attrs = attrs ? attrs : &default_attrs; + int rc; + + vcos_assert(thread); + memset(thread, 0, sizeof(VCOS_THREAD_T)); + + rc = pthread_attr_init(&pt_attrs); + if (rc < 0) + return VCOS_ENOMEM; + + st = vcos_semaphore_create(&thread->suspend, NULL, 0); + if (st != VCOS_SUCCESS) + { + pthread_attr_destroy(&pt_attrs); + return st; + } + + pthread_attr_setstacksize(&pt_attrs, local_attrs->ta_stacksz); +#if VCOS_CAN_SET_STACK_ADDR + if (local_attrs->ta_stackaddr) + { + pthread_attr_setstackaddr(&pt_attrs, local_attrs->ta_stackaddr); + } +#else + vcos_demand(local_attrs->ta_stackaddr == 0); +#endif + + /* pthread_attr_setpriority(&pt_attrs, local_attrs->ta_priority); */ + + vcos_assert(local_attrs->ta_stackaddr == 0); /* Not possible */ + + thread->entry = entry; + thread->arg = arg; + thread->legacy = local_attrs->legacy; + + strncpy(thread->name, name, sizeof(thread->name)); + thread->name[sizeof(thread->name)-1] = '\0'; + memset(thread->at_exit, 0, sizeof(thread->at_exit)); + + rc = pthread_create(&thread->thread, &pt_attrs, vcos_thread_entry, thread); + + pthread_attr_destroy(&pt_attrs); + + if (rc < 0) + { + vcos_semaphore_delete(&thread->suspend); + return VCOS_ENOMEM; + } + else + { + return VCOS_SUCCESS; + } +} + +void vcos_thread_join(VCOS_THREAD_T *thread, + void **pData) +{ + pthread_join(thread->thread, pData); + vcos_thread_cleanup(thread); +} + +VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_thread_create_classic(VCOS_THREAD_T *thread, + const char *name, + void *(*entry)(void *arg), + void *arg, + void *stack, + VCOS_UNSIGNED stacksz, + VCOS_UNSIGNED priaff, + VCOS_UNSIGNED timeslice, + VCOS_UNSIGNED autostart) +{ + VCOS_THREAD_ATTR_T attrs; + vcos_thread_attr_init(&attrs); + vcos_thread_attr_setstacksize(&attrs, stacksz); + vcos_thread_attr_setpriority(&attrs, priaff & ~_VCOS_AFFINITY_MASK); + vcos_thread_attr_setaffinity(&attrs, priaff & _VCOS_AFFINITY_MASK); + (void)timeslice; + (void)autostart; + + if (VCOS_CAN_SET_STACK_ADDR) + { + vcos_thread_attr_setstack(&attrs, stack, stacksz); + } + + return vcos_thread_create(thread, name, &attrs, entry, arg); +} + +uint64_t vcos_getmicrosecs64_internal(void) +{ + struct timeval tv; + uint64_t tm = 0; + + if (!gettimeofday(&tv, NULL)) + { + tm = (tv.tv_sec * 1000000LL) + tv.tv_usec; + } + + return tm; +} + +#ifdef ANDROID + +static int log_prio[] = +{ + ANDROID_LOG_INFO, /* VCOS_LOG_UNINITIALIZED */ + ANDROID_LOG_INFO, /* VCOS_LOG_NEVER */ + ANDROID_LOG_ERROR, /* VCOS_LOG_ERROR */ + ANDROID_LOG_WARN, /* VCOS_LOG_WARN */ + ANDROID_LOG_INFO, /* VCOS_LOG_INFO */ + ANDROID_LOG_DEBUG /* VCOS_LOG_TRACE */ +}; + +int vcos_use_android_log = 1; +int vcos_log_to_file = 0; +#else +int vcos_use_android_log = 0; +int vcos_log_to_file = 0; +#endif + +static FILE * log_fhandle = NULL; + +void vcos_vlog_default_impl(const VCOS_LOG_CAT_T *cat, VCOS_LOG_LEVEL_T _level, const char *fmt, va_list args) +{ + (void)_level; + +#ifdef ANDROID + if ( vcos_use_android_log ) + { + __android_log_vprint(log_prio[_level], cat->name, fmt, args); + } + else + { + vcos_mutex_lock(&printf_lock); +#endif + if(NULL != log_fhandle) + { + if (cat->flags.want_prefix) + fprintf( log_fhandle, "%s: ", cat->name ); + vfprintf(log_fhandle, fmt, args); + fputs("\n", log_fhandle); + fflush(log_fhandle); + } +#ifdef ANDROID + vcos_mutex_unlock(&printf_lock); + } +#endif +} + +void _vcos_log_platform_init(void) +{ + if(vcos_log_to_file) + { + char log_fname[100]; +#ifdef ANDROID + snprintf(log_fname, 100, "/data/log/vcos_log%u.txt", vcos_process_id_current()); +#else + snprintf(log_fname, 100, "/var/log/vcos_log%u.txt", vcos_process_id_current()); +#endif + log_fhandle = fopen(log_fname, "w"); + } + else + log_fhandle = stderr; +} + +/* Flags for init/deinit components */ +enum +{ + VCOS_INIT_NAMED_SEM = (1 << 0), + VCOS_INIT_PRINTF_LOCK = (1 << 1), + VCOS_INIT_MAIN_SEM = (1 << 2), + VCOS_INIT_MSGQ = (1 << 3), + VCOS_INIT_ALL = 0xffffffff +}; + +static void vcos_term(uint32_t flags) +{ + if (flags & VCOS_INIT_MSGQ) + vcos_msgq_deinit(); + + if (flags & VCOS_INIT_MAIN_SEM) + vcos_semaphore_delete(&vcos_thread_main.suspend); + +#ifdef ANDROID + if (flags & VCOS_INIT_PRINTF_LOCK) + vcos_mutex_delete(&printf_lock); +#endif + + if (flags & VCOS_INIT_NAMED_SEM) + _vcos_named_semaphore_deinit(); +} + +VCOS_STATUS_T vcos_platform_init(void) +{ + VCOS_STATUS_T st; + uint32_t flags = 0; + int pst; + + st = _vcos_named_semaphore_init(); + if (!vcos_verify(st == VCOS_SUCCESS)) + goto end; + + flags |= VCOS_INIT_NAMED_SEM; + +#ifdef HAVE_MTRACE + /* enable glibc memory debugging, if the environment + * variable MALLOC_TRACE names a valid file. + */ + mtrace(); +#endif + +#ifdef ANDROID + st = vcos_mutex_create(&printf_lock, "printf"); + if (!vcos_verify(st == VCOS_SUCCESS)) + goto end; + + flags |= VCOS_INIT_PRINTF_LOCK; +#endif + + st = vcos_once(¤t_thread_key_once, current_thread_key_init); + if (!vcos_verify(st == VCOS_SUCCESS)) + goto end; + + /* Initialise a VCOS wrapper for the thread which called vcos_init. */ + st = vcos_semaphore_create(&vcos_thread_main.suspend, NULL, 0); + if (!vcos_verify(st == VCOS_SUCCESS)) + goto end; + + flags |= VCOS_INIT_MAIN_SEM; + + vcos_thread_main.thread = pthread_self(); + + pst = pthread_setspecific(_vcos_thread_current_key, &vcos_thread_main); + if (!vcos_verify(pst == 0)) + { + st = VCOS_EINVAL; + goto end; + } + + st = vcos_msgq_init(); + if (!vcos_verify(st == VCOS_SUCCESS)) + goto end; + + flags |= VCOS_INIT_MSGQ; + + vcos_logging_init(); + +end: + if (st != VCOS_SUCCESS) + vcos_term(flags); + + return st; +} + +void vcos_platform_deinit(void) +{ + vcos_term(VCOS_INIT_ALL); +} + +void vcos_global_lock(void) +{ + pthread_mutex_lock(&lock); +} + +void vcos_global_unlock(void) +{ + pthread_mutex_unlock(&lock); +} + +void vcos_thread_exit(void *arg) +{ + VCOS_THREAD_T *thread = vcos_thread_current(); + + if ( thread && thread->dummy ) + { + vcos_free ( (void*) thread ); + thread = NULL; + } + + pthread_exit(arg); +} + + +void vcos_thread_attr_init(VCOS_THREAD_ATTR_T *attrs) +{ + *attrs = default_attrs; +} + +VCOS_STATUS_T vcos_pthreads_map_error(int error) +{ + switch (error) + { + case ENOMEM: + return VCOS_ENOMEM; + case ENXIO: + return VCOS_ENXIO; + case EAGAIN: + return VCOS_EAGAIN; + case ENOSPC: + return VCOS_ENOSPC; + default: + return VCOS_EINVAL; + } +} + +VCOS_STATUS_T vcos_pthreads_map_errno(void) +{ + return vcos_pthreads_map_error(errno); +} + +void _vcos_task_timer_set(void (*pfn)(void*), void *cxt, VCOS_UNSIGNED ms) +{ + VCOS_THREAD_T *thread = vcos_thread_current(); + + if (thread == NULL) + return; + + vcos_assert(thread->orig_task_timer_expiration_routine == NULL); + + if (!thread->task_timer_created) + { + VCOS_STATUS_T st = vcos_timer_create(&thread->task_timer, NULL, + _task_timer_expiration_routine, thread); + (void)st; + vcos_assert(st == VCOS_SUCCESS); + thread->task_timer_created = 1; + } + + thread->orig_task_timer_expiration_routine = pfn; + thread->orig_task_timer_context = cxt; + + vcos_timer_set(&thread->task_timer, ms); +} + +void _vcos_task_timer_cancel(void) +{ + VCOS_THREAD_T *thread = vcos_thread_current(); + + if (thread == NULL || !thread->task_timer_created) + return; + + vcos_timer_cancel(&thread->task_timer); + thread->orig_task_timer_expiration_routine = NULL; +} + +int vcos_vsnprintf( char *buf, size_t buflen, const char *fmt, va_list ap ) +{ + return vsnprintf( buf, buflen, fmt, ap ); +} + +int vcos_snprintf(char *buf, size_t buflen, const char *fmt, ...) +{ + int ret; + va_list ap; + va_start(ap,fmt); + ret = vsnprintf(buf, buflen, fmt, ap); + va_end(ap); + return ret; +} + +int vcos_have_rtos(void) +{ + return 1; +} + +const char * vcos_thread_get_name(const VCOS_THREAD_T *thread) +{ + return thread->name; +} + +#ifdef VCOS_HAVE_BACKTRACK +void __attribute__((weak)) vcos_backtrace_self(void); +#endif + +void vcos_pthreads_logging_assert(const char *file, const char *func, unsigned int line, const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + fprintf(stderr, "assertion failure:%s:%d:%s():", + file, line, func); + vfprintf(stderr, fmt, ap); + va_end(ap); + fprintf(stderr, "\n"); + +#ifdef VCOS_HAVE_BACKTRACK + if (vcos_backtrace_self) + vcos_backtrace_self(); +#endif + abort(); +} + +extern VCOS_STATUS_T vcos_thread_at_exit(void (*pfn)(void*), void *cxt) +{ + int i; + VCOS_THREAD_T *self = vcos_thread_current(); + if (!self) + { + vcos_assert(0); + return VCOS_EINVAL; + } + for (i=0; iat_exit[i].pfn == NULL) + { + self->at_exit[i].pfn = pfn; + self->at_exit[i].cxt = cxt; + return VCOS_SUCCESS; + } + } + return VCOS_ENOSPC; +} + +void vcos_set_args(int argc, const char **argv) +{ + vcos_argc = argc; + vcos_argv = argv; +} + +int vcos_get_argc(void) +{ + return vcos_argc; +} + +const char ** vcos_get_argv(void) +{ + return vcos_argv; +} + +/* we can't inline this, because HZ comes from sys/param.h which + * dumps all sorts of junk into the global namespace, notable MIN and + * MAX. + */ +uint32_t _vcos_get_ticks_per_second(void) +{ + return HZ; +} + +VCOS_STATUS_T vcos_once(VCOS_ONCE_T *once_control, + void (*init_routine)(void)) +{ + int rc = pthread_once(once_control, init_routine); + if (rc != 0) + { + switch (errno) + { + case EINVAL: + return VCOS_EINVAL; + default: + vcos_assert(0); + return VCOS_EACCESS; + } + } + else + { + return VCOS_SUCCESS; + } +} + + +VCOS_THREAD_T *vcos_dummy_thread_create(void) +{ + VCOS_STATUS_T st; + VCOS_THREAD_T *thread_hndl = NULL; + int rc; + + thread_hndl = (VCOS_THREAD_T *)vcos_malloc(sizeof(VCOS_THREAD_T), NULL); + vcos_assert(thread_hndl != NULL); + + memset(thread_hndl, 0, sizeof(VCOS_THREAD_T)); + + thread_hndl->dummy = 1; + thread_hndl->thread = pthread_self(); + + st = vcos_semaphore_create(&thread_hndl->suspend, NULL, 0); + if (st != VCOS_SUCCESS) + { + vcos_free(thread_hndl); + return( thread_hndl ); + } + + vcos_once(¤t_thread_key_once, current_thread_key_init); + + rc = pthread_setspecific(_vcos_thread_current_key, + thread_hndl); + (void)rc; + + return( thread_hndl ); +} + + +/*********************************************************** + * + * Timers + * + ***********************************************************/ + +/* On Linux we could use POSIX timers with a bit of synchronization. + * Unfortunately POSIX timers on Bionic are NOT POSIX compliant + * what makes that option not viable. + * That's why we ended up with our own implementation of timers. + * NOTE: That condition variables on Bionic are also buggy and + * they work incorrectly with CLOCK_MONOTONIC, so we have to + * use CLOCK_REALTIME (and hope that no one will change the time + * significantly after the timer has been set up + */ +#define NSEC_IN_SEC (1000*1000*1000) +#define MSEC_IN_SEC (1000) +#define NSEC_IN_MSEC (1000*1000) + +static int _timespec_is_zero(struct timespec *ts) +{ + return ((ts->tv_sec == 0) && (ts->tv_nsec == 0)); +} + +static void _timespec_set_zero(struct timespec *ts) +{ + ts->tv_sec = ts->tv_nsec = 0; +} + +/* Adds left to right and stores the result in left */ +static void _timespec_add(struct timespec *left, struct timespec *right) +{ + left->tv_sec += right->tv_sec; + left->tv_nsec += right->tv_nsec; + if (left->tv_nsec >= (NSEC_IN_SEC)) + { + left->tv_nsec -= NSEC_IN_SEC; + left->tv_sec++; + } +} + +static int _timespec_is_larger(struct timespec *left, struct timespec *right) +{ + if (left->tv_sec != right->tv_sec) + return left->tv_sec > right->tv_sec; + else + return left->tv_nsec > right->tv_nsec; +} + +static void* _timer_thread(void *arg) +{ + VCOS_TIMER_T *timer = (VCOS_TIMER_T*)arg; + + pthread_mutex_lock(&timer->lock); + while (!timer->quit) + { + struct timespec now; + + /* Wait until next expiry time, or until timer's settings are changed */ + if (_timespec_is_zero(&timer->expires)) + pthread_cond_wait(&timer->settings_changed, &timer->lock); + else + pthread_cond_timedwait(&timer->settings_changed, &timer->lock, &timer->expires); + + /* See if the timer has expired - reloop if it didn't */ + clock_gettime(CLOCK_REALTIME, &now); + if (_timespec_is_zero(&timer->expires) || _timespec_is_larger(&timer->expires, &now)) + continue; + + /* The timer has expired. Clear the expiry time and call the + * expiration routine + */ + _timespec_set_zero(&timer->expires); + timer->orig_expiration_routine(timer->orig_context); + } + pthread_mutex_unlock(&timer->lock); + + return NULL; +} + +VCOS_STATUS_T vcos_timer_init(void) +{ + return VCOS_SUCCESS; +} + +VCOS_STATUS_T vcos_timer_create(VCOS_TIMER_T *timer, + const char *name, + void (*expiration_routine)(void *context), + void *context) +{ + pthread_mutexattr_t lock_attr; + VCOS_STATUS_T result = VCOS_SUCCESS; + int settings_changed_initialized = 0; + int lock_attr_initialized = 0; + int lock_initialized = 0; + + (void)name; + + vcos_assert(timer); + vcos_assert(expiration_routine); + + memset(timer, 0, sizeof(VCOS_TIMER_T)); + + timer->orig_expiration_routine = expiration_routine; + timer->orig_context = context; + + /* Create conditional variable for notifying the timer's thread + * when settings change. + */ + if (result == VCOS_SUCCESS) + { + int rc = pthread_cond_init(&timer->settings_changed, NULL); + if (rc == 0) + settings_changed_initialized = 1; + else + result = vcos_pthreads_map_error(rc); + } + + /* Create attributes for the lock (we want it to be recursive) */ + if (result == VCOS_SUCCESS) + { + int rc = pthread_mutexattr_init(&lock_attr); + if (rc == 0) + { + pthread_mutexattr_settype(&lock_attr, PTHREAD_MUTEX_RECURSIVE); + lock_attr_initialized = 1; + } + else + { + result = vcos_pthreads_map_error(rc); + } + } + + /* Create lock for the timer structure */ + if (result == VCOS_SUCCESS) + { + int rc = pthread_mutex_init(&timer->lock, &lock_attr); + if (rc == 0) + lock_initialized = 1; + else + result = vcos_pthreads_map_error(rc); + } + + /* Lock attributes are no longer needed */ + if (lock_attr_initialized) + pthread_mutexattr_destroy(&lock_attr); + + /* Create the underlying thread */ + if (result == VCOS_SUCCESS) + { + int rc = pthread_create(&timer->thread, NULL, _timer_thread, timer); + if (rc != 0) + result = vcos_pthreads_map_error(rc); + } + + /* Clean up if anything went wrong */ + if (result != VCOS_SUCCESS) + { + if (lock_initialized) + pthread_mutex_destroy(&timer->lock); + + if (settings_changed_initialized) + pthread_cond_destroy(&timer->settings_changed); + } + + return result; +} + +void vcos_timer_set(VCOS_TIMER_T *timer, VCOS_UNSIGNED delay_ms) +{ + struct timespec now; + + vcos_assert(timer); + + /* Other implementations of this function do undefined things + * when delay_ms is 0. This implementation will simply assert and return + */ + vcos_assert(delay_ms != 0); + if (delay_ms == 0) + return; + + pthread_mutex_lock(&timer->lock); + + /* Calculate the new absolute expiry time */ + clock_gettime(CLOCK_REALTIME, &now); + timer->expires.tv_sec = delay_ms / MSEC_IN_SEC; + timer->expires.tv_nsec = (delay_ms % MSEC_IN_SEC) * NSEC_IN_MSEC; + _timespec_add(&timer->expires, &now); + + /* Notify the timer's thread about the change */ + pthread_cond_signal(&timer->settings_changed); + + pthread_mutex_unlock(&timer->lock); +} + +void vcos_timer_cancel(VCOS_TIMER_T *timer) +{ + vcos_assert(timer); + + pthread_mutex_lock(&timer->lock); + + _timespec_set_zero(&timer->expires); + pthread_cond_signal(&timer->settings_changed); + + pthread_mutex_unlock(&timer->lock); +} + +void vcos_timer_reset(VCOS_TIMER_T *timer, VCOS_UNSIGNED delay_ms) +{ + vcos_timer_set(timer, delay_ms); +} + +void vcos_timer_delete(VCOS_TIMER_T *timer) +{ + vcos_assert(timer); + + pthread_mutex_lock(&timer->lock); + + /* Other implementation of this function (e.g. ThreadX) + * disallow it being called from the expiration routine + */ + vcos_assert(pthread_self() != timer->thread); + + /* Stop the timer and set flag telling the timer thread to quit */ + _timespec_set_zero(&timer->expires); + timer->quit = 1; + + /* Notify the timer's thread about the change */ + pthread_cond_signal(&timer->settings_changed); + + /* Release the lock, so that the timer's thread can quit */ + pthread_mutex_unlock(&timer->lock); + + /* Wait for the timer thread to finish */ + pthread_join(timer->thread, NULL); + + /* Free resources used by the timer */ + pthread_mutex_destroy(&timer->lock); + pthread_cond_destroy(&timer->settings_changed); +} + diff --git a/external_src/raspicam-0.1.3/dependencies/vcos/user_nodefs.h b/external_src/raspicam-0.1.3/dependencies/vcos/user_nodefs.h new file mode 100644 index 0000000..ded2fb4 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/vcos/user_nodefs.h @@ -0,0 +1,47 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 USER_NODEFS_H +#define USER_NODEFS_H + +/* + * This tells coverity not to expand the assert macro, so it still sees the + * asserts in the code, even in release builds (we currently run coverity on + * our release builds). Unfortunately MetaWare won't compile it, even though + * __COVERITY__ isn't defined, so we put this in its own header. + * + * FIXME: This belongs in the Coverity config (in a file called + * config/user_nodefs.h) + */ +#nodef assert + +/* + * So we need to declare the function now that it isn't a macro any more. It's + * already built into coverity that assert is a "killpath". + */ +extern void assert(int cond); + +#endif /* USER_NODEFS_H */ diff --git a/external_src/raspicam-0.1.3/dependencies/vcos/vcos.h b/external_src/raspicam-0.1.3/dependencies/vcos/vcos.h new file mode 100644 index 0000000..e20b009 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/vcos/vcos.h @@ -0,0 +1,221 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. +*/ + +/*============================================================================= +VideoCore OS Abstraction Layer - public header file +=============================================================================*/ + +/** + * \mainpage OS Abstraction Layer + * + * \section intro Introduction + * + * This abstraction layer is here to allow the underlying OS to be easily changed (e.g. from + * Nucleus to ThreadX) and to aid in porting host applications to new targets. + * + * \subsection error Error handling + * + * Wherever possible, VCOS functions assert internally and return void. The only exceptions + * are creation functions (which might fail due to lack of resources) and functions that + * might timeout or fail due to lack of space. Errors that might be reported by the underlying + * OS API (e.g. invalid mutex) are treated as a programming error, and are merely asserted on. + * + * \section thread_synch Threads and synchronisation + * + * \subsection thread Threads + * + * The thread API is somewhat different to that found in Nucleus. In particular, threads + * cannot just be destroyed at arbitrary times and nor can they merely exit. This is so + * that the same API can be implemented across all interesting platforms without too much + * difficulty. See vcos_thread.h for details. Thread attributes are configured via + * the VCOS_THREAD_ATTR_T structure, found in vcos_thread_attr.h. + * + * \subsection sema Semaphores + * + * Counted semaphores (c.f. Nucleus NU_SEMAPHORE) are created with VCOS_SEMAPHORE_T. + * Under ThreadX on VideoCore, semaphores are implemented using VideoCore spinlocks, and + * so are quite a lot faster than ordinary ThreadX semaphores. See vcos_semaphore.h. + * + * \subsection mtx Mutexes + * + * Mutexes are used for locking. Attempts to take a mutex twice, or to unlock it + * in a different thread to the one in which it was locked should be expected to fail. + * Mutexes are not re-entrant (see vcos_reentrant_mutex.h for a slightly slower + * re-entrant mutex). + * + * \subsection evflags Event flags + * + * Event flags (the ThreadX name - also known as event groups under Nucleus) provide + * 32 flags which can be waited on by multiple clients, and signalled by multiple clients. + * A timeout can be specified. See vcos_event_flags.h. An alternative to this is the + * VCOS_EVENT_T (see vcos_event.h) which is akin to the Win32 auto-reset event, or a + * saturating counted semaphore. + * + * \subsection event Events + * + * A VCOS_EVENT_T is a bit like a saturating semaphore. No matter how many times it + * is signalled, the waiter will only wake up once. See vcos_event.h. You might think this + * is useful if you suspect that the cost of reading the semaphore count (perhaps via a + * system call) is expensive on your platform. + * + * \subsection tls Thread local storage + * + * Thread local storage is supported using vcos_tls.h. This is emulated on Nucleus + * and ThreadX. + * + * \section int Interrupts + * + * The legacy LISR/HISR scheme found in Nucleus is supported via the legacy ISR API, + * which is also supported on ThreadX. New code should avoid this, and old code should + * be migrated away from it, since it is slow. See vcos_legacy_isr.h. + * + * Registering an interrupt handler, and disabling/restoring interrupts, is handled + * using the functions in vcos_isr.h. + * + */ + +/** + * \file vcos.h + * + * This is the top level header file. Clients include this. It pulls in the platform-specific + * header file (vcos_platform.h) together with header files defining the expected APIs, such + * as vcos_mutex.h, vcos_semaphore.h, etc. It is also possible to include these header files + * directly. + * + */ + +#ifndef VCOS_H +#define VCOS_H + +#include "vcos_assert.h" +#include "vcos_types.h" +#include "pthreads/vcos_platform.h" + +#ifndef VCOS_INIT_H +#include "vcos_init.h" +#endif + +#ifndef VCOS_SEMAPHORE_H +#include "vcos_semaphore.h" +#endif + +#ifndef VCOS_THREAD_H +#include "vcos_thread.h" +#endif + +#ifndef VCOS_MUTEX_H +#include "vcos_mutex.h" +#endif + +#ifndef VCOS_MEM_H +#include "vcos_mem.h" +#endif + +#ifndef VCOS_LOGGING_H +#include "vcos_logging.h" +#endif + +#ifndef VCOS_STRING_H +#include "vcos_string.h" +#endif + +#ifndef VCOS_EVENT_H +#include "vcos_event.h" +#endif + +#ifndef VCOS_THREAD_ATTR_H +#include "vcos_thread_attr.h" +#endif + +#ifndef VCOS_TLS_H +#include "vcos_tls.h" +#endif + +#ifndef VCOS_REENTRANT_MUTEX_H +#include "vcos_reentrant_mutex.h" +#endif + +#ifndef VCOS_NAMED_SEMAPHORE_H +#include "vcos_named_semaphore.h" +#endif + +#ifndef VCOS_QUICKSLOW_MUTEX_H +#include "vcos_quickslow_mutex.h" +#endif + +/* Headers with predicates */ + +#if VCOS_HAVE_EVENT_FLAGS +#include "vcos_event_flags.h" +#endif + +#if VCOS_HAVE_QUEUE +#include "vcos_queue.h" +#endif + +#if VCOS_HAVE_LEGACY_ISR +#include "vcos_legacy_isr.h" +#endif + +#if VCOS_HAVE_TIMER +#include "vcos_timer.h" +#endif + +#if VCOS_HAVE_MEMPOOL +#include "vcos_mempool.h" +#endif + +#if VCOS_HAVE_ISR +#include "vcos_isr.h" +#endif + +#if VCOS_HAVE_ATOMIC_FLAGS +#include "vcos_atomic_flags.h" +#endif + +#if VCOS_HAVE_ONCE +#include "vcos_once.h" +#endif + +#if VCOS_HAVE_BLOCK_POOL +#include "vcos_blockpool.h" +#endif + +#if VCOS_HAVE_FILE +#include "vcos_file.h" +#endif + +#if VCOS_HAVE_CFG +#include "vcos_cfg.h" +#endif + +#if VCOS_HAVE_CMD +#include "vcos_cmd.h" +#endif + +#endif /* VCOS_H */ + diff --git a/external_src/raspicam-0.1.3/dependencies/vcos/vcos_assert.h b/external_src/raspicam-0.1.3/dependencies/vcos/vcos_assert.h new file mode 100644 index 0000000..ff5b971 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/vcos/vcos_assert.h @@ -0,0 +1,324 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. +*/ + +/*============================================================================= +VideoCore OS Abstraction Layer - Assertion and error-handling macros. +=============================================================================*/ + + +#ifndef VCOS_ASSERT_H +#define VCOS_ASSERT_H + +/* + * Macro: + * vcos_assert(cond) + * vcos_assert_msg(cond, fmt, ...) + * Use: + * Detecting programming errors by ensuring that assumptions are correct. + * On failure: + * Performs a platform-dependent "breakpoint", usually with an assert-style + * message. The '_msg' variant expects a printf-style format string and + * parameters. + * If a failure is detected, the code should be fixed and rebuilt. + * In release builds: + * Generates no code, i.e. does not evaluate 'cond'. + * Returns: + * Nothing. + * + * Macro: + * vcos_demand(cond) + * vcos_demand_msg(cond, fmt, ...) + * Use: + * Detecting fatal system errors that require a reboot. + * On failure: + * Performs a platform-dependent "breakpoint", usually with an assert-style + * message, then calls vcos_abort (see below). + * In release builds: + * Calls vcos_abort() if 'cond' is false. + * Returns: + * Nothing (never, on failure). + * + * Macro: + * vcos_verify(cond) + * vcos_verify_msg(cond, fmt, ...) + * Use: + * Detecting run-time errors and interesting conditions, normally within an + * 'if' statement to catch the failures, i.e. + * if (!vcos_verify(cond)) handle_error(); + * On failure: + * Generates a message and optionally stops at a platform-dependent + * "breakpoint" (usually disabled). See vcos_verify_bkpts_enable below. + * In release builds: + * Just evaluates and returns 'cond'. + * Returns: + * Non-zero if 'cond' is true, otherwise zero. + * + * Macro: + * vcos_static_assert(cond) + * Use: + * Detecting compile-time errors. + * On failure: + * Generates a compiler error. + * In release builds: + * Generates a compiler error. + * + * Function: + * void vcos_abort(void) + * Use: + * Invokes the fatal error handling mechanism, alerting the host where + * applicable. + * Returns: + * Never. + * + * Macro: + * VCOS_VERIFY_BKPTS + * Use: + * Define in a module (before including vcos.h) to specify an alternative + * flag to control breakpoints on vcos_verify() failures. + * Returns: + * Non-zero values enable breakpoints. + * + * Function: + * int vcos_verify_bkpts_enable(int enable); + * Use: + * Sets the global flag controlling breakpoints on vcos_verify failures, + * enabling the breakpoints iff 'enable' is non-zero. + * Returns: + * The previous state of the flag. + * + * Function: + * int vcos_verify_bkpts_enabled(void); + * Use: + * Queries the state of the global flag enabling breakpoints on vcos_verify + * failures. + * Returns: + * The current state of the flag. + * + * Examples: + * + * int my_breakpoint_enable_flag = 1; + * + * #define VCOS_VERIFY_BKPTS my_breakpoint_enable_flag + * + * #include "vcos.h" + * + * vcos_static_assert((sizeof(object) % 32) == 0); + * + * // ... + * + * vcos_assert_msg(postcondition_is_true, "Coding error"); + * + * if (!vcos_verify_msg(buf, "Buffer allocation failed (%d bytes)", size)) + * { + * // Tidy up + * // ... + * return OUT_OF_MEMORY; + * } + * + * vcos_demand(*p++==GUARDWORDHEAP); + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "vcos_types.h" + +#ifdef __COVERITY__ +#include "user_nodefs.h" + +extern void __coverity_panic__(void); +#undef VCOS_ASSERT_BKPT +#define VCOS_ASSERT_BKPT __coverity_panic__() +#endif + +/* + * ANDROID should NOT be defined for files built for Videocore, but currently it + * is. FIXME When that's fixed, remove the __VIDEOCORE__ band-aid. + */ +#if (defined(ANDROID) && !defined(__VIDEOCORE__)) +# include "assert.h" +# define vcos_assert assert +#endif + +#ifndef VCOS_VERIFY_BKPTS +#define VCOS_VERIFY_BKPTS vcos_verify_bkpts_enabled() +#endif + +#ifndef VCOS_BKPT +#if defined(__VIDEOCORE__) && !defined(VCOS_ASSERT_NO_BKPTS) +#define VCOS_BKPT _bkpt() +#else +#define VCOS_BKPT (void )0 +#endif +#endif + +#ifndef VCOS_ASSERT_BKPT +#define VCOS_ASSERT_BKPT VCOS_BKPT +#endif + +#ifndef VCOS_VERIFY_BKPT +#define VCOS_VERIFY_BKPT (VCOS_VERIFY_BKPTS ? VCOS_BKPT : (void)0) +#endif + +VCOSPRE_ int VCOSPOST_ vcos_verify_bkpts_enabled(void); +VCOSPRE_ int VCOSPOST_ vcos_verify_bkpts_enable(int enable); +VCOSPRE_ void VCOSPOST_ vcos_abort(void); + +#ifndef VCOS_ASSERT_MSG +#ifdef LOGGING +extern void logging_assert(const char *file, const char *func, int line, const char *format, ...); +extern void logging_assert_dump(void); +#define VCOS_ASSERT_MSG(...) ((VCOS_ASSERT_LOGGING && !VCOS_ASSERT_LOGGING_DISABLE) ? logging_assert_dump(), logging_assert(__FILE__, __func__, __LINE__, __VA_ARGS__) : (void)0) +#else +#define VCOS_ASSERT_MSG(...) ((void)0) +#endif +#endif + +#ifndef VCOS_VERIFY_MSG +#define VCOS_VERIFY_MSG(...) VCOS_ASSERT_MSG(__VA_ARGS__) +#endif + +#ifndef VCOS_ASSERT_LOGGING +#define VCOS_ASSERT_LOGGING 0 +#endif + +#ifndef VCOS_ASSERT_LOGGING_DISABLE +#define VCOS_ASSERT_LOGGING_DISABLE 0 +#endif + +#if !defined(NDEBUG) || defined(VCOS_RELEASE_ASSERTS) +#define VCOS_ASSERT_ENABLED 1 +#define VCOS_VERIFY_ENABLED 1 +#else +#define VCOS_ASSERT_ENABLED 0 +#define VCOS_VERIFY_ENABLED 0 +#endif + +#define VCOS_DEMAND_ENABLED 1 + +#if VCOS_ASSERT_ENABLED + +#ifndef vcos_assert +#define vcos_assert(cond) \ + ( (cond) ? (void)0 : (VCOS_ASSERT_MSG("%s", #cond), VCOS_ASSERT_BKPT) ) +#endif + +#ifndef vcos_assert_msg +#define vcos_assert_msg(cond, ...) \ + ( (cond) ? (void)0 : (VCOS_ASSERT_MSG(__VA_ARGS__), VCOS_ASSERT_BKPT) ) +#endif + +#else /* VCOS_ASSERT_ENABLED */ + +#ifndef vcos_assert +#define vcos_assert(cond) (void)0 +#endif + +#ifndef vcos_assert_msg +#define vcos_assert_msg(cond, ...) (void)0 +#endif + +#endif /* VCOS_ASSERT_ENABLED */ + + +#if VCOS_DEMAND_ENABLED + +#ifndef vcos_demand +#define vcos_demand(cond) \ + ( (cond) ? (void)0 : (VCOS_ASSERT_MSG("%s", #cond), VCOS_ASSERT_BKPT, vcos_abort()) ) +#endif + +#ifndef vcos_demand_msg +#define vcos_demand_msg(cond, ...) \ + ( (cond) ? (void)0 : (VCOS_ASSERT_MSG(__VA_ARGS__), VCOS_ASSERT_BKPT, vcos_abort()) ) +#endif + +#else /* VCOS_DEMAND_ENABLED */ + +#ifndef vcos_demand +#define vcos_demand(cond) \ + ( (cond) ? (void)0 : vcos_abort() ) +#endif + +#ifndef vcos_demand_msg +#define vcos_demand_msg(cond, ...) \ + ( (cond) ? (void)0 : vcos_abort() ) +#endif + +#endif /* VCOS_DEMAND_ENABLED */ + + +#if VCOS_VERIFY_ENABLED + +#ifndef vcos_verify +#define vcos_verify(cond) \ + ( (cond) ? 1 : (VCOS_VERIFY_MSG("%s", #cond), VCOS_VERIFY_BKPT, 0) ) +#endif + +#ifndef vcos_verify_msg +#define vcos_verify_msg(cond, ...) \ + ( (cond) ? 1 : (VCOS_VERIFY_MSG(__VA_ARGS__), VCOS_VERIFY_BKPT, 0) ) +#endif + +#else /* VCOS_VERIFY_ENABLED */ + +#ifndef vcos_verify +#define vcos_verify(cond) (cond) +#endif + +#ifndef vcos_verify_msg +#define vcos_verify_msg(cond, ...) (cond) +#endif + +#endif /* VCOS_VERIFY_ENABLED */ + + +#ifndef vcos_static_assert +#if defined(__GNUC__) +#define vcos_static_assert(cond) __attribute__((unused)) extern int vcos_static_assert[(cond)?1:-1] +#else +#define vcos_static_assert(cond) extern int vcos_static_assert[(cond)?1:-1] +#endif +#endif + +#ifndef vc_assert +#define vc_assert(cond) vcos_assert(cond) +#endif + +#define vcos_unreachable() vcos_assert(0) +#define vcos_not_impl() vcos_assert(0) + +/** Print out a backtrace, on supported platforms. + */ +extern void vcos_backtrace_self(void); + +#ifdef __cplusplus +} +#endif + +#endif /* VCOS_ASSERT_H */ diff --git a/external_src/raspicam-0.1.3/dependencies/vcos/vcos_atomic_flags.h b/external_src/raspicam-0.1.3/dependencies/vcos/vcos_atomic_flags.h new file mode 100644 index 0000000..1f743fa --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/vcos/vcos_atomic_flags.h @@ -0,0 +1,92 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. +*/ + +/*============================================================================= +VideoCore OS Abstraction Layer - public header file +=============================================================================*/ + +#ifndef VCOS_ATOMIC_FLAGS_H +#define VCOS_ATOMIC_FLAGS_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "vcos_types.h" +#include "pthreads/vcos_platform.h" + +/** + * \file vcos_atomic_flags.h + * + * Defines atomic flags API. + * + * 32 flags. Atomic "or" and "get and clear" operations + */ + +/** + * Create an atomic flags instance. + * + * @param atomic_flags Pointer to atomic flags instance, filled in on return + * + * @return VCOS_SUCCESS if succeeded. + */ +VCOS_INLINE_DECL +VCOS_STATUS_T vcos_atomic_flags_create(VCOS_ATOMIC_FLAGS_T *atomic_flags); + +/** + * Atomically set the specified flags. + * + * @param atomic_flags Instance to set flags on + * @param flags Mask of flags to set + */ +VCOS_INLINE_DECL +void vcos_atomic_flags_or(VCOS_ATOMIC_FLAGS_T *atomic_flags, uint32_t flags); + +/** + * Retrieve the current flags and then clear them. The entire operation is + * atomic. + * + * @param atomic_flags Instance to get/clear flags from/on + * + * @return Mask of flags which were set (and we cleared) + */ +VCOS_INLINE_DECL +uint32_t vcos_atomic_flags_get_and_clear(VCOS_ATOMIC_FLAGS_T *atomic_flags); + +/** + * Delete an atomic flags instance. + * + * @param atomic_flags Instance to delete + */ +VCOS_INLINE_DECL +void vcos_atomic_flags_delete(VCOS_ATOMIC_FLAGS_T *atomic_flags); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external_src/raspicam-0.1.3/dependencies/vcos/vcos_attr.h b/external_src/raspicam-0.1.3/dependencies/vcos/vcos_attr.h new file mode 100644 index 0000000..33f7eee --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/vcos/vcos_attr.h @@ -0,0 +1,153 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. +*/ + +/*============================================================================= +VideoCore OS Abstraction Layer - compiler-specific attributes +=============================================================================*/ + +#ifndef VCOS_ATTR_H +#define VCOS_ATTR_H + +/** + * Type attribute indicating the enum should be stored in as few bytes as + * possible. MetaWare does this by default, so the attribute is useful when + * structs need to be portable to GCC too. + * + * MSVC doesn't support VCOS_ENUM_PACKED, so code that needs to be portable + * across all platforms but wants the type-safety and debug-info benefits + * of enum types when possible, should do: + * + * typedef enum VCOS_ENUM_PACKED { a = 0, b = 0xffff } EXAMPLE_T; + * struct foo { + * int bar; + * #if VCOS_HAS_ENUM_PACKED + * EXAMPLE_T baz; + * #else + * uint16_t baz; + * #endif + * }; + */ + +#if defined(__VECTORC__) +# define VCOS_ENUM_PACKED +# define VCOS_HAS_ENUM_PACKED 0 +#elif defined(__GNUC__) +# define VCOS_ENUM_PACKED __attribute__ ((packed)) +# define VCOS_HAS_ENUM_PACKED 1 +#elif defined(__HIGHC__) +# define VCOS_ENUM_PACKED /* packed enums are default on Metaware */ +# define VCOS_HAS_ENUM_PACKED 1 +#else +# define VCOS_ENUM_PACKED +# define VCOS_HAS_ENUM_PACKED 0 +#endif + +/** Variable attribute indicating the variable must be emitted even if it appears unused. */ +#if defined(__GNUC__) || defined(__HIGHC__) +# define VCOS_ATTR_USED __attribute__ ((used)) +#else +# define VCOS_ATTR_USED +#endif + +/** Variable attribute indicating the compiler should not warn if the variable is unused. */ +#if defined(__GNUC__) || defined(__HIGHC__) +# define VCOS_ATTR_POSSIBLY_UNUSED __attribute__ ((unused)) +#else +# define VCOS_ATTR_POSSIBLY_UNUSED +#endif + +/** Variable attribute requiring specific alignment. + * + * Use as: + * int VCOS_ATTR_ALIGNED(256) n; + * or: + * VCOS_ATTR_ALIGNED(256) int n; + * or if you don't want to support MSVC: + * int n VCOS_ATTR_ALIGNED(256); + */ +#if defined(__GNUC__) || defined(__HIGHC__) +# define VCOS_ATTR_ALIGNED(n) __attribute__ ((aligned(n))) +#elif defined(_MSC_VER) +# define VCOS_ATTR_ALIGNED(n) __declspec(align(n)) +#else +/* Force a syntax error if this is used when the compiler doesn't support it, + * instead of silently misaligning */ +# define VCOS_ATTR_ALIGNED(n) VCOS_ATTR_ALIGNED_NOT_SUPPORTED_ON_THIS_COMPILER +#endif + +/** Variable attribute requiring specific ELF section. + * + * Use as: + * int n VCOS_ATTR_SECTION(".foo") = 1; + * + * A pointer like &n will have type "VCOS_ATTR_SECTION_QUALIFIER int *". + */ +#if defined(__HIGHC__) || defined(__VECTORC__) +/* hcvc requires 'far' else it'll put small objects in .sdata/.rsdata/.sbss */ +# define VCOS_ATTR_SECTION(s) __attribute__ ((far, section(s))) +# define VCOS_ATTR_SECTION_QUALIFIER _Far +#elif defined(__GNUC__) +# define VCOS_ATTR_SECTION(s) __attribute__ ((section(s))) +# define VCOS_ATTR_SECTION_QUALIFIER +#else +/* Force a syntax error if this is used when the compiler doesn't support it */ +# define VCOS_ATTR_SECTION(s) VCOS_ATTR_SECTION_NOT_SUPPORTED_ON_THIS_COMPILER +# define VCOS_ATTR_SECTION_QUALIFIER +#endif + +/** Define a function as a weak alias to another function. + * @param ret_type Function return type. + * @param alias_name Name of the alias. + * @param param_list Function parameter list, including the parentheses. + * @param target_name Target function (bare function name, not a string). + */ +#if defined(__GNUC__) || defined(__HIGHC__) + /* N.B. gcc allows __attribute__ after parameter list, but hcvc seems to silently ignore it. */ +# define VCOS_WEAK_ALIAS(ret_type, alias_name, param_list, target_name) \ + __attribute__ ((weak, alias(#target_name))) ret_type alias_name param_list +#else +# define VCOS_WEAK_ALIAS(ret_type, alias, params, target) VCOS_CASSERT(0) +#endif + +/** Define a function as a weak alias to another function, specified as a string. + * @param ret_type Function return type. + * @param alias_name Name of the alias. + * @param param_list Function parameter list, including the parentheses. + * @param target_name Target function name as a string. + * @note Prefer the use of VCOS_WEAK_ALIAS - it is likely to be more portable. + * Only use VCOS_WEAK_ALIAS_STR if you need to do pre-processor mangling of the target + * symbol. + */ +#if defined(__GNUC__) || defined(__HIGHC__) + /* N.B. gcc allows __attribute__ after parameter list, but hcvc seems to silently ignore it. */ +# define VCOS_WEAK_ALIAS_STR(ret_type, alias_name, param_list, target_name) \ + __attribute__ ((weak, alias(target_name))) ret_type alias_name param_list +#else +# define VCOS_WEAK_ALIAS_STR(ret_type, alias, params, target) VCOS_CASSERT(0) +#endif + +#endif /* VCOS_ATTR_H */ diff --git a/external_src/raspicam-0.1.3/dependencies/vcos/vcos_blockpool.h b/external_src/raspicam-0.1.3/dependencies/vcos/vcos_blockpool.h new file mode 100644 index 0000000..3ac1e25 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/vcos/vcos_blockpool.h @@ -0,0 +1,171 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. +*/ + +/*============================================================================= +VideoCore OS Abstraction Layer - fixed size allocator support +=============================================================================*/ + +#ifndef VCOS_BLOCKPOOL_H +#define VCOS_BLOCKPOOL_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "vcos_types.h" +#include "pthreads/vcos_platform.h" + +/** \file + * + * Thread safe, fixed size allocator API. + * + */ + +/** Initialises a block pool to use already allocated (e.g. statically) + * allocated memory. + * + * Different implementations will incur different overheads. Use + * VCOS_BLOCKPOOL_SIZE(num_blocks, block_size) to calculate the number + * of bytes required including overheads for the desired pools. + * + * @param pool Pointer to pool object + * @param num_blocks The number of blocks required. + * @param block_size The size of an individual block. + * @param start The address of the start of the pool. + * @param pool_size The size of the pool in bytes. + * @param align Alignment for block data. Use VCOS_BLOCKPOOL_ALIGN_DEFAULT + * for default word alignment. + * @param flags Reserved for future use. + * @param name Name of the pool. Used for diagnostics. + * + * @return VCOS_SUCCESS if the pool was created. + */ + +VCOS_INLINE_DECL +VCOS_STATUS_T vcos_blockpool_init(VCOS_BLOCKPOOL_T *pool, + VCOS_UNSIGNED num_blocks, VCOS_UNSIGNED block_size, + void *start, VCOS_UNSIGNED pool_size, VCOS_UNSIGNED align, + VCOS_UNSIGNED flags, const char *name); + +/** Creates a pool of blocks of a given size within a buffer allocated on + * the heap. + * + * The heap memory is freed when the block pool is destroyed by + * calling vcos_blockpool_delete. + * + * @param pool Pointer to pool object + * @param num_blocks The number of blocks required. + * @param block_size The size of an individual block. + * @param align Alignment for block data. Use VCOS_BLOCKPOOL_ALIGN_DEFAULT + * for default word alignment. + * @param flags Reserved for future use. + * @param name Name of the pool. Used for diagnostics. + * + * @return VCOS_SUCCESS if the pool was created. + */ +VCOS_INLINE_DECL +VCOS_STATUS_T vcos_blockpool_create_on_heap(VCOS_BLOCKPOOL_T *pool, + VCOS_UNSIGNED num_blocks, VCOS_UNSIGNED block_size, + VCOS_UNSIGNED align, VCOS_UNSIGNED flags, + const char *name); + +/** Allocate a block from the pool + * + * @param pool Pointer to the pool to allocate from. + * @return a pointer to the newly allocated block or NULL if no blocks were + * available. + */ +VCOS_INLINE_DECL +void *vcos_blockpool_alloc(VCOS_BLOCKPOOL_T *pool); + +/** Allocate a block from the pool and zero it. + * + * @param pool Pointer to the pool to allocate from. + * @return a pointer to the newly allocated block or NULL if no blocks were + * available. + */ +VCOS_INLINE_DECL +void *vcos_blockpool_calloc(VCOS_BLOCKPOOL_T *pool); + +/** Returns a block to the pool. + * + * @param block The block to free. + */ +VCOS_INLINE_DECL +void vcos_blockpool_free(void *block); + +/** Queries the number of available blocks in the pool. + * @param pool The pool to query. + */ +VCOS_INLINE_IMPL + VCOS_UNSIGNED vcos_blockpool_available_count(VCOS_BLOCKPOOL_T *pool); + +/** Queries the number of used blocks in the pool. + * @param pool The pool to query. + */ +VCOS_INLINE_IMPL + VCOS_UNSIGNED vcos_blockpool_used_count(VCOS_BLOCKPOOL_T *pool); + +/** Deinitialize a memory pool. + * + * @param pool The pool to de-initialize. + */ +VCOS_INLINE_DECL +void vcos_blockpool_delete(VCOS_BLOCKPOOL_T *pool); + +/** Return an integer handle for a given allocated block. */ +VCOS_INLINE_DECL +uint32_t vcos_blockpool_elem_to_handle(void *block); + +/** Convert an integer handle back into a pointer. + * Returns NULL if invalid. */ +VCOS_INLINE_DECL +void *vcos_blockpool_elem_from_handle(VCOS_BLOCKPOOL_T *pool, uint32_t handle); + +/** Checks whether a pointer is an allocated block within the specified pool. + * Returns true if the block is valid, otherwise, false is returned. */ +VCOS_INLINE_DECL +uint32_t vcos_blockpool_is_valid_elem( + VCOS_BLOCKPOOL_T *pool, const void *block); + +/** May be called once to allow the block pool to be extended by dynamically + * adding subpools. The block size cannot be altered. + * + * @param num_extensions The number of extensions that may be created. + * The maximum is (VCOS_BLOCKPOOL_MAX_SUBPOOLS - 1) + * @param num_blocks The number of blocks to allocate in each in each + * dynamically allocated subpool. + * @return VCOS_SUCCESS if successful. + */ +VCOS_INLINE_DECL + VCOS_STATUS_T vcos_blockpool_extend(VCOS_BLOCKPOOL_T *pool, + VCOS_UNSIGNED num_extensions, VCOS_UNSIGNED num_blocks); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/external_src/raspicam-0.1.3/dependencies/vcos/vcos_build_info.h b/external_src/raspicam-0.1.3/dependencies/vcos/vcos_build_info.h new file mode 100644 index 0000000..710619e --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/vcos/vcos_build_info.h @@ -0,0 +1,32 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. +*/ + +const char *vcos_get_build_hostname( void ); +const char *vcos_get_build_version( void ); +const char *vcos_get_build_time( void ); +const char *vcos_get_build_date( void ); + diff --git a/external_src/raspicam-0.1.3/dependencies/vcos/vcos_cfg.h b/external_src/raspicam-0.1.3/dependencies/vcos/vcos_cfg.h new file mode 100644 index 0000000..c510624 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/vcos/vcos_cfg.h @@ -0,0 +1,126 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. +*/ + +#if !defined( VCOS_CFG_H ) +#define VCOS_CFG_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "vcos_types.h" +#include "pthreads/vcos_platform.h" + +typedef struct opaque_vcos_cfg_buf_t *VCOS_CFG_BUF_T; +typedef struct opaque_vcos_cfg_entry_t *VCOS_CFG_ENTRY_T; + +/** \file vcos_file.h + * + * API for accessing configuration/statistics information. This + * is loosely modelled on the linux proc entries. + */ + +typedef void (*VCOS_CFG_SHOW_FPTR)( VCOS_CFG_BUF_T buf, void *data ); +typedef void (*VCOS_CFG_PARSE_FPTR)( VCOS_CFG_BUF_T buf, void *data ); + +/** Create a configuration directory. + * + * @param entry Place to store the created config entry. + * @param parent Parent entry (for directory like config + * options). + * @param entryName Name of the directory. + */ + +VCOS_STATUS_T vcos_cfg_mkdir( VCOS_CFG_ENTRY_T *entry, + VCOS_CFG_ENTRY_T *parent, + const char *dirName ); + +/** Create a configuration entry. + * + * @param entry Place to store the created config entry. + * @param parent Parent entry (for directory like config + * options). + * @param entryName Name of the configuration entry. + * @param showFunc Function pointer to show configuration + * data. + * @param parseFunc Function pointer to parse new data. + */ + +VCOS_STATUS_T vcos_cfg_create_entry( VCOS_CFG_ENTRY_T *entry, + VCOS_CFG_ENTRY_T *parent, + const char *entryName, + VCOS_CFG_SHOW_FPTR showFunc, + VCOS_CFG_PARSE_FPTR parseFunc, + void *data ); + +/** Determines if a configuration entry has been created or not. + * + * @param entry Configuration entry to query. + */ + +int vcos_cfg_is_entry_created( VCOS_CFG_ENTRY_T entry ); + +/** Returns the name of a configuration entry. + * + * @param entry Configuration entry to query. + */ + +const char *vcos_cfg_get_entry_name( VCOS_CFG_ENTRY_T entry ); + +/** Removes a configuration entry. + * + * @param entry Configuration entry to remove. + */ + +VCOS_STATUS_T vcos_cfg_remove_entry( VCOS_CFG_ENTRY_T *entry ); + + +/** Writes data into a configuration buffer. Only valid inside + * the show function. + * + * @param buf Buffer to write data into. + * @param fmt printf style format string. + */ + +void vcos_cfg_buf_printf( VCOS_CFG_BUF_T buf, const char *fmt, ... ); + +/** Retrieves a null terminated string of the data associated + * with the buffer. Only valid inside the parse function. + * + * @param buf Buffer to get data from. + * @param fmt printf style format string. + */ + +char *vcos_cfg_buf_get_str( VCOS_CFG_BUF_T buf ); + +void *vcos_cfg_get_proc_entry( VCOS_CFG_ENTRY_T entry ); + +#ifdef __cplusplus +} +#endif +#endif + diff --git a/external_src/raspicam-0.1.3/dependencies/vcos/vcos_cmd.h b/external_src/raspicam-0.1.3/dependencies/vcos/vcos_cmd.h new file mode 100644 index 0000000..16b1531 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/vcos/vcos_cmd.h @@ -0,0 +1,119 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. +*/ + +#if !defined( VCOS_CMD_H ) +#define VCOS_CMD_H + +/* ---- Include Files ----------------------------------------------------- */ + +#ifndef VCOS_H +#include "vcos.h" +#endif +#include "vcos_stdint.h" + + +/* ---- Constants and Types ---------------------------------------------- */ + +struct VCOS_CMD_S; +typedef struct VCOS_CMD_S VCOS_CMD_T; + +typedef struct +{ + int argc; /* Number of arguments (includes the command/sub-command) */ + char **argv; /* Array of arguments */ + char **argv_orig; /* Original array of arguments */ + + VCOS_CMD_T *cmd_entry; + VCOS_CMD_T *cmd_parent_entry; + + int use_log; /* Output being logged? */ + size_t result_size; /* Size of result buffer. */ + char *result_ptr; /* Next place to put output. */ + char *result_buf; /* Start of the buffer. */ + +} VCOS_CMD_PARAM_T; + +typedef VCOS_STATUS_T (*VCOS_CMD_FUNC_T)( VCOS_CMD_PARAM_T *param ); + +struct VCOS_CMD_S +{ + const char *name; + const char *args; + VCOS_CMD_FUNC_T cmd_fn; + VCOS_CMD_T *sub_cmd_entry; + const char *descr; + +}; + +/* ---- Variable Externs ------------------------------------------------- */ + +/* ---- Function Prototypes ---------------------------------------------- */ + +/* + * Common printing routine for generating command output. + */ +VCOSPRE_ void VCOSPOST_ vcos_cmd_error( VCOS_CMD_PARAM_T *param, const char *fmt, ... ) VCOS_FORMAT_ATTR_(printf, 2, 3); +VCOSPRE_ void VCOSPOST_ vcos_cmd_printf( VCOS_CMD_PARAM_T *param, const char *fmt, ... ) VCOS_FORMAT_ATTR_(printf, 2, 3); +VCOSPRE_ void VCOSPOST_ vcos_cmd_vprintf( VCOS_CMD_PARAM_T *param, const char *fmt, va_list args ) VCOS_FORMAT_ATTR_(printf, 2, 0); + +/* + * Cause vcos_cmd_error, printf and vprintf to always log to the provided + * category. When this call is made, the results buffer passed into + * vcos_cmd_execute is used as a line buffer and does not need to be + * output by the caller. + */ +VCOSPRE_ void VCOSPOST_ vcos_cmd_always_log_output( VCOS_LOG_CAT_T *log_category ); + +/* + * Prints command usage for the current command. + */ +VCOSPRE_ void VCOSPOST_ vcos_cmd_usage( VCOS_CMD_PARAM_T *param ); + +/* + * Register commands to be processed + */ +VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_cmd_register( VCOS_CMD_T *cmd_entry ); + +/* + * Registers multiple commands to be processed. The array should + * be terminated by an entry with all zeros. + */ +VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_cmd_register_multiple( VCOS_CMD_T *cmd_entry ); + +/* + * Executes a command based on a command line. + */ +VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_cmd_execute( int argc, char **argv, size_t result_size, char *result_buf ); + +/* + * Shut down the command system and free all allocated data. + * Do not call any other command functions after this. + */ +VCOSPRE_ void VCOSPOST_ vcos_cmd_shutdown( void ); + +#endif /* VCOS_CMD_H */ + diff --git a/external_src/raspicam-0.1.3/dependencies/vcos/vcos_ctype.h b/external_src/raspicam-0.1.3/dependencies/vcos/vcos_ctype.h new file mode 100644 index 0000000..64bda96 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/vcos/vcos_ctype.h @@ -0,0 +1,49 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. +*/ + +/*============================================================================= +VideoCore OS Abstraction Layer - public header file +=============================================================================*/ + +#ifndef VCOS_CTYPE_H +#define VCOS_CTYPE_H + +/** + * \file + * + * ctype functions. + * + */ + +#ifdef __KERNEL__ +#include +#else +#include +#endif + +#endif + diff --git a/external_src/raspicam-0.1.3/dependencies/vcos/vcos_dlfcn.h b/external_src/raspicam-0.1.3/dependencies/vcos/vcos_dlfcn.h new file mode 100644 index 0000000..1d563d5 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/vcos/vcos_dlfcn.h @@ -0,0 +1,86 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. +*/ + +/*============================================================================= +VCOS - abstraction over dynamic library opening +=============================================================================*/ + +#ifndef VCOS_DLFCN_H +#define VCOS_DLFCN_H + +#include "vcos_types.h" +#include "pthreads/vcos_platform.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \file + * + * Loading dynamic libraries. See also dlfcn.h. + */ + +/** Open a dynamic library. + * + * @param name name of the library + * @param mode Load lazily or immediately (VCOS_DL_LAZY, VCOS_DL_NOW, VCOS_DL_LOCAL, VCOS_DL_GLOBAL). + * + * @return A handle for use in subsequent calls. + */ +VCOSPRE_ void * VCOSPOST_ vcos_dlopen(const char *name, int mode); + +/** Look up a symbol. + * + * @param handle Handle to open + * @param name Name of function + * + * @return Function pointer, or NULL. + */ +VCOSPRE_ void VCOSPOST_ (*vcos_dlsym(void *handle, const char *name))(void); + +/** Close a library + * + * @param handle Handle to close + */ +VCOSPRE_ int VCOSPOST_ vcos_dlclose (void *handle); + +/** Return error message from library. + * + * @param err On return, set to non-zero if an error has occurred + * @param buf Buffer to write error to + * @param len Size of buffer (including terminating NUL). + */ +VCOSPRE_ int VCOSPOST_ vcos_dlerror(int *err, char *buf, size_t buflen); + + +#ifdef __cplusplus +} +#endif +#endif + + diff --git a/external_src/raspicam-0.1.3/dependencies/vcos/vcos_event.h b/external_src/raspicam-0.1.3/dependencies/vcos/vcos_event.h new file mode 100644 index 0000000..ddf4b4a --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/vcos/vcos_event.h @@ -0,0 +1,117 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. +*/ + +/*============================================================================= +VideoCore OS Abstraction Layer - public header file for events +=============================================================================*/ + +#ifndef VCOS_EVENT_H +#define VCOS_EVENT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "vcos_types.h" +#include "pthreads/vcos_platform.h" + +/** + * \file + * + * An event is akin to the Win32 auto-reset event. + * + * + * Signalling an event will wake up one waiting thread only. Once one + * thread has been woken the event atomically returns to the unsignalled + * state. + * + * If no threads are waiting on the event when it is signalled it remains + * signalled. + * + * This is almost, but not quite, completely unlike the "event flags" + * object based on Nucleus event groups and ThreadX event flags. + * + * In particular, it should be similar in speed to a semaphore, unlike + * the event flags. + */ + +/** + * Create an event instance. + * + * @param event Filled in with constructed event. + * @param name Name of the event (for debugging) + * + * @return VCOS_SUCCESS on success, or error code. + */ +VCOS_INLINE_DECL +VCOS_STATUS_T vcos_event_create(VCOS_EVENT_T *event, const char *name); + +#ifndef vcos_event_signal + +/** + * Signal the event. The event will return to being unsignalled + * after exactly one waiting thread has been woken up. If no + * threads are waiting it remains signalled. + * + * @param event The event to signal + */ +VCOS_INLINE_DECL +void vcos_event_signal(VCOS_EVENT_T *event); + +/** + * Wait for the event. + * + * @param event The event to wait for + * @return VCOS_SUCCESS on success, VCOS_EAGAIN if the wait was interrupted. + */ +VCOS_INLINE_DECL +VCOS_STATUS_T vcos_event_wait(VCOS_EVENT_T *event); + +/** + * Try event, but don't block. + * + * @param event The event to try + * @return VCOS_SUCCESS on success, VCOS_EAGAIN if the event is not currently signalled + */ +VCOS_INLINE_DECL +VCOS_STATUS_T vcos_event_try(VCOS_EVENT_T *event); + +#endif + +/* + * Destroy an event. + */ +VCOS_INLINE_DECL +void vcos_event_delete(VCOS_EVENT_T *event); + +#ifdef __cplusplus +} +#endif + +#endif + + diff --git a/external_src/raspicam-0.1.3/dependencies/vcos/vcos_event_flags.h b/external_src/raspicam-0.1.3/dependencies/vcos/vcos_event_flags.h new file mode 100644 index 0000000..e539ec9 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/vcos/vcos_event_flags.h @@ -0,0 +1,118 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. +*/ + +/*============================================================================= +VideoCore OS Abstraction Layer - public header file +=============================================================================*/ + +#ifndef VCOS_EVENT_FLAGS_H +#define VCOS_EVENT_FLAGS_H + + +#ifdef __cplusplus +extern "C" { +#endif + +#include "vcos_types.h" +#include "pthreads/vcos_platform.h" + +#define VCOS_EVENT_FLAGS_SUSPEND VCOS_SUSPEND +#define VCOS_EVENT_FLAGS_NO_SUSPEND VCOS_NO_SUSPEND +typedef VCOS_OPTION VCOS_EVENTGROUP_OPERATION_T; + +/** + * \file vcos_event_flags.h + * + * Defines event flags API. + * + * Similar to Nucleus event groups. + * + * These have the same semantics as Nucleus event groups and ThreadX event + * flags. As such, they are quite complex internally; if speed is important + * they might not be your best choice. + * + */ + +/** + * Create an event flags instance. + * + * @param flags Pointer to event flags instance, filled in on return. + * @param name Name for the event flags, used for debug. + * + * @return VCOS_SUCCESS if succeeded. + */ + +VCOS_INLINE_DECL +VCOS_STATUS_T vcos_event_flags_create(VCOS_EVENT_FLAGS_T *flags, const char *name); + +/** + * Set some events. + * + * @param flags Instance to set flags on + * @param events Bitmask of the flags to actually set + * @param op How the flags should be set. VCOS_OR will OR in the flags; VCOS_AND + * will AND them in, possibly clearing existing flags. + */ +VCOS_INLINE_DECL +void vcos_event_flags_set(VCOS_EVENT_FLAGS_T *flags, + VCOS_UNSIGNED events, + VCOS_OPTION op); + +/** + * Retrieve some events. + * + * Waits until the specified events have been set. + * + * @param flags Instance to wait on + * @param requested_events The bitmask to wait for + * @param op VCOS_OR - get any; VCOS_AND - get all. + * @param ms_suspend How long to wait, in milliseconds + * @param retrieved_events the events actually retrieved. + * + * @return VCOS_SUCCESS if events were retrieved. VCOS_EAGAIN if the + * timeout expired. + */ +VCOS_INLINE_DECL +VCOS_STATUS_T vcos_event_flags_get(VCOS_EVENT_FLAGS_T *flags, + VCOS_UNSIGNED requested_events, + VCOS_OPTION op, + VCOS_UNSIGNED ms_suspend, + VCOS_UNSIGNED *retrieved_events); + + +/** + * Delete an event flags instance. + */ +VCOS_INLINE_DECL +void vcos_event_flags_delete(VCOS_EVENT_FLAGS_T *); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/external_src/raspicam-0.1.3/dependencies/vcos/vcos_init.h b/external_src/raspicam-0.1.3/dependencies/vcos/vcos_init.h new file mode 100644 index 0000000..20e149f --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/vcos/vcos_init.h @@ -0,0 +1,110 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. +*/ + +/*============================================================================= +VideoCore OS Abstraction Layer - initialization routines +=============================================================================*/ + + +#include "vcos_types.h" +#include "pthreads/vcos_platform.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** \file + * + * Some OS support libraries need some initialization. To support this, call + * vcos_init() function at the start of day; vcos_deinit() at the end. + */ + +/** + * vcos initialization. Call this function before using other vcos functions. + * Calls can be nested within the same process; they are reference counted so + * that only a call from uninitialized state has any effect. + * @note On platforms/toolchains that support it, gcc's constructor attribute or + * similar is used to invoke this function before main() or equivalent. + * @return Status of initialisation. + */ +VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_init(void); + +/** + * vcos deinitialization. Call this function when vcos is no longer required, + * in order to free resources. + * Calls can be nested within the same process; they are reference counted so + * that only a call that decrements the reference count to 0 has any effect. + * @note On platforms/toolchains that support it, gcc's destructor attribute or + * similar is used to invoke this function after exit() or equivalent. + * @return Status of initialisation. + */ +VCOSPRE_ void VCOSPOST_ vcos_deinit(void); + +/** + * Acquire global lock. This must be available independent of vcos_init()/vcos_deinit(). + */ +VCOSPRE_ void VCOSPOST_ vcos_global_lock(void); + +/** + * Release global lock. This must be available independent of vcos_init()/vcos_deinit(). + */ +VCOSPRE_ void VCOSPOST_ vcos_global_unlock(void); + +/** Pass in the argv/argc arguments passed to main() */ +VCOSPRE_ void VCOSPOST_ vcos_set_args(int argc, const char **argv); + +/** Return argc. */ +VCOSPRE_ int VCOSPOST_ vcos_get_argc(void); + +/** Return argv. */ +VCOSPRE_ const char ** VCOSPOST_ vcos_get_argv(void); + +/** + * Platform-specific initialisation. + * VCOS internal function, not part of public API, do not call from outside + * vcos. vcos_init()/vcos_deinit() reference count calls, so this function is + * only called from an uninitialized state, i.e. there will not be two + * consecutive calls to vcos_platform_init() without an intervening call to + * vcos_platform_deinit(). + * This function is called with vcos_global_lock held. + * @return Status of initialisation. + */ +VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_platform_init(void); + +/** + * Platform-specific de-initialisation. + * VCOS internal function, not part of public API, do not call from outside + * vcos. + * See vcos_platform_init() re reference counting. + * This function is called with vcos_global_lock held. + */ +VCOSPRE_ void VCOSPOST_ vcos_platform_deinit(void); + +#ifdef __cplusplus +} +#endif + diff --git a/external_src/raspicam-0.1.3/dependencies/vcos/vcos_inttypes.h b/external_src/raspicam-0.1.3/dependencies/vcos/vcos_inttypes.h new file mode 100644 index 0000000..ba254d5 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/vcos/vcos_inttypes.h @@ -0,0 +1,49 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 VCOS_INTTYPES_H +#define VCOS_INTTYPES_H + +/** \file + * Attempt to provide the support for fixed width integer types as per + * inttypes.h. This simply includes inttypes.h, which should find the + * system/toolchain version if present, otherwise falling back to the version + * in . The vcos versions initially only provide the + * most common printf() macros. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#ifdef __cplusplus +} +#endif + +#endif /* VCOS_INTTYPES_H */ diff --git a/external_src/raspicam-0.1.3/dependencies/vcos/vcos_isr.h b/external_src/raspicam-0.1.3/dependencies/vcos/vcos_isr.h new file mode 100644 index 0000000..bf2e150 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/vcos/vcos_isr.h @@ -0,0 +1,90 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. +*/ + +/*============================================================================= +VideoCore OS Abstraction Layer - IRQ support +=============================================================================*/ + +#ifndef VCOS_ISR_H +#define VCOS_ISR_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "vcos_types.h" +#include "pthreads/vcos_platform.h" + +/** + * \file vcos_isr.h + * + * \section isr ISR support + * + * API for dispatching interrupts. + */ + +/** + * + * Register an interrupt handler. The old handler (if any) is returned in + * old_handler. The old handler should be called if the interrupt was not + * for you. + * + * The handler function will be called in a context with interrupts disabled, + * so should be written to be as short as possible. If significant processing + * is needed, the handler should delegate to a thread. + * + * The handler function can call any OS primitive that does not block (e.g. + * post a semaphore or set an event flag). Blocking operations (including memory + * allocation from the system heap) are not permitted. + * + * To deregister an ISR, pass in NULL. + * + * @param vec Vector to register for + * @param handler Handler to be called + * @param old_handler Updated with the old handler, or NULL. + */ + +VCOS_INLINE_DECL +void vcos_register_isr(VCOS_UNSIGNED vec, + VCOS_ISR_HANDLER_T handler, + VCOS_ISR_HANDLER_T *old_handler); + +/** Disable interrupts, returning the old value (enabled/disabled) to the caller. + */ +VCOS_INLINE_DECL +VCOS_UNSIGNED vcos_int_disable(void); + +/** Restore the previous interrupt enable/disable state. + */ +VCOS_INLINE_DECL +void vcos_int_restore(VCOS_UNSIGNED previous); + +#ifdef __cplusplus +} +#endif +#endif + diff --git a/external_src/raspicam-0.1.3/dependencies/vcos/vcos_legacy_isr.h b/external_src/raspicam-0.1.3/dependencies/vcos/vcos_legacy_isr.h new file mode 100644 index 0000000..62d1498 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/vcos/vcos_legacy_isr.h @@ -0,0 +1,102 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. +*/ + +/*============================================================================= +VideoCore OS Abstraction Layer - legacy (Nucleus) IRQ support +=============================================================================*/ + +#ifndef VCOS_LEGACY_ISR_H +#define VCOS_LEGACY_ISR_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "vcos_types.h" +#include "pthreads/vcos_platform.h" + +/** \file vcos_legacy_isr.h + * + * API for dispatching interrupts the Nucleus way, via a LISR and HISR. + * New code should use the single-dispatch scheme - the LISR/HISR + * distinction is not necessary. + * + * Under ThreadX, a HISR is implemented as a high-priority thread which + * waits on a counting semaphore to call the HISR function. Although this + * provides a good approximation to the Nucleus semantics, it is potentially + * slow if all you are trying to do is to wake a thread from LISR context. + */ + +/** Register a LISR. This is identical to the NU_Register_LISR API. + */ +VCOS_INLINE_DECL +VCOS_STATUS_T vcos_register_legacy_lisr(VCOS_UNSIGNED vecnum, + void (*lisr)(VCOS_INT), + void (**old_lisr)(VCOS_INT)); + +VCOS_INLINE_DECL +VCOS_STATUS_T vcos_legacy_hisr_create(VCOS_HISR_T *hisr, const char *name, + void (*entry)(void), + VCOS_UNSIGNED pri, + void *stack, VCOS_UNSIGNED stack_size); + +/** Activate a HISR. On an OS which has no distinction between a HISR and LISR, + * this may use some kind of emulation, which could well be less efficient than + * a normal ISR.` + * + * @param hisr HISR to activate. + */ +VCOS_INLINE_DECL +void vcos_legacy_hisr_activate(VCOS_HISR_T *hisr); + +/** Delete a HISR. + * + * @param hisr HISR to delete. + */ +VCOS_INLINE_DECL +void vcos_legacy_hisr_delete(VCOS_HISR_T *hisr); + +/** Are we in a legacy LISR? + * + * @return On Nucleus, non-zero if in a LISR. On other platforms, non-zero if + * in an interrupt. + */ +VCOS_INLINE_DECL +int vcos_in_legacy_lisr(void); + +/** Is the current thread actually a fake HISR thread? Only implemented + * on platforms that fake up HISRs. + */ + +#ifndef VCOS_LISRS_NEED_HISRS +VCOSPRE_ int VCOSPOST_ vcos_current_thread_is_fake_hisr_thread(VCOS_HISR_T *); +#endif + +#ifdef __cplusplus +} +#endif +#endif diff --git a/external_src/raspicam-0.1.3/dependencies/vcos/vcos_logging.h b/external_src/raspicam-0.1.3/dependencies/vcos/vcos_logging.h new file mode 100644 index 0000000..2a48d75 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/vcos/vcos_logging.h @@ -0,0 +1,315 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. +*/ + +/*============================================================================= +VideoCore OS Abstraction Layer - logging support +=============================================================================*/ + +#ifndef VCOS_LOGGING_H +#define VCOS_LOGGING_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#include "vcos_types.h" +#include "pthreads/vcos_platform.h" +#include "vcos_logging_control.h" + +/** + * \file + * + * Logging support + * + * This provides categorised logging. Clients register + * a category, and then get a number of logging levels for + * that category. + * + * The logging level flag is tested using a flag *before* the + * function call, which makes logging very fast when disabled - there + * is no function call overhead just to find out that this log + * message is disabled. + * + * \section VCOS_LOG_CATEGORY + * + * As a convenience, clients define VCOS_LOG_CATEGORY to point to + * their category; the various vcos_log_xxx() macros then expand to + * use this. + * + * e.g. + * + * #define VCOS_LOG_CATEGORY (&my_category) + * + * #include + * + * VCOS_LOG_CAT_T my_category; + * + * .... + * + * vcos_log_trace("Stuff happened: %d", n_stuff); + * + */ + +/** Logging levels */ +typedef enum VCOS_LOG_LEVEL_T +{ + VCOS_LOG_UNINITIALIZED = 0, + VCOS_LOG_NEVER, + VCOS_LOG_ERROR, + VCOS_LOG_WARN, + VCOS_LOG_INFO, + VCOS_LOG_TRACE, +} VCOS_LOG_LEVEL_T; + + +/** Initialize a logging category without going through vcos_log_register(). + * + * This is useful for the case where there is no obvious point to do the + * registration (no initialization function for the module). However, it + * means that your logging category is not registered, so cannot be easily + * changed at run-time. + */ +#define VCOS_LOG_INIT(n,l) { l, n, 0, {0}, 0, 0 } + +/** A registered logging category. + */ +typedef struct VCOS_LOG_CAT_T +{ + VCOS_LOG_LEVEL_T level; /**< Which levels are enabled for this category */ + const char *name; /**< Name for this category. */ + struct VCOS_LOG_CAT_T *next; + struct { + unsigned int want_prefix:1; + } flags; + unsigned int refcount; + void *platform_data; /**< platform specific data */ +} VCOS_LOG_CAT_T; + +typedef void (*VCOS_VLOG_IMPL_FUNC_T)(const VCOS_LOG_CAT_T *cat, VCOS_LOG_LEVEL_T _level, const char *fmt, va_list args); + +/** Convert a VCOS_LOG_LEVEL_T into a printable string. + * The platform needs to implement this function. + */ +VCOSPRE_ const char * VCOSPOST_ vcos_log_level_to_string( VCOS_LOG_LEVEL_T level ); + +/** Convert a string into a VCOS_LOG_LEVEL_T + * The platform needs to implement this function. + */ +VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_string_to_log_level( const char *str, VCOS_LOG_LEVEL_T *level ); + +/** Log a message. Basic API. Normal code should not use this. + * The platform needs to implement this function. + */ +VCOSPRE_ void VCOSPOST_ vcos_log_impl(const VCOS_LOG_CAT_T *cat, VCOS_LOG_LEVEL_T _level, const char *fmt, ...) VCOS_FORMAT_ATTR_(printf, 3, 4); + +/** Log a message using a varargs parameter list. Normal code should + * not use this. + */ +VCOSPRE_ void VCOSPOST_ vcos_vlog_impl(const VCOS_LOG_CAT_T *cat, VCOS_LOG_LEVEL_T _level, const char *fmt, va_list args) VCOS_FORMAT_ATTR_(printf, 3, 0); + +/** Set the function which does the actual logging output. + * Passing in NULL causes the default logging function to be + * used. + */ +VCOSPRE_ void VCOSPOST_ vcos_set_vlog_impl( VCOS_VLOG_IMPL_FUNC_T vlog_impl_func ); + +/** The default logging function, which is provided by each + * platform. + */ + +VCOSPRE_ void VCOSPOST_ vcos_vlog_default_impl(const VCOS_LOG_CAT_T *cat, VCOS_LOG_LEVEL_T _level, const char *fmt, va_list args) VCOS_FORMAT_ATTR_(printf, 3, 0); + +/* + * Initialise the logging subsystem. This is called from + * vcos_init() so you don't normally need to call it. + */ +VCOSPRE_ void VCOSPOST_ vcos_logging_init(void); + +/** Register a logging category. + * + * @param name the name of this category. + * @param category the category to register. + */ +VCOSPRE_ void VCOSPOST_ vcos_log_register(const char *name, VCOS_LOG_CAT_T *category); + +/** Unregister a logging category. + */ +VCOSPRE_ void VCOSPOST_ vcos_log_unregister(VCOS_LOG_CAT_T *category); + +/** Return a default logging category, for people too lazy to create their own. + * + * Using the default category will be slow (there's an extra function + * call overhead). Don't do this in normal code. + */ +VCOSPRE_ const VCOS_LOG_CAT_T * VCOSPOST_ vcos_log_get_default_category(void); + +VCOSPRE_ void VCOSPOST_ vcos_set_log_options(const char *opt); + +/** Set the logging level for a category at run time. Without this, the level + * will be that set by vcos_log_register from a platform-specific source. + * + * @param category the category to modify. + * @param level the new logging level for this category. + */ +VCOS_STATIC_INLINE void vcos_log_set_level(VCOS_LOG_CAT_T *category, VCOS_LOG_LEVEL_T level) +{ + category->level = level; +} + +#define vcos_log_dump_mem(cat,label,addr,voidMem,numBytes) do { if (vcos_is_log_enabled(cat,VCOS_LOG_TRACE)) vcos_log_dump_mem_impl(cat,label,addr,voidMem,numBytes); } while (0) + +void vcos_log_dump_mem_impl( const VCOS_LOG_CAT_T *cat, + const char *label, + uint32_t addr, + const void *voidMem, + size_t numBytes ); + +/* + * Platform specific hooks (optional). + */ +#ifndef vcos_log_platform_init +#define vcos_log_platform_init() (void)0 +#endif + +#ifndef vcos_log_platform_register +#define vcos_log_platform_register(category) (void)0 +#endif + +#ifndef vcos_log_platform_unregister +#define vcos_log_platform_unregister(category) (void)0 +#endif + +/* VCOS_TRACE() - deprecated macro which just outputs in a debug build and + * is a no-op in a release build. + * + * _VCOS_LOG_X() - internal macro which outputs if the current level for the + * particular category is higher than the supplied message level. + */ + +#define VCOS_LOG_DFLT_CATEGORY vcos_log_get_default_category() + +#define _VCOS_LEVEL(x) (x) + +#define vcos_is_log_enabled(cat,_level) (_VCOS_LEVEL((cat)->level) >= _VCOS_LEVEL(_level)) + +#if defined(_VCOS_METAWARE) || defined(__GNUC__) + +# if !defined(AMPUTATE_ALL_VCOS_LOGGING) && (!defined(NDEBUG) || defined(VCOS_ALWAYS_WANT_LOGGING)) +# define VCOS_LOGGING_ENABLED +# define _VCOS_LOG_X(cat, _level, fmt...) do { if (vcos_is_log_enabled(cat,_level)) vcos_log_impl(cat,_level,fmt); } while (0) +# define _VCOS_VLOG_X(cat, _level, fmt, ap) do { if (vcos_is_log_enabled(cat,_level)) vcos_vlog_impl(cat,_level,fmt,ap); } while (0) +# else +# define _VCOS_LOG_X(cat, _level, fmt...) (void)0 +# define _VCOS_VLOG_X(cat, _level, fmt, ap) (void)0 +# endif + + + +# define vcos_log_error(...) _VCOS_LOG_X(VCOS_LOG_CATEGORY, VCOS_LOG_ERROR, __VA_ARGS__) +# define vcos_log_warn(...) _VCOS_LOG_X(VCOS_LOG_CATEGORY, VCOS_LOG_WARN, __VA_ARGS__) +# define vcos_log_info(...) _VCOS_LOG_X(VCOS_LOG_CATEGORY, VCOS_LOG_INFO, __VA_ARGS__) +# define vcos_log_trace(...) _VCOS_LOG_X(VCOS_LOG_CATEGORY, VCOS_LOG_TRACE, __VA_ARGS__) + +# define vcos_vlog_error(fmt,ap) _VCOS_VLOG_X(VCOS_LOG_CATEGORY, VCOS_LOG_ERROR, fmt, ap) +# define vcos_vlog_warn(fmt,ap) _VCOS_VLOG_X(VCOS_LOG_CATEGORY, VCOS_LOG_WARN, fmt, ap) +# define vcos_vlog_info(fmt,ap) _VCOS_VLOG_X(VCOS_LOG_CATEGORY, VCOS_LOG_INFO, fmt, ap) +# define vcos_vlog_trace(fmt,ap) _VCOS_VLOG_X(VCOS_LOG_CATEGORY, VCOS_LOG_TRACE, fmt, ap) + +# define vcos_logc_error(cat,...) _VCOS_LOG_X(cat, VCOS_LOG_ERROR, __VA_ARGS__) +# define vcos_logc_warn(cat,...) _VCOS_LOG_X(cat, VCOS_LOG_WARN, __VA_ARGS__) +# define vcos_logc_info(cat,...) _VCOS_LOG_X(cat, VCOS_LOG_INFO, __VA_ARGS__) +# define vcos_logc_trace(cat,...) _VCOS_LOG_X(cat, VCOS_LOG_TRACE, __VA_ARGS__) + +# define vcos_vlogc_error(cat,fmt,ap) _VCOS_VLOG_X(cat, VCOS_LOG_ERROR, fmt, ap) +# define vcos_vlogc_warn(cat,fmt,ap) _VCOS_VLOG_X(cat, VCOS_LOG_WARN, fmt, ap) +# define vcos_vlogc_info(cat,fmt,ap) _VCOS_VLOG_X(cat, VCOS_LOG_INFO, fmt, ap) +# define vcos_vlogc_trace(cat,fmt,ap) _VCOS_VLOG_X(cat, VCOS_LOG_TRACE, fmt, ap) + +# define vcos_log(...) _VCOS_LOG_X(VCOS_LOG_DFLT_CATEGORY, VCOS_LOG_INFO, __VA_ARGS__) +# define vcos_vlog(fmt,ap) _VCOS_VLOG_X(VCOS_LOG_DFLT_CATEGORY, VCOS_LOG_INFO, fmt, ap) +# define VCOS_ALERT(...) _VCOS_LOG_X(VCOS_LOG_DFLT_CATEGORY, VCOS_LOG_ERROR, __VA_ARGS__) +# define VCOS_TRACE(...) _VCOS_LOG_X(VCOS_LOG_DFLT_CATEGORY, VCOS_LOG_INFO, __VA_ARGS__) + +/* + * MS Visual Studio - pre 2005 does not grok variadic macros + */ +#elif defined(_MSC_VER) + +# if _MSC_VER >= 1400 + +# if !defined(AMPUTATE_ALL_VCOS_LOGGING) && (!defined(NDEBUG) || defined(VCOS_ALWAYS_WANT_LOGGING)) +# define VCOS_LOGGING_ENABLED +# define _VCOS_LOG_X(cat, _level, fmt,...) do { if (vcos_is_log_enabled(cat,_level)) vcos_log_impl(cat, _level, fmt, __VA_ARGS__); } while (0) +# else +# define _VCOS_LOG_X(cat, _level, fmt,...) (void)0 +# endif + +# define vcos_log_error(fmt,...) _VCOS_LOG_X(VCOS_LOG_CATEGORY, VCOS_LOG_ERROR, fmt, __VA_ARGS__) +# define vcos_log_warn(fmt,...) _VCOS_LOG_X(VCOS_LOG_CATEGORY, VCOS_LOG_WARN, fmt, __VA_ARGS__) +# define vcos_log_info(fmt,...) _VCOS_LOG_X(VCOS_LOG_CATEGORY, VCOS_LOG_INFO, fmt, __VA_ARGS__) +# define vcos_log_trace(fmt,...) _VCOS_LOG_X(VCOS_LOG_CATEGORY, VCOS_LOG_TRACE, fmt, __VA_ARGS__) + +# define vcos_logc_error(cat,fmt,...) _VCOS_LOG_X(cat, VCOS_LOG_ERROR, fmt, __VA_ARGS__) +# define vcos_logc_warn(cat,fmt,...) _VCOS_LOG_X(cat, VCOS_LOG_WARN, fmt, __VA_ARGS__) +# define vcos_logc_info(cat,fmt,...) _VCOS_LOG_X(cat, VCOS_LOG_INFO, fmt, __VA_ARGS__) +# define vcos_logc_trace(cat,fmt,...) _VCOS_LOG_X(cat, VCOS_LOG_TRACE, fmt, __VA_ARGS__) + +# define vcos_log(fmt,...) _VCOS_LOG_X(VCOS_LOG_DFLT_CATEGORY, VCOS_LOG_INFO, fmt, __VA_ARGS__) +# define VCOS_ALERT(fmt,...) _VCOS_LOG_X(VCOS_LOG_DFLT_CATEGORY, VCOS_LOG_ERROR, fmt, __VA_ARGS__) +# define VCOS_TRACE(fmt,...) _VCOS_LOG_X(VCOS_LOG_DFLT_CATEGORY, VCOS_LOG_INFO, fmt, __VA_ARGS__) + +# else /* _MSC_VER >= 1400 */ + +/* do not define these */ + +# endif /* _MSC_VER >= 1400 */ + +#endif + +#if VCOS_HAVE_CMD + +#include "vcos_cmd.h" + +/* + * These are the log sub-commands. They're exported here for user-mode apps which + * may want to call these, since the "log" command isn't registered for user-mode + * apps (vcdbg for example, has its own log command). + */ +VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_log_assert_cmd( VCOS_CMD_PARAM_T *param ); +VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_log_set_cmd( VCOS_CMD_PARAM_T *param ); +VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_log_status_cmd( VCOS_CMD_PARAM_T *param ); +VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_log_test_cmd( VCOS_CMD_PARAM_T *param ); +#endif + +#ifdef __cplusplus +} +#endif +#endif /* VCOS_LOGGING_H */ + + diff --git a/external_src/raspicam-0.1.3/dependencies/vcos/vcos_logging_control.h b/external_src/raspicam-0.1.3/dependencies/vcos/vcos_logging_control.h new file mode 100644 index 0000000..b180ad8 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/vcos/vcos_logging_control.h @@ -0,0 +1,28 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. +*/ + + diff --git a/external_src/raspicam-0.1.3/dependencies/vcos/vcos_lowlevel_thread.h b/external_src/raspicam-0.1.3/dependencies/vcos/vcos_lowlevel_thread.h new file mode 100644 index 0000000..2bcfebf --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/vcos/vcos_lowlevel_thread.h @@ -0,0 +1,129 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. +*/ + +/*============================================================================= +VideoCore OS Abstraction Layer - low level thread support +=============================================================================*/ + +#ifndef VCOS_LOWLEVEL_THREAD_H +#define VCOS_LOWLEVEL_THREAD_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "vcos_types.h" +#ifndef VCOS_PLATFORM_H +#include "pthreads/vcos_platform.h" +#endif + +/** + * \file + * + * This defines a low level thread API that is supported by *some* operating systems + * and can be used to construct the regular "joinable thread" API on those operating + * systems. + * + * Most clients will not need to use this code. + * + * \sa vcos_joinable_thread.h + */ + +/** + * \brief Create a thread. + * + * This creates a thread which can be stopped either by returning from the + * entry point function or by calling vcos_llthread_exit from within the entry + * point function. The thread must be cleaned up by calling + * vcos_llthread_delete. vcos_llthread_delete may or may not terminate the + * thread. + * + * The preemptible parameter familiar from Nucleus is removed, as it is unused in + * VideoCore code. Affinity is added, since we do use this. + * + * @param thread Filled in with thread instance + * @param name An optional name for the thread. "" may be used (but + * a name will aid in debugging). + * @param entry Entry point + * @param arg A single argument passed to the entry point function + * @param stack Pointer to stack address + * @param stacksz Size of stack in bytes + * @param priority Priority of task, between VCOS_PRI_LOW and VCOS_PRI_HIGH + * @param affinity CPU affinity + * + * @sa vcos_llthread_terminate vcos_llthread_delete + */ +VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_llthread_create(VCOS_LLTHREAD_T *thread, + const char *name, + VCOS_LLTHREAD_ENTRY_FN_T entry, + void *arg, + void *stack, + VCOS_UNSIGNED stacksz, + VCOS_UNSIGNED priority, + VCOS_UNSIGNED affinity, + VCOS_UNSIGNED timeslice, + VCOS_UNSIGNED autostart); + +/** + * \brief Exits the current thread. + */ +VCOSPRE_ void VCOSPOST_ vcos_llthread_exit(void); + +/** + * \brief Delete a thread. This must be called to cleanup after + * vcos_llthread_create. This may or may not terminate the thread. + * It does not clean up any resources that may have been + * allocated by the thread. + */ +VCOSPRE_ void VCOSPOST_ vcos_llthread_delete(VCOS_LLTHREAD_T *thread); + +/** + * \brief Return current lowlevel thread pointer. + */ +VCOS_INLINE_DECL +VCOS_LLTHREAD_T *vcos_llthread_current(void); + +/** + * Resume a thread. + */ +VCOS_INLINE_DECL +void vcos_llthread_resume(VCOS_LLTHREAD_T *thread); + +VCOSPRE_ int VCOSPOST_ vcos_llthread_running(VCOS_LLTHREAD_T *thread); + +/** + * \brief Create a VCOS_LLTHREAD_T for the current thread. This is so we can + * have VCOS_LLTHREAD_Ts even for threads not originally created by VCOS (eg + * the thread that calls vcos_init). + */ +extern VCOS_STATUS_T _vcos_llthread_create_attach(VCOS_LLTHREAD_T *thread); + +#ifdef __cplusplus +} +#endif +#endif + diff --git a/external_src/raspicam-0.1.3/dependencies/vcos/vcos_mem.h b/external_src/raspicam-0.1.3/dependencies/vcos/vcos_mem.h new file mode 100644 index 0000000..687fb99 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/vcos/vcos_mem.h @@ -0,0 +1,101 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. +*/ + +/*============================================================================= +VideoCore OS Abstraction Layer - memory support +=============================================================================*/ + +#ifndef VCOS_MEM_H +#define VCOS_MEM_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "vcos_types.h" +#include "pthreads/vcos_platform.h" + +/** \file + * + * Memory allocation api (malloc/free equivalents) is for benefit of host + * applications. VideoCore code should use rtos_XXX functions. + * + */ + + +/** Allocate memory + * + * @param size Size of memory to allocate + * @param description Description, to aid in debugging. May be ignored internally on some platforms. + */ +VCOS_INLINE_DECL +void *vcos_malloc(VCOS_UNSIGNED size, const char *description); + +void *vcos_kmalloc(VCOS_UNSIGNED size, const char *description); +void *vcos_kcalloc(VCOS_UNSIGNED num, VCOS_UNSIGNED size, const char *description); + +/** Allocate cleared memory + * + * @param num Number of items to allocate. + * @param size Size of each item in bytes. + * @param description Description, to aid in debugging. May be ignored internally on some platforms. + */ +VCOS_INLINE_DECL +void *vcos_calloc(VCOS_UNSIGNED num, VCOS_UNSIGNED size, const char *description); + +/** Free memory + * + * Free memory that has been allocated. + */ +VCOS_INLINE_DECL +void vcos_free(void *ptr); + +void vcos_kfree(void *ptr); + +/** Allocate aligned memory + * + * Allocate memory aligned on the specified boundary. + * + * @param size Size of memory to allocate + * @param description Description, to aid in debugging. May be ignored internally on some platforms. + */ +VCOS_INLINE_DECL +void *vcos_malloc_aligned(VCOS_UNSIGNED size, VCOS_UNSIGNED align, const char *description); + +/** Return the amount of free heap memory + * + */ +VCOS_INLINE_DECL +unsigned long vcos_get_free_mem(void); + +#ifdef __cplusplus +} +#endif + +#endif + + diff --git a/external_src/raspicam-0.1.3/dependencies/vcos/vcos_mempool.h b/external_src/raspicam-0.1.3/dependencies/vcos/vcos_mempool.h new file mode 100644 index 0000000..8f5b84d --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/vcos/vcos_mempool.h @@ -0,0 +1,109 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. +*/ + +/*============================================================================= +VideoCore OS Abstraction Layer - memory pool support +=============================================================================*/ + +#ifndef VCOS_MEMPOOL_H +#define VCOS_MEMPOOL_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "vcos_types.h" +#include "pthreads/vcos_platform.h" + +/** \file + * + * Memory pools - variable sized allocator. + * + * A very basic memory pool API. + * + * This interface is deliberately not thread safe - clients should add + * their own locking, if required. + * + * + * \fixme: Add fixed-size allocator. + * + */ + + +/** Initialize a memory pool. The control data is taken from the memory + * supplied itself. + * + * Note: the dmalloc pool uses the memory supplied for its control + * area. This is probably a bit broken, as it stops you creating + * a pool in some "special" area of memory, while leaving the control + * information in normal memory. + * + * @param pool Pointer to pool object. + * + * @param name Name for the pool. Used for diagnostics. + * + * @param start Starting address. Must be at least 8byte aligned. + * + * @param size Size of pool in bytes. + * + * @return VCOS_SUCCESS if pool was created. + */ +VCOS_INLINE_DECL +VCOS_STATUS_T vcos_mempool_create(VCOS_MEMPOOL_T *pool, const char *name, void *start, VCOS_UNSIGNED size); + +/** Allocate some memory from a pool. If no memory is available, it + * returns NULL. + * + * @param pool Pool to allocate from + * @param len Length of memory to allocate + * + */ +VCOS_INLINE_DECL +void *vcos_mempool_alloc(VCOS_MEMPOOL_T *pool, VCOS_UNSIGNED len); + +/** Free some memory back to a pool. + * + * @param pool Pool to return to + * @param mem Memory to return + */ +VCOS_INLINE_DECL +void vcos_mempool_free(VCOS_MEMPOOL_T *pool, void *mem); + +/** Deinitialize a memory pool. + * + * @param pool Pool to return to + */ +VCOS_INLINE_DECL +void vcos_mempool_delete(VCOS_MEMPOOL_T *pool); + +#ifdef __cplusplus +} +#endif +#endif + + + diff --git a/external_src/raspicam-0.1.3/dependencies/vcos/vcos_msgqueue.h b/external_src/raspicam-0.1.3/dependencies/vcos/vcos_msgqueue.h new file mode 100644 index 0000000..6da69d7 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/vcos/vcos_msgqueue.h @@ -0,0 +1,280 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. +*/ + +/*============================================================================= +VCOS - packet-like messages, based loosely on those found in TRIPOS. + +In the simple case, only the server thread creates a message queue, and +clients wait for replies on a semaphore. In more complex cases, clients can +also create message queues (not yet implemented). + +Although it's possible for a thread to create multiple queues and listen +on them in turn, if you find yourself doing this it's probably a bug. +=============================================================================*/ + +#ifndef VCOS_MSGQUEUE_H +#define VCOS_MSGQUEUE_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "vcos_types.h" +#include "pthreads/vcos_platform.h" +#include "vcos_blockpool.h" + +/** + * \file + * + * Packet-like messages, based loosely on those found in TRIPOS and + * derivatives thereof. + * + * A task can send a message *pointer* to another task, where it is + * queued on a linked list and the task woken up. The receiving task + * consumes all of the messages on its input queue, and optionally + * sends back replies using the original message memory. + * + * A caller can wait for the reply to a specific message - any other + * messages that arrive in the meantime are queued separately. + * + * + * All messages have a standard common layout, but the payload area can + * be used freely to extend this. + */ + +#define VCOS_MSGQ_MAGIC 0x5147534d + +/** Map the payload portion of a message to a structure pointer. + */ +#define VCOS_MSG_DATA(_msg) (void*)((_msg)->data) + +/** Standard message ids - FIXME - these need to be done properly! */ +#define VCOS_MSG_N_QUIT 1 +#define VCOS_MSG_N_OPEN 2 +#define VCOS_MSG_N_CLOSE 3 +#define VCOS_MSG_N_PRIVATE (1<<20) + +#define VCOS_MSG_REPLY_BIT (1<<31) + +/** Make gnuc compiler be happy about pointer punning */ +#ifdef __GNUC__ +#define __VCOS_MAY_ALIAS __attribute__((__may_alias__)) +#else +#define __VCOS_MAY_ALIAS +#endif + +struct VCOS_MSG_T; + +/* Replies go to one of these objects. + */ +typedef struct VCOS_MSG_WAITER_T +{ + /* When the reply is sent, this function gets called with the + * address of the waiter. + */ + void (*on_reply)(struct VCOS_MSG_WAITER_T *waiter, + struct VCOS_MSG_T *msg); +} VCOS_MSG_WAITER_T; + +/** A single message queue. + */ +typedef struct VCOS_MSGQUEUE_T +{ + VCOS_MSG_WAITER_T waiter; /**< So we can wait on a queue */ + struct VCOS_MSG_T *head; /**< head of linked list of messages waiting on this queue */ + struct VCOS_MSG_T *tail; /**< tail of message queue */ + VCOS_SEMAPHORE_T sem; /**< thread waits on this for new messages */ + VCOS_MUTEX_T lock; /**< locks the messages list */ + int attached; /**< Is this attached to a thread? */ +} VCOS_MSGQUEUE_T; + +/** A single message + */ +typedef struct VCOS_MSG_T +{ + uint32_t magic; /**< Sanity checking */ + uint32_t code; /**< message code */ + struct VCOS_MSG_T *next; /**< next in queue */ + VCOS_THREAD_T *src_thread; /**< for debug */ + struct VCOS_MSG_WAITER_T *waiter; /**< client waiter structure */ + struct VCOS_MSGQ_POOL_T *pool; /**< Pool allocated from, or NULL */ +} VCOS_MSG_T; + +#define MSG_REPLY_BIT (1<<31) + +/** Initialize a VCOS_MSG_T. Can also use vcos_msg_init(). + */ +#define VCOS_MSG_INITIALIZER {VCOS_MSGQ_MAGIC, 0, NULL, NULL, NULL, 0} + +/** A pool of messages. This contains its own waiter and + * semaphore, as well as a blockpool for the actual memory + * management. + * + * When messages are returned to the waiter, it posts the + * semaphore. + * + * When waiting for a message, we just wait on the semaphore. + * When allocating without waiting, we just try-wait on the + * semaphore. + * + * If we managed to claim the semaphore, then by definition + * there must be at least that many free messages in the + * blockpool. + */ +typedef struct VCOS_MSGQ_POOL_T +{ + VCOS_MSG_WAITER_T waiter; + VCOS_BLOCKPOOL_T blockpool; + VCOS_SEMAPHORE_T sem; + uint32_t magic; +} VCOS_MSGQ_POOL_T; + +/** Initalise the library. Normally called from vcos_init(). + */ +VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_msgq_init(void); + +/** De-initialise the library. Normally called from vcos_deinit(). + */ +VCOSPRE_ void VCOSPOST_ vcos_msgq_deinit(void); + +/** Send a message. + * + * @param dest Destination message queue + * @param code Message code. + * @param msg Pointer to message to send. Must not go out of scope before + * message is received (do not declare on the stack). + */ +VCOSPRE_ void VCOSPOST_ vcos_msg_send(VCOS_MSGQUEUE_T *dest, uint32_t code, VCOS_MSG_T *msg); + +/** Send a message and wait for a reply. + * + * @param dest Destination message queue + * @param code Message code. + * @param msg Pointer to message to send. May be declared on the stack. + */ +VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_msg_sendwait(VCOS_MSGQUEUE_T *queue, uint32_t code, VCOS_MSG_T *msg); + +/** Wait for a message on a queue. + */ +VCOSPRE_ VCOS_MSG_T * VCOSPOST_ vcos_msg_wait(VCOS_MSGQUEUE_T *queue); + +/** Peek for a message on this thread's endpoint. If a message is not + * available, NULL is returned. If a message is available it will be + * removed from the endpoint and returned. + */ +VCOSPRE_ VCOS_MSG_T * VCOSPOST_ vcos_msg_peek(VCOS_MSGQUEUE_T *queue); + +/** Send a reply to a message + */ +VCOSPRE_ void VCOSPOST_ vcos_msg_reply(VCOS_MSG_T *msg); + +/** Set the reply queue for a message. When the message is replied-to, it + * will return to the given queue. + * + * @param msg Message + * @param queue Message queue the message should return to + */ +VCOSPRE_ void VCOSPOST_ vcos_msg_set_source(VCOS_MSG_T *msg, VCOS_MSGQUEUE_T *queue); + +/** Initialise a newly allocated message. This only needs to be called + * for messages allocated on the stack, heap or statically. It is not + * needed for messages allocated from a pool. + */ +VCOSPRE_ void VCOSPOST_ vcos_msg_init(VCOS_MSG_T *msg); + +/** Create a message queue to wait on. + */ +VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_msgq_create(VCOS_MSGQUEUE_T *queue, const char *name); + +/** Destroy a queue + */ +VCOSPRE_ void VCOSPOST_ vcos_msgq_delete(VCOS_MSGQUEUE_T *queue); + +/* + * Message pools + */ + +/** Create a pool of messages. Messages can be allocated from the pool and + * sent to a message queue. Replying to the message will automatically + * free it back to the pool. + * + * The pool is threadsafe. + * + * @param count number of messages in the pool + * @param payload_size maximum message payload size, not including MSG_T. + */ +VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_msgq_pool_create( + VCOS_MSGQ_POOL_T *pool, + size_t count, + size_t payload_size, + const char *name); + +/** Destroy a message pool. + */ +VCOSPRE_ void VCOSPOST_ vcos_msgq_pool_delete(VCOS_MSGQ_POOL_T *pool); + +/** Allocate a message from a message pool. + * + * Note: + * + * If the alloc fails (returns NULL) then your worker thread has stopped + * servicing requests or your pool is too small for the latency in + * the system. Your best bet to handle this is to fail the call that + * needs to send the message. + * + * The returned message payload area is initialised to zero. + * + * @param pool Pool to allocate from. + * @return Message or NULL if pool exhausted. + */ +VCOSPRE_ VCOS_MSG_T *VCOSPOST_ vcos_msgq_pool_alloc(VCOS_MSGQ_POOL_T *pool); + +/** Wait for a message from a message pool. Waits until a + * message is available in the pool and then allocates it. If + * one is already available, returns immediately. + * + * This call can never fail. + * + * The returned message payload area is initialised to zero. + * + * @param pool Pool to allocate from. + * @return Message + */ +VCOSPRE_ VCOS_MSG_T *VCOSPOST_ vcos_msgq_pool_wait(VCOS_MSGQ_POOL_T *pool); + +/** Explicitly free a message and return it to its pool. + * + * @param msg Message to free. No-op if NULL. + */ +VCOSPRE_ void VCOSPOST_ vcos_msgq_pool_free(VCOS_MSG_T *msg); + +#ifdef __cplusplus +} +#endif +#endif + + diff --git a/external_src/raspicam-0.1.3/dependencies/vcos/vcos_mutex.h b/external_src/raspicam-0.1.3/dependencies/vcos/vcos_mutex.h new file mode 100644 index 0000000..4a03853 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/vcos/vcos_mutex.h @@ -0,0 +1,112 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. +*/ + +/*============================================================================= +VideoCore OS Abstraction Layer - mutex public header file +=============================================================================*/ + +#ifndef VCOS_MUTEX_H +#define VCOS_MUTEX_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "vcos_types.h" +#include "pthreads/vcos_platform.h" + +/** + * \file vcos_mutex.h + * + * Mutex API. Mutexes are not re-entrant, as supporting this adds extra code + * that slows down clients which have been written sensibly. + * + * \sa vcos_reentrant_mutex.h + * + */ + +/** Create a mutex. + * + * @param m Filled in with mutex on return + * @param name A non-null name for the mutex, used for diagnostics. + * + * @return VCOS_SUCCESS if mutex was created, or error code. + */ +VCOS_INLINE_DECL +VCOS_STATUS_T vcos_mutex_create(VCOS_MUTEX_T *m, const char *name); + +/** Delete the mutex. + */ +VCOS_INLINE_DECL +void vcos_mutex_delete(VCOS_MUTEX_T *m); + +/** + * \brief Wait to claim the mutex. + * + * On most platforms this always returns VCOS_SUCCESS, and so would ideally be + * a void function, however some platforms allow a wait to be interrupted so + * it remains non-void. + * + * Try to obtain the mutex. + * @param m Mutex to wait on + * @return VCOS_SUCCESS - mutex was taken. + * VCOS_EAGAIN - could not take mutex. + */ +#ifndef vcos_mutex_lock +VCOS_INLINE_DECL +VCOS_STATUS_T vcos_mutex_lock(VCOS_MUTEX_T *m); + +/** Release the mutex. + */ +VCOS_INLINE_DECL +void vcos_mutex_unlock(VCOS_MUTEX_T *m); +#endif + +/** Test if the mutex is already locked. + * + * @return 1 if mutex is locked, 0 if it is unlocked. + */ +VCOS_INLINE_DECL +int vcos_mutex_is_locked(VCOS_MUTEX_T *m); + +/** Obtain the mutex if possible. + * + * @param m the mutex to try to obtain + * + * @return VCOS_SUCCESS if mutex is succesfully obtained, or VCOS_EAGAIN + * if it is already in use by another thread. + */ +#ifndef vcos_mutex_trylock +VCOS_INLINE_DECL +VCOS_STATUS_T vcos_mutex_trylock(VCOS_MUTEX_T *m); +#endif + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/external_src/raspicam-0.1.3/dependencies/vcos/vcos_named_semaphore.h b/external_src/raspicam-0.1.3/dependencies/vcos/vcos_named_semaphore.h new file mode 100644 index 0000000..00022eb --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/vcos/vcos_named_semaphore.h @@ -0,0 +1,113 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. +*/ + +/*============================================================================= +VideoCore OS Abstraction Layer - named semaphores +=============================================================================*/ + +#ifndef VCOS_NAMED_SEMAPHORE_H +#define VCOS_NAMED_SEMAPHORE_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "vcos_types.h" +#include "pthreads/vcos_platform.h" + +/** + * \file + * + * Create a named semaphore, or open an existing one by name. + * + */ + +/** + * \brief Create a named semaphore. + * + * Semaphores are not re-entrant. + * + * @param sem Pointer to memory to be initialized + * @param name A name for this semaphore. + * @param count The initial count for the semaphore. + * + * @return VCOS_SUCCESS if the semaphore was created. + * + */ +VCOS_INLINE_DECL +VCOS_STATUS_T vcos_named_semaphore_create(VCOS_NAMED_SEMAPHORE_T *sem, const char *name, VCOS_UNSIGNED count); + +/** + * \brief Wait on a named semaphore. + * + * There is no timeout option on a semaphore, as adding this will slow down + * implementations on some platforms. If you need that kind of behaviour, use + * an event group. + * + * This always returns VCOS_SUCCESS and so should really be a void function. However + * too many lines of code would need to be changed in non-trivial ways, so for now + * it is non-void. + * + * @param sem Semaphore to wait on + * @return VCOS_SUCCESS - semaphore was taken. + * + */ +VCOS_INLINE_DECL +void vcos_named_semaphore_wait(VCOS_NAMED_SEMAPHORE_T *sem); + +/** + * \brief Try to wait for a semaphore. + * + * Try to obtain the semaphore. If it is already taken, return VCOS_TIMEOUT. + * @param sem Semaphore to wait on + * @return VCOS_SUCCESS - semaphore was taken. + * VCOS_EAGAIN - could not take semaphore + */ +VCOS_INLINE_DECL +VCOS_STATUS_T vcos_named_semaphore_trywait(VCOS_NAMED_SEMAPHORE_T *sem); + +/** + * \brief Post a semaphore. + * + * @param sem Semaphore to wait on + */ +VCOS_INLINE_DECL +void vcos_named_semaphore_post(VCOS_NAMED_SEMAPHORE_T *sem); + +/** + * \brief Delete a semaphore, releasing any resources consumed by it. + * + * @param sem Semaphore to wait on + */ +void vcos_named_semaphore_delete(VCOS_NAMED_SEMAPHORE_T *sem); + + +#ifdef __cplusplus +} +#endif +#endif + diff --git a/external_src/raspicam-0.1.3/dependencies/vcos/vcos_once.h b/external_src/raspicam-0.1.3/dependencies/vcos/vcos_once.h new file mode 100644 index 0000000..4cca139 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/vcos/vcos_once.h @@ -0,0 +1,62 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. +*/ + +/*============================================================================= +VideoCore OS Abstraction Layer - 'once' +=============================================================================*/ + +#ifndef VCOS_ONCE_H +#define VCOS_ONCE_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "vcos_types.h" +#include "pthreads/vcos_platform.h" + +/** + * \file vcos_once.h + * + * Ensure something is called only once. + * + * Initialize once_control to VCOS_ONCE_INIT. The first + * time this is called, the init_routine will be called. Thereafter + * it won't. + * + * \sa pthread_once() + * + */ + +VCOS_STATUS_T vcos_once(VCOS_ONCE_T *once_control, + void (*init_routine)(void)); + +#ifdef __cplusplus +} +#endif +#endif + diff --git a/external_src/raspicam-0.1.3/dependencies/vcos/vcos_queue.h b/external_src/raspicam-0.1.3/dependencies/vcos/vcos_queue.h new file mode 100644 index 0000000..1f28e1d --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/vcos/vcos_queue.h @@ -0,0 +1,105 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. +*/ + +/*============================================================================= +VideoCore OS Abstraction Layer - Queue public header file +=============================================================================*/ + +#ifndef VCOS_QUEUE_H +#define VCOS_QUEUE_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "vcos_types.h" +#include "pthreads/vcos_platform.h" + +/** \file vcos_queue.h + * + * API for accessing a fixed length queue. + * + * Nucleus offers variable length items, but this feature is not used + * in the current code base, so is withdrawn to simplify the API. + */ + +/** Create a fixed length queue. + * + * @param queue Pointer to queue control block + * @param name Name of queue + * @param message_size Size of each queue message item in words (words are sizeof VCOS_UNSIGNED). + * @param queue_start Start address of queue area + * @param queue_size Size in words (words are sizeof VCOS_UNSIGNED) of queue + * + */ + +VCOS_INLINE_DECL +VCOS_STATUS_T vcos_queue_create(VCOS_QUEUE_T *queue, + const char *name, + VCOS_UNSIGNED message_size, + void *queue_start, + VCOS_UNSIGNED queue_size); + +/** Delete a queue. + * @param queue The queue to delete + */ +VCOS_INLINE_DECL +void vcos_queue_delete(VCOS_QUEUE_T *queue); + +/** Send an item to a queue. If there is no space, the call with + * either block waiting for space, or return an error, depending + * on the value of the wait parameter. + * + * @param queue The queue to send to + * @param src The data to send (length set when queue was created) + * @param wait Whether to wait for space (VCOS_SUSPEND) or fail if + * no space (VCOS_NO_SUSPEND). + * + * @return If space available, returns VCOS_SUCCESS. Otherwise returns + * VCOS_EAGAIN if no space available before timeout expires. + * + */ +VCOS_INLINE_DECL +VCOS_STATUS_T vcos_queue_send(VCOS_QUEUE_T *queue, const void *src, VCOS_UNSIGNED wait); + +/** Receive an item from a queue. + * @param queue The queue to receive from + * @param dst Where to write the data to + * @param wait Whether to wait (VCOS_SUSPEND) or fail if + * empty (VCOS_NO_SUSPEND). + * + * @return If an item is available, returns VCOS_SUCCESS. Otherwise returns + * VCOS_EAGAIN if no item available before timeout expires. + */ +VCOS_INLINE_DECL +VCOS_STATUS_T vcos_queue_receive(VCOS_QUEUE_T *queue, void *dst, VCOS_UNSIGNED wait); + +#ifdef __cplusplus +} +#endif +#endif + diff --git a/external_src/raspicam-0.1.3/dependencies/vcos/vcos_quickslow_mutex.h b/external_src/raspicam-0.1.3/dependencies/vcos/vcos_quickslow_mutex.h new file mode 100644 index 0000000..229d518 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/vcos/vcos_quickslow_mutex.h @@ -0,0 +1,101 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. +*/ + +/*============================================================================= +VideoCore OS Abstraction Layer - mutex public header file +=============================================================================*/ + +#ifndef VCOS_QUICKSLOW_MUTEX_H +#define VCOS_QUICKSLOW_MUTEX_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "vcos_types.h" +#include "pthreads/vcos_platform.h" + +/** + * \file vcos_quickslow_mutex.h + * + * "Quick/Slow" Mutex API. This is a mutex which supports an additional "quick" + * (spinlock-based) locking mechanism. While in this quick locked state, other + * operating system commands will be unavailable and the caller should complete + * whatever it has to do in a short, bounded length of time (as the spinlock + * completely locks out other system activity). + * + * \sa vcos_mutex.h + * + */ + +/** Create a mutex. + * + * @param m Filled in with mutex on return + * @param name A non-null name for the mutex, used for diagnostics. + * + * @return VCOS_SUCCESS if mutex was created, or error code. + */ +VCOS_INLINE_DECL +VCOS_STATUS_T vcos_quickslow_mutex_create(VCOS_QUICKSLOW_MUTEX_T *m, const char *name); + +/** Delete the mutex. + */ +VCOS_INLINE_DECL +void vcos_quickslow_mutex_delete(VCOS_QUICKSLOW_MUTEX_T *m); + +/** + * \brief Wait to claim the mutex ("slow" mode). + * + * Obtain the mutex. + */ +VCOS_INLINE_DECL +void vcos_quickslow_mutex_lock(VCOS_QUICKSLOW_MUTEX_T *m); + +/** Release the mutex ("slow" mode). + */ +VCOS_INLINE_DECL +void vcos_quickslow_mutex_unlock(VCOS_QUICKSLOW_MUTEX_T *m); + +/** + * \brief Wait to claim the mutex ("quick" mode). + * + * Obtain the mutex. The caller must not call any OS functions or do anything + * "slow" before the corresponding call to vcos_mutex_quickslow_unlock_quick. + */ +VCOS_INLINE_DECL +void vcos_quickslow_mutex_lock_quick(VCOS_QUICKSLOW_MUTEX_T *m); + +/** Release the mutex ("quick" mode). + */ +VCOS_INLINE_DECL +void vcos_quickslow_mutex_unlock_quick(VCOS_QUICKSLOW_MUTEX_T *m); + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/external_src/raspicam-0.1.3/dependencies/vcos/vcos_reentrant_mutex.h b/external_src/raspicam-0.1.3/dependencies/vcos/vcos_reentrant_mutex.h new file mode 100644 index 0000000..1a1ca56 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/vcos/vcos_reentrant_mutex.h @@ -0,0 +1,86 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. +*/ + +/*============================================================================= +VideoCore OS Abstraction Layer - reentrant mutex public header file +=============================================================================*/ + +#ifndef VCOS_REENTRANT_MUTEX_H +#define VCOS_REENTRANT_MUTEX_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "vcos_types.h" +#include "pthreads/vcos_platform.h" + +/** + * \file + * + * Reentrant Mutex API. You can take one of these mutexes even if you've already + * taken it. Just to make sure. + * + * A re-entrant mutex may be slower on some platforms than a regular one. + * + * \sa vcos_mutex.h + * + */ + +/** Create a mutex. + * + * @param m Filled in with mutex on return + * @param name A non-null name for the mutex, used for diagnostics. + * + * @return VCOS_SUCCESS if mutex was created, or error code. + */ +VCOS_INLINE_DECL +VCOS_STATUS_T vcos_reentrant_mutex_create(VCOS_REENTRANT_MUTEX_T *m, const char *name); + +/** Delete the mutex. + */ +VCOS_INLINE_DECL +void vcos_reentrant_mutex_delete(VCOS_REENTRANT_MUTEX_T *m); + +/** Wait to claim the mutex. Must not have already been claimed by the current thread. + */ +#ifndef vcos_reentrant_mutexlock +VCOS_INLINE_DECL +void vcos_reentrant_mutex_lock(VCOS_REENTRANT_MUTEX_T *m); + +/** Release the mutex. + */ +VCOS_INLINE_DECL +void vcos_reentrant_mutex_unlock(VCOS_REENTRANT_MUTEX_T *m); +#endif + + +#ifdef __cplusplus +} +#endif +#endif + diff --git a/external_src/raspicam-0.1.3/dependencies/vcos/vcos_semaphore.h b/external_src/raspicam-0.1.3/dependencies/vcos/vcos_semaphore.h new file mode 100644 index 0000000..c9c3199 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/vcos/vcos_semaphore.h @@ -0,0 +1,158 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. +*/ + +/*============================================================================= +VideoCore OS Abstraction Layer - public header file +=============================================================================*/ + +#ifndef VCOS_SEMAPHORE_H +#define VCOS_SEMAPHORE_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "vcos_types.h" +#ifndef VCOS_PLATFORM_H +#include "pthreads/vcos_platform.h" +#endif + +/** + * \file vcos_semaphore.h + * + * \section sem Semaphores + * + * This provides counting semaphores. Semaphores are not re-entrant. On sensible + * operating systems a semaphore can always be posted but can only be taken in + * thread (not interrupt) context. Under Nucleus, a LISR cannot post a semaphore, + * although it would not be hard to lift this restriction. + * + * \subsection timeout Timeout + * + * On both Nucleus and ThreadX a semaphore can be taken with a timeout. This is + * not supported by VCOS because it makes the non-timeout code considerably more + * complicated (and hence slower). In the unlikely event that you need a timeout + * with a semaphore, and you cannot simply redesign your code to avoid it, use + * an event flag (vcos_event_flags.h). + * + * \subsection sem_nucleus Changes from Nucleus: + * + * Semaphores are always "FIFO" - i.e. sleeping threads are woken in FIFO order. That's + * because: + * \arg there's no support for NU_PRIORITY in threadx (though it can be emulated, slowly) + * \arg we don't appear to actually consciously use it - for example, Dispmanx uses + * it, but all threads waiting are the same priority. + * + */ + +/** + * \brief Create a semaphore. + * + * Create a semaphore. + * + * @param sem Pointer to memory to be initialized + * @param name A name for this semaphore. The name may be truncated internally. + * @param count The initial count for the semaphore. + * + * @return VCOS_SUCCESS if the semaphore was created. + * + */ +VCOS_INLINE_DECL +VCOS_STATUS_T vcos_semaphore_create(VCOS_SEMAPHORE_T *sem, const char *name, VCOS_UNSIGNED count); + +/** + * \brief Wait on a semaphore. + * + * There is no timeout option on a semaphore, as adding this will slow down + * implementations on some platforms. If you need that kind of behaviour, use + * an event group. + * + * On most platforms this always returns VCOS_SUCCESS, and so would ideally be + * a void function, however some platforms allow a wait to be interrupted so + * it remains non-void. + * + * @param sem Semaphore to wait on + * @return VCOS_SUCCESS - semaphore was taken. + * VCOS_EAGAIN - could not take semaphore + * + */ +VCOS_INLINE_DECL +VCOS_STATUS_T vcos_semaphore_wait(VCOS_SEMAPHORE_T *sem); + +/** + * \brief Wait on a semaphore with a timeout. + * + * Note that this function may not be implemented on all + * platforms, and may not be efficient on all platforms + * (see comment in vcos_semaphore_wait) + * + * Try to obtain the semaphore. If it is already taken, return + * VCOS_EAGAIN. + * @param sem Semaphore to wait on + * @param timeout Number of milliseconds to wait before + * returning if the semaphore can't be acquired. + * @return VCOS_SUCCESS - semaphore was taken. + * VCOS_EAGAIN - could not take semaphore (i.e. timeout + * expired) + * VCOS_EINVAL - Some other error (most likely bad + * parameters). + */ +VCOS_INLINE_DECL +VCOS_STATUS_T vcos_semaphore_wait_timeout(VCOS_SEMAPHORE_T *sem, VCOS_UNSIGNED timeout); + +/** + * \brief Try to wait for a semaphore. + * + * Try to obtain the semaphore. If it is already taken, return VCOS_TIMEOUT. + * @param sem Semaphore to wait on + * @return VCOS_SUCCESS - semaphore was taken. + * VCOS_EAGAIN - could not take semaphore + */ +VCOS_INLINE_DECL +VCOS_STATUS_T vcos_semaphore_trywait(VCOS_SEMAPHORE_T *sem); + +/** + * \brief Post a semaphore. + * + * @param sem Semaphore to wait on + */ +VCOS_INLINE_DECL +VCOS_STATUS_T vcos_semaphore_post(VCOS_SEMAPHORE_T *sem); + +/** + * \brief Delete a semaphore, releasing any resources consumed by it. + * + * @param sem Semaphore to wait on + */ +VCOS_INLINE_DECL +void vcos_semaphore_delete(VCOS_SEMAPHORE_T *sem); + +#ifdef __cplusplus +} +#endif +#endif + diff --git a/external_src/raspicam-0.1.3/dependencies/vcos/vcos_stdbool.h b/external_src/raspicam-0.1.3/dependencies/vcos/vcos_stdbool.h new file mode 100644 index 0000000..25b0e09 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/vcos/vcos_stdbool.h @@ -0,0 +1,47 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 VCOS_STDBOOL_H +#define VCOS_STDBOOL_H + +#ifndef __cplusplus + +#if defined(__STDC__) && (__STDC_VERSION__ >= 199901L) +#include +#else +/* sizeof(bool) == 1. hopefully this matches up with c++ (so structures and + * such containing bool are binary compatible), but the c++ standard doesn't + * require sizeof(bool) == 1, so there's no guarantee */ +typedef unsigned char bool; +enum { + false, + true +}; +#endif + +#endif /* __cplusplus */ + +#endif diff --git a/external_src/raspicam-0.1.3/dependencies/vcos/vcos_stdint.h b/external_src/raspicam-0.1.3/dependencies/vcos/vcos_stdint.h new file mode 100644 index 0000000..1ea1aa3 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/vcos/vcos_stdint.h @@ -0,0 +1,107 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 VCOS_STDINT_H +#define VCOS_STDINT_H + +/** \file + * Attempt to provide the types defined in stdint.h. + * + * Except for use with lcc, this simply includes stdint.h, which should find + * the system/toolchain version if present, otherwise falling back to the + * version in . + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined (VCMODS_LCC) + +#include + +typedef signed char int8_t; +typedef unsigned char uint8_t; + +typedef signed short int16_t; +typedef unsigned short uint16_t; + +typedef signed long int32_t; +typedef unsigned long uint32_t; + +typedef int32_t intptr_t; +typedef uint32_t uintptr_t; + +typedef int32_t intmax_t; +typedef uint32_t uintmax_t; + +typedef int8_t int_least8_t; +typedef int16_t int_least16_t; +typedef int32_t int_least32_t; +typedef uint8_t uint_least8_t; +typedef uint16_t uint_least16_t; +typedef uint32_t uint_least32_t; + +#define INT8_MIN SCHAR_MIN +#define INT8_MAX SCHAR_MAX +#define UINT8_MAX UCHAR_MAX + +#define INT16_MIN SHRT_MIN +#define INT16_MAX SHRT_MAX +#define UINT16_MAX USHRT_MAX + +#define INT32_MIN LONG_MIN +#define INT32_MAX LONG_MAX +#define UINT32_MAX ULONG_MAX + +#define INTPTR_MIN INT32_MIN +#define INTPTR_MAX INT32_MAX +#define UINTPTR_MAX UINT32_MAX + +#define INTMAX_MIN INT32_MIN +#define INTMAX_MAX INT32_MAX +#define UINTMAX_MAX UINT32_MAX + +/* N.B. 64-bit integer types are not currently supported by lcc. + * However, these symbols are referenced in header files included by files + * compiled by lcc for VCE, so removing them would break the build. + * The solution here then is to define them, as the correct size, but in a + * way that should make them unusable in normal arithmetic operations. + */ +typedef struct { uint32_t a; uint32_t b; } int64_t; +typedef struct { uint32_t a; uint32_t b; } uint64_t; + +#else + +#include + +#endif + +#ifdef __cplusplus +} +#endif +#endif /* VCOS_STDINT_H */ diff --git a/external_src/raspicam-0.1.3/dependencies/vcos/vcos_string.h b/external_src/raspicam-0.1.3/dependencies/vcos/vcos_string.h new file mode 100644 index 0000000..133c0c7 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/vcos/vcos_string.h @@ -0,0 +1,129 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. +*/ + +/*============================================================================= +VideoCore OS Abstraction Layer - public header file +=============================================================================*/ + +#ifndef VCOS_STRING_H +#define VCOS_STRING_H + +/** + * \file + * + * String functions. + * + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "vcos_types.h" +#include "pthreads/vcos_platform.h" + +#ifdef __KERNEL__ +#include +#else +#include +#endif + +/** Case insensitive string comparison. + * + */ + +VCOS_INLINE_DECL +int vcos_strcasecmp(const char *s1, const char *s2); + +VCOS_INLINE_DECL +int vcos_strncasecmp(const char *s1, const char *s2, size_t n); + +VCOSPRE_ int VCOSPOST_ vcos_vsnprintf(char *buf, size_t buflen, const char *fmt, va_list ap); + +VCOSPRE_ int VCOSPOST_ vcos_snprintf(char *buf, size_t buflen, const char *fmt, ...); + +/** Like vsnprintf, except it places the output at the specified offset. + * Output is truncated to fit in buflen bytes, and is guaranteed to be NUL-terminated. + * Returns the string length before/without truncation. + */ +VCOSPRE_ size_t VCOSPOST_ vcos_safe_vsprintf(char *buf, size_t buflen, size_t offset, const char *fmt, va_list ap); + +#define VCOS_SAFE_VSPRINTF(buf, offset, fmt, ap) \ + vcos_safe_vsprintf(buf, sizeof(buf) + ((char (*)[sizeof(buf)])buf - &(buf)), offset, fmt, ap) + +/** Like snprintf, except it places the output at the specified offset. + * Output is truncated to fit in buflen bytes, and is guaranteed to be NUL-terminated. + * Returns the string length before/without truncation. + */ +VCOSPRE_ size_t VCOSPOST_ vcos_safe_sprintf(char *buf, size_t buflen, size_t offset, const char *fmt, ...); + +/* The Metaware compiler currently has a bug in its variadic macro handling which + causes it to append a spurious command to the end of its __VA_ARGS__ data. + Do not use until this has been fixed (and this comment has been deleted). */ + +#define VCOS_SAFE_SPRINTF(buf, offset, ...) \ + vcos_safe_sprintf(buf, sizeof(buf) + ((char (*)[sizeof(buf)])buf - &(buf)), offset, __VA_ARGS__) + +/** Copies string src to dst at the specified offset. + * Output is truncated to fit in dstlen bytes, i.e. the string is at most + * (buflen - 1) characters long. Unlike strncpy, exactly one NUL is written + * to dst, which is always NUL-terminated. + * Returns the string length before/without truncation. + */ +VCOSPRE_ size_t VCOSPOST_ vcos_safe_strcpy(char *dst, const char *src, size_t dstlen, size_t offset); + +#define VCOS_SAFE_STRCPY(dst, src, offset) \ + vcos_safe_strcpy(dst, src, sizeof(dst) + ((char (*)[sizeof(dst)])dst - &(dst)), offset) + +VCOS_STATIC_INLINE +int vcos_strlen(const char *s) { return (int)strlen(s); } + +VCOS_STATIC_INLINE +int vcos_strcmp(const char *s1, const char *s2) { return strcmp(s1,s2); } + +VCOS_STATIC_INLINE +int vcos_strncmp(const char *cs, const char *ct, size_t count) { return strncmp(cs, ct, count); } + +VCOS_STATIC_INLINE +char *vcos_strcpy(char *dst, const char *src) { return strcpy(dst, src); } + +VCOS_STATIC_INLINE +char *vcos_strncpy(char *dst, const char *src, size_t count) { return strncpy(dst, src, count); } + +VCOS_STATIC_INLINE +void *vcos_memcpy(void *dst, const void *src, size_t n) { memcpy(dst, src, n); return dst; } + +VCOS_STATIC_INLINE +void *vcos_memset(void *p, int c, size_t n) { return memset(p, c, n); } + +VCOS_STATIC_INLINE +int vcos_memcmp(const void *ptr1, const void *ptr2, size_t count) { return memcmp(ptr1, ptr2, count); } + +#ifdef __cplusplus +} +#endif +#endif diff --git a/external_src/raspicam-0.1.3/dependencies/vcos/vcos_thread.h b/external_src/raspicam-0.1.3/dependencies/vcos/vcos_thread.h new file mode 100644 index 0000000..0a49083 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/vcos/vcos_thread.h @@ -0,0 +1,282 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. +*/ + +/*============================================================================= +VideoCore OS Abstraction Layer - public header file +=============================================================================*/ + +#ifndef VCOS_THREAD_H +#define VCOS_THREAD_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "vcos_types.h" +#include "pthreads/vcos_platform.h" + +/** + * \file vcos_thread.h + * + * \section thread Threads + * + * Under Nucleus, a thread is created by NU_Create_Task, passing in the stack + * and various other parameters. To stop the thread, NU_Terminate_Thread() and + * NU_Delete_Thread() are called. + * + * Unfortunately it's not possible to emulate this API under some fairly common + * operating systems. Under Windows you can't pass in the stack, and you can't + * safely terminate a thread. + * + * Therefore, an API which is similar to the pthreads API is used instead. This + * API can (mostly) be emulated under all interesting operating systems. + * + * Obviously this makes the code somewhat more complicated on VideoCore than it + * would otherwise be - we end up with an extra mutex per thread, and some code + * that waits for it. The benefit is that we have a single way of creating + * threads that works consistently on all platforms (apart from stack supplying). + * + * \subsection stack Stack + * + * It's still not possible to pass in the stack address, but this can be made + * much more obvious in the API: the relevant function is missing and the + * CPP symbol VCOS_CAN_SET_STACK_ADDR is zero rather than one. + * + * \subsection thr_create Creating a thread + * + * The simplest way to create a thread is with vcos_thread_create() passing in a + * NULL thread parameter argument. To wait for the thread to exit, call + * vcos_thread_join(). + * + * \subsection back Backward compatibility + * + * To ease migration, a "classic" thread creation API is provided for code + * that used to make use of Nucleus, vcos_thread_create_classic(). The + * arguments are not exactly the same, as the PREEMPT parameter is dropped. + * + */ + +#define VCOS_AFFINITY_CPU0 _VCOS_AFFINITY_CPU0 +#define VCOS_AFFINITY_CPU1 _VCOS_AFFINITY_CPU1 +#define VCOS_AFFINITY_MASK _VCOS_AFFINITY_MASK +#define VCOS_AFFINITY_DEFAULT _VCOS_AFFINITY_DEFAULT +#define VCOS_AFFINITY_THISCPU _VCOS_AFFINITY_THISCPU + +/** Report whether or not we have an RTOS at all, and hence the ability to + * create threads. + */ +VCOSPRE_ int VCOSPOST_ vcos_have_rtos(void); + +/** Create a thread. It must be cleaned up by calling vcos_thread_join(). + * + * @param thread Filled in on return with thread + * @param name A name for the thread. May be the empty string. + * @param attrs Attributes; default attributes will be used if this is NULL. + * @param entry Entry point. + * @param arg Argument passed to the entry point. + */ +VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_thread_create(VCOS_THREAD_T *thread, + const char *name, + VCOS_THREAD_ATTR_T *attrs, + VCOS_THREAD_ENTRY_FN_T entry, + void *arg); + +/** Exit the thread from within the thread function itself. + * Resources must still be cleaned up via a call to thread_join(). + * + * The thread can also be terminated by simply exiting the thread function. + * + * @param data Data passed to thread_join. May be NULL. + */ +VCOSPRE_ void VCOSPOST_ vcos_thread_exit(void *data); + +/** Wait for a thread to terminate and then clean up its resources. + * + * @param thread Thread to wait for + * @param pData Updated to point at data provided in vcos_thread_exit or exit + * code of thread function. + */ +VCOSPRE_ void VCOSPOST_ vcos_thread_join(VCOS_THREAD_T *thread, + void **pData); + + +/** + * \brief Create a thread using an API similar to the one "traditionally" + * used under Nucleus. + * + * This creates a thread which must be cleaned up by calling vcos_thread_join(). + * The thread cannot be simply terminated (as in Nucleus and ThreadX) as thread + * termination is not universally supported. + * + * @param thread Filled in with thread instance + * @param name An optional name for the thread. NULL or "" may be used (but + * a name will aid in debugging). + * @param entry Entry point + * @param arg A single argument passed to the entry point function + * @param stack Pointer to stack address + * @param stacksz Size of stack in bytes + * @param priaff Priority of task, between VCOS_PRI_LOW and VCOS_PRI_HIGH, ORed with the CPU affinity + * @param autostart If non-zero the thread will start immediately. + * @param timeslice Timeslice (system ticks) for this thread. + * + * @sa vcos_thread_terminate vcos_thread_delete + */ +VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_thread_create_classic(VCOS_THREAD_T *thread, + const char *name, + void *(*entry)(void *arg), + void *arg, + void *stack, + VCOS_UNSIGNED stacksz, + VCOS_UNSIGNED priaff, + VCOS_UNSIGNED timeslice, + VCOS_UNSIGNED autostart); + +/** + * \brief Set a thread's priority + * + * Set the priority for a thread. + * + * @param thread The thread + * @param pri Thread priority in VCOS_PRI_MASK bits; affinity in VCOS_AFFINITY_MASK bits. + */ +VCOS_INLINE_DECL +void vcos_thread_set_priority(VCOS_THREAD_T *thread, VCOS_UNSIGNED pri); + +/** + * \brief Return the currently executing thread. + * + */ +VCOS_INLINE_DECL +VCOS_THREAD_T *vcos_thread_current(void); + +/** + * \brief Return the thread's priority. + */ +VCOS_INLINE_DECL +VCOS_UNSIGNED vcos_thread_get_priority(VCOS_THREAD_T *thread); + +/** + * \brief Return the thread's cpu affinity. + */ +VCOS_INLINE_DECL +VCOS_UNSIGNED vcos_thread_get_affinity(VCOS_THREAD_T *thread); + +/** + * \brief Set the thread's cpu affinity. + */ + +VCOS_INLINE_DECL +void vcos_thread_set_affinity(VCOS_THREAD_T *thread, VCOS_UNSIGNED affinity); + +/** + * \brief Query whether we are in an interrupt. + * + * @return 1 if in interrupt context. + */ +VCOS_INLINE_DECL +int vcos_in_interrupt(void); + +/** + * \brief Sleep a while. + * + * @param ms Number of milliseconds to sleep for + * + * This may actually sleep a whole number of ticks. + */ +VCOS_INLINE_DECL +void vcos_sleep(uint32_t ms); + +/** + * \brief Return the value of the hardware microsecond counter. + * + */ +VCOS_INLINE_DECL +uint32_t vcos_getmicrosecs(void); + +VCOS_INLINE_DECL +uint64_t vcos_getmicrosecs64(void); + +#define vcos_get_ms() (vcos_getmicrosecs()/1000) + +/** + * \brief Return a unique identifier for the current process + * + */ +VCOS_INLINE_DECL +VCOS_UNSIGNED vcos_process_id_current(void); + +/** Relinquish this time slice. */ +VCOS_INLINE_DECL +void vcos_thread_relinquish(void); + +/** Return the name of the given thread. + */ +VCOSPRE_ const char * VCOSPOST_ vcos_thread_get_name(const VCOS_THREAD_T *thread); + +/** Change preemption. This is almost certainly not what you want, as it won't + * work reliably in a multicore system: although you can affect the preemption + * on *this* core, you won't affect what's happening on the other core(s). + * + * It's mainly here to ease migration. If you're using it in new code, you + * probably need to think again. + * + * @param pe New preemption, VCOS_PREEMPT or VCOS_NO_PREEMPT + * @return Old value of preemption. + */ +VCOS_INLINE_DECL +VCOS_UNSIGNED vcos_change_preemption(VCOS_UNSIGNED pe); + +/** Is a thread still running, or has it exited? + * + * Note: this exists for some fairly scary code in the video codec tests. Don't + * try to use it for anything else, as it may well not do what you expect. + * + * @param thread thread to query + * @return non-zero if thread is running, or zero if it has exited. + */ +VCOS_INLINE_DECL +int vcos_thread_running(VCOS_THREAD_T *thread); + +/** Resume a thread. + * + * @param thread thread to resume + */ +VCOS_INLINE_DECL +void vcos_thread_resume(VCOS_THREAD_T *thread); + +/* + * Internal APIs - may not always be present and should not be used in + * client code. + */ + +extern void _vcos_task_timer_set(void (*pfn)(void*), void *, VCOS_UNSIGNED ms); +extern void _vcos_task_timer_cancel(void); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/external_src/raspicam-0.1.3/dependencies/vcos/vcos_thread_attr.h b/external_src/raspicam-0.1.3/dependencies/vcos/vcos_thread_attr.h new file mode 100644 index 0000000..9eddd69 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/vcos/vcos_thread_attr.h @@ -0,0 +1,96 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. +*/ + +/*============================================================================= +VideoCore OS Abstraction Layer - thread attributes +=============================================================================*/ + +#ifndef VCOS_THREAD_ATTR_H +#define VCOS_THREAD_ATTR_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \file + * + * Attributes for thread creation. + * + */ + +/** Initialize thread attribute struct. This call does not allocate memory, + * and so cannot fail. + * + */ +VCOSPRE_ void VCOSPOST_ vcos_thread_attr_init(VCOS_THREAD_ATTR_T *attrs); + +/** Set the stack address and size. If not set, a stack will be allocated automatically. + * + * This can only be set on some platforms. It will always be possible to set the stack + * address on VideoCore, but on host platforms, support may well not be available. + */ +#if VCOS_CAN_SET_STACK_ADDR +VCOS_INLINE_DECL +void vcos_thread_attr_setstack(VCOS_THREAD_ATTR_T *attrs, void *addr, VCOS_UNSIGNED sz); +#endif + +/** Set the stack size. If not set, a default size will be used. Attempting to call this after having + * set the stack location with vcos_thread_attr_setstack() will result in undefined behaviour. + */ +VCOS_INLINE_DECL +void vcos_thread_attr_setstacksize(VCOS_THREAD_ATTR_T *attrs, VCOS_UNSIGNED sz); + +/** Set the task priority. If not set, a default value will be used. + */ +VCOS_INLINE_DECL +void vcos_thread_attr_setpriority(VCOS_THREAD_ATTR_T *attrs, VCOS_UNSIGNED pri); + +/** Set the task cpu affinity. If not set, the default will be used. + */ +VCOS_INLINE_DECL +void vcos_thread_attr_setaffinity(VCOS_THREAD_ATTR_T *attrs, VCOS_UNSIGNED aff); + +/** Set the timeslice. If not set the default will be used. + */ +VCOS_INLINE_DECL +void vcos_thread_attr_settimeslice(VCOS_THREAD_ATTR_T *attrs, VCOS_UNSIGNED ts); + +/** The thread entry function takes (argc,argv), as per Nucleus, with + * argc being 0. This may be withdrawn in a future release and should not + * be used in new code. + */ +VCOS_INLINE_DECL +void _vcos_thread_attr_setlegacyapi(VCOS_THREAD_ATTR_T *attrs, VCOS_UNSIGNED legacy); + +VCOS_INLINE_DECL +void vcos_thread_attr_setautostart(VCOS_THREAD_ATTR_T *attrs, VCOS_UNSIGNED autostart); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/external_src/raspicam-0.1.3/dependencies/vcos/vcos_timer.h b/external_src/raspicam-0.1.3/dependencies/vcos/vcos_timer.h new file mode 100644 index 0000000..0e198e1 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/vcos/vcos_timer.h @@ -0,0 +1,117 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. +*/ + +/*============================================================================= +VideoCore OS Abstraction Layer - timer support +=============================================================================*/ + +#ifndef VCOS_TIMER_H +#define VCOS_TIMER_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "vcos_types.h" +#ifndef VCOS_PLATFORM_H +#include "pthreads/vcos_platform.h" +#endif + +/** \file vcos_timer.h + * + * Timers are single shot. + * + * Timer times are in milliseconds. + * + * \note that timer callback functions are called from an arbitrary thread + * context. The expiration function should do its work as quickly as possible; + * blocking should be avoided. + * + * \note On Windows, the separate function vcos_timer_init() must be called + * as timer initialization from DllMain is not possible. + */ + +/** Perform timer subsystem initialization. This function is not needed + * on non-Windows platforms but is still present so that it can be + * called. On Windows it is needed because vcos_init() gets called + * from DLL initialization where it is not possible to create a + * time queue (deadlock occurs if you try). + * + * @return VCOS_SUCCESS on success. VCOS_EEXIST if this has already been called + * once. VCOS_ENOMEM if resource allocation failed. + */ +VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_timer_init(void); + +/** Create a timer in a disabled state. + * + * The timer is initially disabled. + * + * @param timer timer handle + * @param name name for timer + * @param expiration_routine function to call when timer expires + * @param context context passed to expiration routine + * + */ +VCOS_INLINE_DECL +VCOS_STATUS_T vcos_timer_create(VCOS_TIMER_T *timer, + const char *name, + void (*expiration_routine)(void *context), + void *context); + + + +/** Start a timer running. + * + * Timer must be stopped. + * + * @param timer timer handle + * @param delay Delay to wait for, in ms + */ +VCOS_INLINE_DECL +void vcos_timer_set(VCOS_TIMER_T *timer, VCOS_UNSIGNED delay); + +/** Stop an already running timer. + * + * @param timer timer handle + */ +VCOS_INLINE_DECL +void vcos_timer_cancel(VCOS_TIMER_T *timer); + +/** Stop a timer and restart it. + * @param timer timer handle + * @param delay delay in ms + */ +VCOS_INLINE_DECL +void vcos_timer_reset(VCOS_TIMER_T *timer, VCOS_UNSIGNED delay); + +VCOS_INLINE_DECL +void vcos_timer_delete(VCOS_TIMER_T *timer); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/external_src/raspicam-0.1.3/dependencies/vcos/vcos_tls.h b/external_src/raspicam-0.1.3/dependencies/vcos/vcos_tls.h new file mode 100644 index 0000000..ca6259e --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/vcos/vcos_tls.h @@ -0,0 +1,84 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. +*/ + +/*============================================================================= +VideoCore OS Abstraction Layer - thread local storage +=============================================================================*/ + +#ifndef VCOS_TLS_H +#define VCOS_TLS_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "vcos_types.h" +#include "pthreads/vcos_platform.h" + + +/** Create a new thread local storage data key visible to all threads in + * the current process. + * + * @param key The key to create + */ +VCOS_INLINE_DECL +VCOS_STATUS_T vcos_tls_create(VCOS_TLS_KEY_T *key); + +/** Delete an existing TLS data key. + */ +VCOS_INLINE_DECL +void vcos_tls_delete(VCOS_TLS_KEY_T tls); + +/** Set the value seen by the current thread. + * + * @param key The key to update + * @param v The value to set for the current thread. + * + * @return VCOS_SUCCESS, or VCOS_ENOMEM if memory for this slot + * could not be allocated. + * + * If TLS is being emulated via VCOS then the memory required + * can be preallocated at thread creation time + */ +VCOS_INLINE_DECL +VCOS_STATUS_T vcos_tls_set(VCOS_TLS_KEY_T tls, void *v); + +/** Get the value for the current thread. + * + * @param key The key to update + * + * @return The current value for this thread. + */ +VCOS_INLINE_DECL +void *vcos_tls_get(VCOS_TLS_KEY_T tls); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/external_src/raspicam-0.1.3/dependencies/vcos/vcos_types.h b/external_src/raspicam-0.1.3/dependencies/vcos/vcos_types.h new file mode 100644 index 0000000..4e0ad19 --- /dev/null +++ b/external_src/raspicam-0.1.3/dependencies/vcos/vcos_types.h @@ -0,0 +1,283 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. +*/ + +/*============================================================================= +VideoCore OS Abstraction Layer - basic types +=============================================================================*/ + +#ifndef VCOS_TYPES_H +#define VCOS_TYPES_H + +#define VCOS_VERSION 1 + +#include +#include "pthreads/vcos_platform_types.h" +#include "vcos_attr.h" + +#if !defined(VCOSPRE_) || !defined(VCOSPOST_) +#error VCOSPRE_ and VCOSPOST_ not defined! +#endif + +/* Redefine these here; this means that existing header files can carry on + * using the VCHPOST/VCHPRE macros rather than having huge changes, which + * could cause nasty merge problems. + */ +#ifndef VCHPOST_ +#define VCHPOST_ VCOSPOST_ +#endif +#ifndef VCHPRE_ +#define VCHPRE_ VCOSPRE_ +#endif + +/** Entry function for a lowlevel thread. + * + * Returns void for consistency with Nucleus/ThreadX. + */ +typedef void (*VCOS_LLTHREAD_ENTRY_FN_T)(void *); + +/** Thread entry point. Returns a void* for consistency + * with pthreads. + */ +typedef void *(*VCOS_THREAD_ENTRY_FN_T)(void*); + + +/* Error return codes - chosen to be similar to errno values */ +typedef enum +{ + VCOS_SUCCESS, + VCOS_EAGAIN, + VCOS_ENOENT, + VCOS_ENOSPC, + VCOS_EINVAL, + VCOS_EACCESS, + VCOS_ENOMEM, + VCOS_ENOSYS, + VCOS_EEXIST, + VCOS_ENXIO, + VCOS_EINTR +} VCOS_STATUS_T; + +/* Some compilers (MetaWare) won't inline with -g turned on, which then results + * in a lot of code bloat. To overcome this, inline functions are forward declared + * with the prefix VCOS_INLINE_DECL, and implemented with the prefix VCOS_INLINE_IMPL. + * + * That then means that in a release build, "static inline" can be used in the obvious + * way, but in a debug build the implementations can be skipped in all but one file, + * by using VCOS_INLINE_BODIES. + * + * VCOS_INLINE_DECL - put this at the start of an inline forward declaration of a VCOS + * function. + * + * VCOS_INLINE_IMPL - put this at the start of an inlined implementation of a VCOS + * function. + * + */ + +/* VCOS_EXPORT - it turns out that in some circumstances we need the implementation of + * a function even if it is usually inlined. + * + * In particular, if we have a codec that is usually provided in object form, if it + * was built for a debug build it will be full of calls to vcos_XXX(). If this is used + * in a *release* build, then there won't be any of these calls around in the main image + * as they will all have been inlined. The problem also exists for vcos functions called + * from assembler. + * + * VCOS_EXPORT ensures that the named function will be emitted as a regular (not static-inline) + * function inside vcos_.c so that it can be linked against. Doing this for every + * VCOS function would be a bit code-bloat-tastic, so it is only done for those that need it. + * + */ + +#ifdef __cplusplus +#define _VCOS_INLINE inline +#else +#define _VCOS_INLINE __inline +#endif + +#if defined(NDEBUG) + +#ifdef __GNUC__ +# define VCOS_INLINE_DECL extern __inline__ +# define VCOS_INLINE_IMPL static __inline__ +#else +# define VCOS_INLINE_DECL static _VCOS_INLINE /* declare a func */ +# define VCOS_INLINE_IMPL static _VCOS_INLINE /* implement a func inline */ +#endif + +# if defined(VCOS_WANT_IMPL) +# define VCOS_EXPORT +# else +# define VCOS_EXPORT VCOS_INLINE_IMPL +# endif /* VCOS_WANT_IMPL */ + +#define VCOS_INLINE_BODIES + +#else /* NDEBUG */ + +#if !defined(VCOS_INLINE_DECL) + #define VCOS_INLINE_DECL extern +#endif +#if !defined(VCOS_INLINE_IMPL) + #define VCOS_INLINE_IMPL +#endif +#define VCOS_EXPORT VCOS_INLINE_IMPL +#endif + +#define VCOS_STATIC_INLINE static _VCOS_INLINE + +#if defined(__HIGHC__) || defined(__HIGHC_ANSI__) +#define _VCOS_METAWARE +#endif + +/** It seems that __FUNCTION__ isn't standard! + */ +#if __STDC_VERSION__ < 199901L +# if __GNUC__ >= 2 || defined(__VIDEOCORE__) +# define VCOS_FUNCTION __FUNCTION__ +# else +# define VCOS_FUNCTION "" +# endif +#else +# define VCOS_FUNCTION __func__ +#endif + +#define _VCOS_MS_PER_TICK (1000/VCOS_TICKS_PER_SECOND) + +/* Convert a number of milliseconds to a tick count. Internal use only - fails to + * convert VCOS_SUSPEND correctly. + */ +#define _VCOS_MS_TO_TICKS(ms) (((ms)+_VCOS_MS_PER_TICK-1)/_VCOS_MS_PER_TICK) + +#define VCOS_TICKS_TO_MS(ticks) ((ticks) * _VCOS_MS_PER_TICK) + +/** VCOS version of DATESTR, from pcdisk.h. Used by the hostreq service. + */ +typedef struct vcos_datestr +{ + uint8_t cmsec; /**< Centesimal mili second */ + uint16_t date; /**< Date */ + uint16_t time; /**< Time */ + +} VCOS_DATESTR; + +/* Compile-time assert - declares invalid array length if condition + * not met, or array of length one if OK. + */ +#define VCOS_CASSERT(e) extern char vcos_compile_time_check[1/(e)] + +#define vcos_min(x,y) ((x) < (y) ? (x) : (y)) +#define vcos_max(x,y) ((x) > (y) ? (x) : (y)) + +/** Return the count of an array. FIXME: under gcc we could make + * this report an error for pointers using __builtin_types_compatible(). + */ +#define vcos_countof(x) (sizeof((x)) / sizeof((x)[0])) + +/* for backward compatibility */ +#define countof(x) (sizeof((x)) / sizeof((x)[0])) + +#define VCOS_ALIGN_DOWN(p,n) (((ptrdiff_t)(p)) & ~((n)-1)) +#define VCOS_ALIGN_UP(p,n) VCOS_ALIGN_DOWN((ptrdiff_t)(p)+(n)-1,(n)) + +#ifdef _MSC_VER + #define vcos_alignof(T) __alignof(T) +#elif defined(__GNUC__) + #define vcos_alignof(T) __alignof__(T) +#else + #define vcos_alignof(T) (sizeof(struct { T t; char ch; }) - sizeof(T)) +#endif + +/** bool_t is not a POSIX type so cannot rely on it. Define it here. + * It's not even defined in stdbool.h. + */ +typedef int32_t vcos_bool_t; +typedef int32_t vcos_fourcc_t; + +#define VCOS_FALSE 0 +#define VCOS_TRUE (!VCOS_FALSE) + +/** Mark unused arguments to keep compilers quiet */ +#define vcos_unused(x) (void)(x) + +/** For backward compatibility */ +typedef vcos_fourcc_t fourcc_t; +typedef vcos_fourcc_t FOURCC_T; + +#ifdef __cplusplus +#define VCOS_EXTERN_C_BEGIN extern "C" { +#define VCOS_EXTERN_C_END } +#else +#define VCOS_EXTERN_C_BEGIN +#define VCOS_EXTERN_C_END +#endif + +/** Variable attribute indicating the variable must be emitted even if it appears unused. */ +#if defined(__GNUC__) || defined(_VCOS_METAWARE) +# define VCOS_ATTR_USED __attribute__ ((used)) +#else +# define VCOS_ATTR_USED +#endif + +/** Variable attribute requiring specific alignment. */ +#if defined(__GNUC__) || defined(_VCOS_METAWARE) +# define VCOS_ATTR_ALIGNED(n) __attribute__ ((aligned(n))) +#else +# define VCOS_ATTR_ALIGNED(n) +#endif + +/** Define a function as a weak alias to another function. + * @param ret_type Function return type. + * @param alias_name Name of the alias. + * @param param_list Function parameter list, including the parentheses. + * @param target_name Target function (bare function name, not a string). + */ +#if defined(__GNUC__) || defined(_VCOS_METAWARE) + /* N.B. gcc allows __attribute__ after parameter list, but hcvc seems to silently ignore it. */ +# define VCOS_WEAK_ALIAS(ret_type, alias_name, param_list, target_name) \ + __attribute__ ((weak, alias(#target_name))) ret_type alias_name param_list +#else +# define VCOS_WEAK_ALIAS(ret_type, alias, params, target) VCOS_CASSERT(0) +#endif + +/** Define a function as a weak alias to another function, specified as a string. + * @param ret_type Function return type. + * @param alias_name Name of the alias. + * @param param_list Function parameter list, including the parentheses. + * @param target_name Target function name as a string. + * @note Prefer the use of VCOS_WEAK_ALIAS - it is likely to be more portable. + * Only use VCOS_WEAK_ALIAS_STR if you need to do pre-processor mangling of the target + * symbol. + */ +#if defined(__GNUC__) || defined(_VCOS_METAWARE) + /* N.B. gcc allows __attribute__ after parameter list, but hcvc seems to silently ignore it. */ +# define VCOS_WEAK_ALIAS_STR(ret_type, alias_name, param_list, target_name) \ + __attribute__ ((weak, alias(target_name))) ret_type alias_name param_list +#else +# define VCOS_WEAK_ALIAS_STR(ret_type, alias, params, target) VCOS_CASSERT(0) +#endif + +#endif diff --git a/external_src/raspicam-0.1.3/src/CMakeLists.txt b/external_src/raspicam-0.1.3/src/CMakeLists.txt new file mode 100644 index 0000000..09640b2 --- /dev/null +++ b/external_src/raspicam-0.1.3/src/CMakeLists.txt @@ -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} ) +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) + diff --git a/external_src/raspicam-0.1.3/src/private/exceptions.h b/external_src/raspicam-0.1.3/src/private/exceptions.h new file mode 100644 index 0000000..91a34a3 --- /dev/null +++ b/external_src/raspicam-0.1.3/src/private/exceptions.h @@ -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 +#include +#include +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 diff --git a/external_src/raspicam-0.1.3/src/private/fake_mmal_dependencies.cpp b/external_src/raspicam-0.1.3/src/private/fake_mmal_dependencies.cpp new file mode 100644 index 0000000..001bd8a --- /dev/null +++ b/external_src/raspicam-0.1.3/src/private/fake_mmal_dependencies.cpp @@ -0,0 +1,395 @@ +#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" + MMAL_BUFFER_HEADER_T *mmal_queue_get(MMAL_QUEUE_T *queue){} +MMAL_STATUS_T mmal_buffer_header_mem_lock(MMAL_BUFFER_HEADER_T *header){} + +void mmal_buffer_header_mem_unlock(MMAL_BUFFER_HEADER_T *header){} + void mmal_port_pool_destroy(MMAL_PORT_T *port, MMAL_POOL_T *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){} + +/** 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){} + +/** 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){} + +/** 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){} + +/** 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){} + +/** 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){} + + + + +/** 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){} + + +/** 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: + *
    + *
  • The port shall be populated with a pool of buffers, allocated as required, according + * to the buffer_num and buffer_size values. + *
  • 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. + *
+ * + * @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){} + +/** 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){} + +/** 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){} + +/** 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){} + +/** 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){} + +/** 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){} + +/** 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){} + +/** 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){} + +/** 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){} + +/** 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){} + +/** 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){} +/** 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){} + + + +/** 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){} + +/** 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){} + +/** 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){} + +/** 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){} + +/** 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){} + +/** 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){} + +/** 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){} + + +/** 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){} + +/** 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){} + + +/** 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){} + + +/** 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){} + + + +/** 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){} + +/** 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){} +/** 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){} diff --git a/external_src/raspicam-0.1.3/src/private/private_impl.cpp b/external_src/raspicam-0.1.3/src/private/private_impl.cpp new file mode 100644 index 0000000..2f549e5 --- /dev/null +++ b/external_src/raspicam-0.1.3/src/private/private_impl.cpp @@ -0,0 +1,812 @@ +/********************************************************** + 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 +#include +#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 = 30; + 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; + + } + 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__<output[MMAL_CAMERA_VIDEO_PORT]; + callback_data.pstate = &State; + // assign data to use for callback + camera_video_port->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."<queue ); + int q; + for ( q=0; qqueue ); + + if ( !buffer ) + cerr<<"Unable to get a required buffer"<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"<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 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 ); + + // 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::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 lck ( pData->_mutex ); + if ( pData ) { + if ( pData->wantToGrab && buffer->length ) { + mmal_buffer_header_mem_lock ( buffer ); + pData->_buffData.resize ( buffer->length ); + memcpy ( pData->_buffData.data,buffer->data,buffer->length ); + 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 ) + mmal_port_parameter_set_uint32 ( pData->pstate->camera_component->control, MMAL_PARAMETER_SHUTTER_SPEED, pData->pstate->shutterSpeed ) ; + if ( hasGrabbed ) 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"< 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(); + } + + + 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 MMAL_ENCODING_BGR24; + case RASPICAM_FORMAT_BGR: + return 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"<control, ¶m.hdr) != MMAL_SUCCESS ) + cout << __func__ << ": Failed to set AWBG gains parameter.\n"; + } + }; +}; + diff --git a/external_src/raspicam-0.1.3/src/private/private_impl.h b/external_src/raspicam-0.1.3/src/private/private_impl.h new file mode 100644 index 0000000..8414e85 --- /dev/null +++ b/external_src/raspicam-0.1.3/src/private/private_impl.h @@ -0,0 +1,280 @@ +/********************************************************** + 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 +#include +#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 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 + std::mutex _mutex; + ThreadCondition Thcond; + bool wantToGrab; + membuf _buffData; + }; + + 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;} + /**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 ); + void setWidth ( unsigned int width ) ; + void setHeight ( unsigned int height ); + 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 + + RASPICAM_FORMAT getFormat() const {return State.captureFtm;} + //Accessors + 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; + } + 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;} + + 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 ); + 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; + + + }; + }; +}; + +#endif + + diff --git a/external_src/raspicam-0.1.3/src/private/private_types.h b/external_src/raspicam-0.1.3/src/private/private_types.h new file mode 100644 index 0000000..07d1a98 --- /dev/null +++ b/external_src/raspicam-0.1.3/src/private/private_types.h @@ -0,0 +1,116 @@ +/********************************************************** + 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 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 + 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 + diff --git a/external_src/raspicam-0.1.3/src/private/threadcondition.cpp b/external_src/raspicam-0.1.3/src/private/threadcondition.cpp new file mode 100644 index 0000000..20e0a63 --- /dev/null +++ b/external_src/raspicam-0.1.3/src/private/threadcondition.cpp @@ -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& 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 ----- */ + +} diff --git a/external_src/raspicam-0.1.3/src/private/threadcondition.h b/external_src/raspicam-0.1.3/src/private/threadcondition.h new file mode 100644 index 0000000..47a1a55 --- /dev/null +++ b/external_src/raspicam-0.1.3/src/private/threadcondition.h @@ -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 +#include // std::thread +#include // std::mutex, std::unique_lock +#include // 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& 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 diff --git a/external_src/raspicam-0.1.3/src/private_still/private_still_impl.cpp b/external_src/raspicam-0.1.3/src/private_still/private_still_impl.cpp new file mode 100644 index 0000000..b27cfed --- /dev/null +++ b/external_src/raspicam-0.1.3/src/private_still/private_still_impl.cpp @@ -0,0 +1,850 @@ +/********************************************************** + 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 +#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 +#include +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 ) { + 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 ) }}; + 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(); + } + + 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 ) { + 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 ) { + 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"< +#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 diff --git a/external_src/raspicam-0.1.3/src/raspicam.cpp b/external_src/raspicam-0.1.3/src/raspicam.cpp new file mode 100644 index 0000000..52297e9 --- /dev/null +++ b/external_src/raspicam-0.1.3/src/raspicam.cpp @@ -0,0 +1,166 @@ +/********************************************************** + 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(); + } + + 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 ); + } + + + 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 150000;}//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() ;} + 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();} + + +}; + diff --git a/external_src/raspicam-0.1.3/src/raspicam.h b/external_src/raspicam-0.1.3/src/raspicam.h new file mode 100644 index 0000000..3b601ea --- /dev/null +++ b/external_src/raspicam-0.1.3/src/raspicam.h @@ -0,0 +1,178 @@ +/********************************************************** + 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 +#include +#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(); + /**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 ); + + //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; + 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 + diff --git a/external_src/raspicam-0.1.3/src/raspicam_cv.cpp b/external_src/raspicam-0.1.3/src/raspicam_cv.cpp new file mode 100644 index 0000000..d8c0baf --- /dev/null +++ b/external_src/raspicam-0.1.3/src/raspicam_cv.cpp @@ -0,0 +1,214 @@ +/********************************************************** + 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 +#include +#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(); + } + + /** + *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 ( 0 )); + } + + /**Returns the specified VideoCapture property + */ + + double RaspiCam_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 imgFormat; + 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;//auto + else return Scaler::scale (0,330000, 0,100, _impl->getShutterSpeed() ) ; + break; + case CV_CAP_PROP_CONVERT_RGB : + return ( imgFormat==CV_8UC3 ); + case CV_CAP_PROP_WHITE_BALANCE_RED_V: + return _impl->getAWBG_red()*100; + break; + + case CV_CAP_PROP_WHITE_BALANCE_BLUE_U: + return _impl->getAWBG_blue()*100; + break; + default : + return -1; + }; + } + + /**Sets a property in the VideoCapture. + */ + + bool RaspiCam_Cv::set ( int propId, double value ) { + + switch ( propId ) { + + 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_BGR); + imgFormat=value; + } + else res=false;//error int format + return res; + }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 : + imgFormat=CV_8UC3; + break; + case CV_CAP_PROP_WHITE_BALANCE_RED_V: + if (value==0) _impl->setAWB(raspicam::RASPICAM_AWB_AUTO); + else { + int valblue=_impl->getAWBG_blue()*100; + _impl->setAWB(raspicam::RASPICAM_AWB_OFF); + _impl->setAWB_RB(value*100,valblue); + }; + break; + + case CV_CAP_PROP_WHITE_BALANCE_BLUE_U: + if (value==0) _impl->setAWB(raspicam::RASPICAM_AWB_AUTO); + else { + int valred=_impl->getAWBG_red()*100; + _impl->setAWB(raspicam::RASPICAM_AWB_OFF); + _impl->setAWB_RB(valred, value*100 ); + }; + break; + +// case CV_CAP_PROP_WHITE_BALANCE :return _cam_impl->getAWB(); + default : + return false; + }; + return true; + + } + std::string RaspiCam_Cv::getId() const{ + return _impl->getId(); + } + +} + + diff --git a/external_src/raspicam-0.1.3/src/raspicam_cv.h b/external_src/raspicam-0.1.3/src/raspicam_cv.h new file mode 100644 index 0000000..fdeeef4 --- /dev/null +++ b/external_src/raspicam-0.1.3/src/raspicam_cv.h @@ -0,0 +1,115 @@ +/********************************************************** + 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 +#include +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(); + + /** + * 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 + * + */ + + 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: + cv::Mat image; + int imgFormat;//required image format // + }; + +}; +#endif + + diff --git a/external_src/raspicam-0.1.3/src/raspicam_still.cpp b/external_src/raspicam-0.1.3/src/raspicam_still.cpp new file mode 100644 index 0000000..52c4b7a --- /dev/null +++ b/external_src/raspicam-0.1.3/src/raspicam_still.cpp @@ -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(); + } +} + + diff --git a/external_src/raspicam-0.1.3/src/raspicam_still.h b/external_src/raspicam-0.1.3/src/raspicam_still.h new file mode 100644 index 0000000..5362a32 --- /dev/null +++ b/external_src/raspicam-0.1.3/src/raspicam_still.h @@ -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 +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 + diff --git a/external_src/raspicam-0.1.3/src/raspicam_still_cv.cpp b/external_src/raspicam-0.1.3/src/raspicam_still_cv.cpp new file mode 100644 index 0000000..e3d8137 --- /dev/null +++ b/external_src/raspicam-0.1.3/src/raspicam_still_cv.cpp @@ -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 ( 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(); + } +} + + diff --git a/external_src/raspicam-0.1.3/src/raspicam_still_cv.h b/external_src/raspicam-0.1.3/src/raspicam_still_cv.h new file mode 100644 index 0000000..82fc56e --- /dev/null +++ b/external_src/raspicam-0.1.3/src/raspicam_still_cv.h @@ -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 +#include "raspicamtypes.h" +#include +#include +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 + diff --git a/external_src/raspicam-0.1.3/src/raspicamtypes.h b/external_src/raspicam-0.1.3/src/raspicamtypes.h new file mode 100644 index 0000000..3d4479e --- /dev/null +++ b/external_src/raspicam-0.1.3/src/raspicamtypes.h @@ -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 + diff --git a/external_src/raspicam-0.1.3/src/scaler.h b/external_src/raspicam-0.1.3/src/scaler.h new file mode 100644 index 0000000..4c277c6 --- /dev/null +++ b/external_src/raspicam-0.1.3/src/scaler.h @@ -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 diff --git a/external_src/raspicam-0.1.3/utils/CMakeLists.txt b/external_src/raspicam-0.1.3/utils/CMakeLists.txt new file mode 100644 index 0000000..7580c43 --- /dev/null +++ b/external_src/raspicam-0.1.3/utils/CMakeLists.txt @@ -0,0 +1,18 @@ +INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/src) +LINK_LIBRARIES(${PROJECT_NAME} ) + + +ADD_EXECUTABLE(raspicam_test raspicam_test.cpp ) +INSTALL(TARGETS raspicam_test RUNTIME DESTINATION bin) + +ADD_EXECUTABLE(raspicam_still_test raspicam_still_test.cpp ) +INSTALL(TARGETS raspicam_still_test RUNTIME DESTINATION bin) + +IF (OpenCV_FOUND) +ADD_EXECUTABLE(raspicam_cv_test raspicam_cv_test.cpp ) +target_link_libraries(raspicam_cv_test ${PROJECT_NAME}_cv) +ADD_EXECUTABLE(raspicam_cv_still_test raspicam_cv_still_test.cpp ) +target_link_libraries(raspicam_cv_still_test ${PROJECT_NAME}_cv) +INSTALL(TARGETS raspicam_cv_test raspicam_cv_still_test RUNTIME DESTINATION bin) + +ENDIF() diff --git a/external_src/raspicam-0.1.3/utils/raspicam_cv_still_test.cpp b/external_src/raspicam-0.1.3/utils/raspicam_cv_still_test.cpp new file mode 100644 index 0000000..aaa2ddb --- /dev/null +++ b/external_src/raspicam-0.1.3/utils/raspicam_cv_still_test.cpp @@ -0,0 +1,82 @@ +/********************************************************** + 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 +#include +#include +#include "raspicam_still_cv.h" +using namespace std; + +raspicam::RaspiCam_Still_Cv Camera; +//Returns the value of a param. If not present, returns the defvalue +float getParamVal ( string id,int argc,char **argv,float defvalue ) { + for ( int i=0; i +#include +#include +#include +#include +#include "raspicam_cv.h" + +using namespace std; +bool doTestSpeedOnly=false; +//parse command line +//returns the index of a command line param in argv. If not found, return -1 +int findParam ( string param,int argc,char **argv ) { + int idx=-1; + for ( int i=0; i +#include +#include +#include +#include +#include +#include "raspicam.h" +using namespace std; +bool doTestSpeedOnly=false; +size_t nFramesCaptured=100; +//parse command line +//returns the index of a command line param in argv. If not found, return -1 + +int findParam ( string param,int argc,char **argv ) { + int idx=-1; + for ( int i=0; i +#include +class Timer{ + private: + struct timeval _start, _end; + +public: + Timer(){} + void start(){ + gettimeofday(&_start, NULL); + } + void end(){ + gettimeofday(&_end, NULL); + } + double getSecs(){ + return double(((_end.tv_sec - _start.tv_sec) * 1000 + (_end.tv_usec - _start.tv_usec)/1000.0) + 0.5)/1000.; + } + +}; + +void saveImage ( string filepath,unsigned char *data,raspicam::RaspiCam &Camera ) { + std::ofstream outFile ( filepath.c_str(),std::ios::binary ); + if ( Camera.getFormat()==raspicam::RASPICAM_FORMAT_BGR || Camera.getFormat()==raspicam::RASPICAM_FORMAT_RGB ) { + outFile<<"P6\n"; + } else if ( Camera.getFormat()==raspicam::RASPICAM_FORMAT_GRAY ) { + outFile<<"P5\n"; + } else if ( Camera.getFormat()==raspicam::RASPICAM_FORMAT_YUV420 ) { //made up format + outFile<<"P7\n"; + } + outFile<0 ) { //save image if not in inifite loop + std::stringstream fn; + fn<<"image"; + if (i<10) fn<<"0"; + fn<