Projects
Multimedia
slowmoVideo
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
Expand all
Collapse all
Changes of Revision 5
View file
slowmoVideo.changes
Changed
@@ -1,4 +1,14 @@ ------------------------------------------------------------------- +Tue Oct 6 14:10:11 UTC 2020 - Luigi Baldoni <aloisio@gmx.com> + +- Update to version 0.6 (no changelog supplied) +- Use current ffmpeg and Qt5 +- Drop slowmoVideo-0.4_link_libraries.patch (no longer necessary) +- Add _service file +- Add slowmoVideo-desktop.patch +- Spec cleanup + +------------------------------------------------------------------- Thu Aug 20 00:12:38 UTC 2015 - avvissu@yandex.ru - Update to 0.4
View file
slowmoVideo.spec
Changed
@@ -1,6 +1,7 @@ # -# spec file for package etherpad-lite +# spec file for package slowmoVideo # +# Copyright (c) 2020 Packman Team <packman@links2linux.de> # Copyright (c) 2014 SUSE LINUX Products GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties @@ -12,84 +13,83 @@ # license that conforms to the Open Source Definition (Version 1.9) # published by the Open Source Initiative. -# Please submit bugfixes or comments via http://bugs.opensuse.org/ +# Please submit bugfixes or comments via https://bugs.links2linux.org/ # Name: slowmoVideo -Version: 0.4 +Version: 0.6 Release: 0 Summary: Video slow motion effect via interpolation -License: GPL-3.0+ +License: GPL-3.0-or-later Group: Productivity/Multimedia/Video/Editors and Convertors -Url: http://slowmovideo.granjow.net/ -Source: https://github.com/slowmoVideo/slowmoVideo/archive/v0.4.tar.gz#/%{name}-%{version}.tar.gz -# PATCH-FIX-UPSTREAM link_libraries.patch avvissu@yandex.ru -- Add link to libraries and use a static library -Patch0: slowmoVideo-0.4_link_libraries.patch +URL: http://slowmovideo.granjow.net/ +Source: %{name}-%{version}.tar.xz +# PATCH-FIX-OPENSUSE slowmoVideo-desktop.patch produce proper desktop file -- aloisio@gmx.com +Patch1: slowmoVideo-desktop.patch +BuildRequires: ImageMagick BuildRequires: cmake BuildRequires: gcc-c++ -BuildRequires: fdupes -BuildRequires: unzip -BuildRequires: freeglut-devel -BuildRequires: pkgconfig(libavcodec) = 56.60.100 -BuildRequires: pkgconfig(libavformat) = 56.40.101 -BuildRequires: pkgconfig(libavutil) = 54.31.100 -BuildRequires: pkgconfig(libswscale) = 3.1.101 -BuildRequires: pkgconfig(QtCore) >= 4.7 -BuildRequires: pkgconfig(QtGui) -BuildRequires: pkgconfig(QtTest) -BuildRequires: pkgconfig(QtScript) -BuildRequires: pkgconfig(glew) +BuildRequires: hicolor-icon-theme +BuildRequires: pkgconfig +BuildRequires: update-desktop-files +BuildRequires: pkgconfig(Qt5Concurrent) +BuildRequires: pkgconfig(Qt5Core) +BuildRequires: pkgconfig(Qt5Gui) +BuildRequires: pkgconfig(Qt5Script) +BuildRequires: pkgconfig(Qt5Widgets) +BuildRequires: pkgconfig(Qt5Xml) BuildRequires: pkgconfig(gl) -BuildRequires: pkgconfig(sdl) +BuildRequires: pkgconfig(glew) +%if 0%{?sle_version} >= 150200 || %{?suse_version} > 1500 +BuildRequires: pkgconfig(glut) +%else +BuildRequires: pkgconfig(freeglut) +%endif +BuildRequires: pkgconfig(libavcodec) +BuildRequires: pkgconfig(libavformat) +BuildRequires: pkgconfig(libavutil) +BuildRequires: pkgconfig(libswscale) BuildRequires: pkgconfig(opencv) -BuildRequires: ImageMagick -BuildRequires: update-desktop-files -BuildRoot: %{_tmppath}/%{name}-%{version}-build +BuildRequires: pkgconfig(sdl) +Requires: ffmpeg +Requires: slowmoFlowBuilder %description Is an OpenSource program that creates slow-motion videos from your footage.. -But it does not simply make your videos play at 0.01× speed. You can +But it does not simply make your videos play at 0.01× speed. You can smoothly slow down and speed up your footage, optionally with motion blur. -How does slow motion work? slowmoVideo tries to find out where pixels move -in the video (this information is called Optical Flow), and then uses this -information to calculate the additional frames between the ones recorded by +How does slow motion work? slowmoVideo tries to find out where pixels move +in the video (this information is called Optical Flow), and then uses this +information to calculate the additional frames between the ones recorded by your camera. %prep -%setup -q -%patch0 -p1 +%autosetup -p1 %build %cmake \ -DCMAKE_BUILD_TYPE:STRING=Release \ - -DENABLE_TESTS:BOOL=false \ - ../src -make %{?_smp_mflags} + -DENABLE_TESTS:BOOL=false +%cmake_build %install %cmake_install -#install -d %{buildroot}%{_var}/lib/%{name} - -convert src/%{name}/slowmoUI/res/AppIcon.png -resize 64x64 %{name}.png -install -Dm 0644 %{name}.png %{buildroot}%{_datadir}/pixmaps/%{name}.png -%suse_update_desktop_file -c %{name} %{name} "Slowmotion Video" slowmoUI %{name} Qt Multimedia AudioVideoEditing - -%fdupes -s %{buildroot} +for s in 16 32 48 64 96 128 192 256 512; do + mkdir -pv %{buildroot}%{_datadir}/icons/hicolor/${s}x${s}/apps + convert -strip -scale ${s}x${s} src/slowmoUI/res/AppIcon.png %{buildroot}%{_datadir}/icons/hicolor/${s}x${s}/apps/slowmoUI.png +done %files -%defattr(-,root,root) -%{_bindir}/slowmoFlowBuilder %{_bindir}/slowmoFlowEdit -%{_bindir}/slowmoInfo %{_bindir}/slowmoInterpolate %{_bindir}/slowmoRenderer %{_bindir}/slowmoUI %{_bindir}/slowmoVideoInfo %{_bindir}/slowmoVisualizeFlow -%{_datadir}/pixmaps/%{name}.png -%{_datadir}/applications/%{name}.desktop +%{_datadir}/applications/slowmoUI.desktop +%{_datadir}/icons/hicolor/*/apps/slowmoUI.png %changelog
View file
slowmoVideo-0.4_link_libraries.patch
Deleted
@@ -1,14 +0,0 @@ -diff -U 3 -H -d -r -N -- slowmoVideo-0.4.orig/src/CMakeLists.txt slowmoVideo-0.4/src/CMakeLists.txt ---- slowmoVideo-0.4.orig/src/CMakeLists.txt 2014-06-28 11:34:28.000000000 +0300 -+++ slowmoVideo-0.4/src/CMakeLists.txt 2015-08-20 06:36:49.414494041 +0300 -@@ -242,8 +242,8 @@ - V3D/Math/v3d_linearbase.h - ) - -- add_library(V3D ${ALL_SRC}) -- target_link_libraries(V3D ${GLEW_LIBRARIES}) -+ add_library(V3D STATIC ${ALL_SRC}) -+ target_link_libraries(V3D ${GLEW_LIBRARIES} -lX11 -lglut -lGL -lGLU -ljpeg -lpng) - #install(TARGETS V3D DESTINATION lib) - add_subdirectory(V3D/Apps) - endif (BUILD_FLOW_BUILDER)
View file
slowmoVideo-desktop.patch
Added
@@ -0,0 +1,32 @@ +Index: slowmoVideo-0.6/src/slowmoUI/CMakeLists.txt +=================================================================== +--- slowmoVideo-0.6.orig/src/slowmoUI/CMakeLists.txt ++++ slowmoVideo-0.6/src/slowmoUI/CMakeLists.txt +@@ -126,22 +126,21 @@ if (UNIX AND NOT APPLE) + # create desktop file for KDE/Gnome + # desktop file section + file( WRITE "${PROJECT_BINARY_DIR}/slowmoUI.desktop" +-"#!/usr/bin/env xdg-open +-Desktop Entry ++"Desktop Entry + Type=Application + Comment=Slow Motion Video + Exec=${CMAKE_INSTALL_PREFIX}/bin/slowmoUI + GenericName=slowmoVideo +-Icon=${CMAKE_INSTALL_PREFIX}/share/icons/AppIcon ++Icon=slowmoUI + MimeType= + Name=slowmoUI + Terminal=false +-Categories=Qt;AudioVideo;Video;\n") ++Categories=Qt;AudioVideo;AudioVideoEditing;\n") + + #install ( FILES icons/slowmoUI.png DESTINATION share/icons ) +- install ( FILES res/AppIcon.png DESTINATION share/icons ) ++ #install ( FILES res/AppIcon.png DESTINATION share/icons ) + install ( FILES ${PROJECT_BINARY_DIR}/slowmoUI.desktop DESTINATION share/applications +- PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE ++ PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ + ) + endif() +
View file
_service
Added
@@ -0,0 +1,17 @@ +<services> + <service mode="disabled" name="tar_scm"> + <param name="url">https://github.com/slowmoVideo/slowmoVideo.git</param> + <param name="scm">git</param> + <param name="exclude">.git</param> + <param name="revision">v0.6</param> + <param name="versionrewrite-pattern">v(.*)</param> + <param name="versionrewrite-replacement">\1</param> + <param name="versionformat">@PARENT_TAG@</param> + </service> + <service mode="disabled" name="recompress"> + <param name="file">*.tar</param> + <param name="compression">xz</param> + </service> + <service mode="disabled" name="set_version" /> +</services> +
View file
slowmoVideo-0.4.tar.gz/.gitignore
Deleted
@@ -1,24 +0,0 @@ -*~ -*.txt.user - -install - -/*.png -/slowmoVideo*.bz2 -flowScripts/*.avi -flowScripts/*.pyc - -clips -*/build - -slowmoVideo/docs/html -slowmoVideo/docs/latex - -img/*.sVflow -qtcreator* - -material/*.blend1 -material/*.blend2 - -.DS_Store -
View file
slowmoVideo-0.4.tar.gz/Makefile
Deleted
@@ -1,6 +0,0 @@ -.PHONY : tarball -.PHONY : release - -# Creates a tarball when on a git repository. (git is required.) -tarball : - @git archive master --format=tar |bzip2 >"slowmoVideo-sources-$(shell ./version.sh).tar.bz2"
View file
slowmoVideo-0.4.tar.gz/doc
Deleted
-(directory)
View file
slowmoVideo-0.4.tar.gz/doc/todo.txt
Deleted
@@ -1,2 +0,0 @@ - -* Literatur, H.264 etc
View file
slowmoVideo-0.4.tar.gz/src/CMakeLists.txt
Deleted
@@ -1,332 +0,0 @@ -cmake_minimum_required(VERSION 2.6) - -project(slowmoVideo) - -set (CMAKE_BUILD_TYPE Release) -#set(CMAKE_BUILD_TYPE Debug) - -set(PROJECT_VERSION_MAJOR "0") -set(PROJECT_VERSION_MINOR "3") -set(PROJECT_VERSION_PATCH "1") -set(PROJECT_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}") - -### Compiler options ### - -if (APPLE) -# To compile with clang: -#set(CMAKE_CXX_COMPILER "clang++") -#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall --verbose") -#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -O2 -mtune=corei7") -else() -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -O2") -endif() - -if(CMAKE_TOOLCHAIN_FILE) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DMXE") - set(CMAKE_C_FLAGS "${CMAKE_CXX_FLAGS} -DMXE") -endif(CMAKE_TOOLCHAIN_FILE) - - -### CMake Configuration ### -option (ENABLE_TESTS "Build the unit tests" TRUE) -set(ADDITIONAL_LIBS "") -if(MSYS) - message(STATUS "MSYS system detected.") - include("${PROJECT_SOURCE_DIR}/cmake/MingwCrossEnv.cmake") -endif(MSYS) - - -### Find packages ### - -set(CMAKE_MODULE_PATH - ${slowmoVideo_SOURCE_DIR}/cmake -) - -set(DEST "bin") - -include(cmake/macros.cmake) - -SET(QT_USE_QTXML TRUE) -SET(QT_USE_QTTEST TRUE) -SET(QT_USE_QTSCRIPT TRUE) -find_package(Qt4) -include(${QT_USE_FILE}) -include_directories(${QT_INCLUDES}) - - -if(NOT MSYS) - find_package(FFMPEG) -else(NOT MSYS) - # Handled by MingwCrossEnv.cmake to avoid errors like: - # libavformat.a(avisynth.o):avisynth.c:(.text+0x6b): undefined reference to `AVIStreamRelease@4' -endif(NOT MSYS) -# not here anymore -#include_directories(${FFMPEG_INCLUDE_DIR}) -#include_directories("/usr/include/ffmpeg/") -#link_directories(${FFMPEG_LIBRARY_DIR}) - -find_package(OpenCV) -include_directories(${OPENCV_INCLUDE_DIRS}) - - - - - -### Set up libraries ### -if(MSYS) - set(EXTERNAL_LIBS ${FFMPEG_LIBRARIES} ${QT_LIBRARIES} ${OpenCV_LIBS_OPT} ${OpenCV_EXTRA_LIBS_OPT} ${ADDITIONAL_LIBS}) -else(MSYS) - set(EXTERNAL_LIBS ${QT_LIBRARIES} ${OpenCV_LIBS} ${ADDITIONAL_LIBS} ${FFMPEG_LIBRARIES}) -endif(MSYS) - - -### Information output -set(BUILD_SLOWMO "NO") -if(QT_LIBRARIES AND FFMPEG_FOUND) -set(BUILD_SLOWMO "YES") -endif(QT_LIBRARIES AND FFMPEG_FOUND) -if(NOT FFMPEG_SWSCALE_FOUND) - if(CMAKE_TOOLCHAIN_FILE) - - else(CMAKE_TOOLCHAIN_FILE) - set(BUILD_SLOWMO "NO") - endif(CMAKE_TOOLCHAIN_FILE) -endif(NOT FFMPEG_SWSCALE_FOUND) - - - - - -## Include projects to build ## - -include_directories(slowmoVideo/tr) -add_subdirectory(slowmoVideo/lib) -add_subdirectory(slowmoVideo/libgui) -add_subdirectory(slowmoVideo/project) -add_subdirectory(slowmoVideo/slowmoCLI) -add_subdirectory(slowmoVideo/slowmoUI) -add_subdirectory(slowmoVideo/slowmoFlowEdit) -add_subdirectory(slowmoVideo/slowmoInfo) -add_subdirectory(slowmoVideo/slowmoRenderer) -add_subdirectory(slowmoVideo/visualizeFlow) -if(ENABLE_TESTS) -add_subdirectory(slowmoVideo/test) -add_subdirectory(slowmoVideo/unittests) -endif(ENABLE_TESTS) - -##### SV END ##### - - - - - -##### V3D START ##### - -if(WIN32) -set(GLUT_ROOT_PATH ${PROJECT_SOURCE_DIR}/libs/) -endif(WIN32) - -find_package(OpenGL) -find_package(GLEW) -find_package(GLUT) -find_package(JPEG) -find_package(PNG) -find_package(ZLIB) - -# Windows: Try to find libraries that could not be found manually in the libs/ directory. -if(WIN32) - if(NOT ZLIB_FOUND) - FIND_PATH(ZLIB_INCLUDE_DIR zlib.h - PATHS ${PROJECT_SOURCE_DIR}/libs/include - ) - find_library(ZLIB_LIBRARY NAMES zlib PATHS ${PROJECT_SOURCE_DIR}/libs/lib) - if(ZLIB_INCLUDE_DIR AND ZLIB_LIBRARY) - set(ZLIB_FOUND TRUE) - endif(ZLIB_INCLUDE_DIR AND ZLIB_LIBRARY) - message(STATUS "Manual search for zlib: ${ZLIB_LIBRARY} in ${ZLIB_INCLUDE_DIR}") - endif(NOT ZLIB_FOUND) - - if(NOT PNG_FOUND) - find_path(PNG_INCLUDE_DIR png.h PATHS ${PROJECT_SOURCE_DIR}/libs/include) - find_library(PNG_LIBRARIES libpng PATHS ${PROJECT_SOURCE_DIR}/libs/lib) - if(PNG_INCLUDE_DIR AND PNG_LIBRARIES) - set(PNG_FOUND TRUE) - endif(PNG_INCLUDE_DIR AND PNG_LIBRARIES) - message(STATUS "Manual search for png: ${PNG_LIBRARIES} in ${PNG_INCLUDE_DIR}") - endif(NOT PNG_FOUND) - - if(NOT GLUT_FOUND) - find_path(GLUT_LIBRARY_DIR NAMES GL/glut.h PATHS ${PROJECT_SOURCE_DIR}/libs/include) - find_library(GLUT_LIBRARIES glut32 PATHS ${PROJECT_SOURCE_DIR}/libs/lib) - if(GLUT_LIBRARY_DIR AND GLUT_LIBRARIES) - set(GLUT_FOUND TRUE) - endif(GLUT_LIBRARY_DIR AND GLUT_LIBRARIES) - message(STATUS "Manual search for GLUT: ${GLUT_LIBRARIES} in ${GLUT_LIBRARY_DIR}") - endif(NOT GLUT_FOUND) - - if(NOT JPEG_FOUND) - FIND_PATH(JPEG_INCLUDE_DIR jpeglib.h PATHS ${PROJECT_SOURCE_DIR}/libs/include) - - SET(JPEG_NAMES ${JPEG_NAMES} jpeg) - FIND_LIBRARY(JPEG_LIBRARY NAMES ${JPEG_NAMES} PATHS ${PROJECT_SOURCE_DIR}/libs/lib) - if(JPEG_INCLUDE_DIR AND JPEG_LIBRARY) - set(JPEG_FOUND TRUE) - endif(JPEG_INCLUDE_DIR AND JPEG_LIBRARY) - message(STATUS "Manual search for JPEG: ${JPEG_LIBRARY} in ${JPEG_INCLUDE_DIR}") - endif(NOT JPEG_FOUND) -endif(WIN32) - - -set(BUILD_FLOW_BUILDER "NO") -if(OPENGL_FOUND AND GLUT_FOUND AND GLEW_FOUND AND JPEG_FOUND AND PNG_FOUND) - set(BUILD_FLOW_BUILDER "YES") -endif(OPENGL_FOUND AND GLUT_FOUND AND GLEW_FOUND AND JPEG_FOUND AND PNG_FOUND) - -set(INCLUDE_SOURCE "YES") -if(DISABLE_INCLUDE_SOURCE) - set(INCLUDE_SOURCE "NO") -add_definitions(-DDISABLE_INCLUDE_SOURCE) -endif(DISABLE_INCLUDE_SOURCE) - - -if (BUILD_FLOW_BUILDER) - include_directories(${OPENGL_INCLUDE_DIR}) - include_directories(${GLUT_INCLUDE_DIR}) - include_directories(${GLEW_INCLUDE_DIR}) - include_directories(${JPEG_INCLUDE_DIR}) - include_directories(${ZLIB_INCLUDE_DIR}) - include_directories(${PNG_INCLUDE_DIR}) - - - set (V3D_DIR ${CMAKE_CURRENT_SOURCE_DIR}/V3D) - set (V3D_INCLUDE_DIRS ${V3D_DIR}/.) - - include (V3D/Config/v3d_macros.cmake) - include_directories(${V3D_INCLUDE_DIRS} ${EXTRA_INC_DIRS}) - - add_definitions(-DDISABLE_REDEFINITIONS) - #-------------------------------------------------- - enable_feature (V3DLIB_ENABLE_LIBJPEG) - enable_feature (V3DLIB_ENABLE_LIBPNG) - enable_feature_libraries (V3DLIB_ENABLE_LIBJPEG ${JPEG_LIBRARIES}) - enable_feature_libraries (V3DLIB_ENABLE_LIBPNG ${PNG_LIBRARIES}) - - enable_feature (V3DLIB_ENABLE_GPGPU) - enable_feature_libraries (V3DLIB_ENABLE_GPGPU ${OPENGL_LIBRARIES}) - enable_feature_libraries (V3DLIB_ENABLE_GPGPU ${GLEW_LIBRARIES}) - enable_feature_libraries (V3DLIB_ENABLE_GPGPU ${GLUT_glut_LIBRARY}) - #-------------------------------------------------- - - - include_directories(V3D/Config) - - set (GL_SRC - V3D/GL/glsl_shaders.cpp - V3D/GL/v3d_gpubase.cpp - V3D/GL/v3d_gpuflow.cpp - V3D/GL/v3d_gpucolorflow.cpp - V3D/GL/v3d_gpupyramid.cpp - ) - - set (ALL_SRC - ${GL_SRC} - V3D/Config/config.h - - V3D/Base/v3d_image.cpp - V3D/Base/v3d_imageprocessing.h - V3D/Base/v3d_exception.h - V3D/Base/v3d_timer.h - V3D/Base/v3d_serialization.h - V3D/Base/v3d_utilities.h - V3D/Math/v3d_linear.h - V3D/Math/v3d_linearbase.h - ) - - add_library(V3D ${ALL_SRC}) - target_link_libraries(V3D ${GLEW_LIBRARIES}) - #install(TARGETS V3D DESTINATION lib) - add_subdirectory(V3D/Apps) -endif (BUILD_FLOW_BUILDER) - -##### V3D END ##### - - - - - -message("") -message("======================V3D============================") -message("* (info) Installation prefix: ${CMAKE_INSTALL_PREFIX}.") -message(" (Can be adjusted with -DCMAKE_INSTALL_PREFIX=your_path. Default: ${SV_INST_DIR}.)") -message("* (info) Shaders will be included in the binary: ${INCLUDE_SOURCE}") -if(INCLUDE_SOURCE) - message(" (Can be disabled with the cmake flag -DDISABLE_INCLUDE_SOURCE)") -endif(INCLUDE_SOURCE) - - -if(NOT OPENGL_FOUND) - message("* OpenGL could not be found.") -else(NOT OPENGL_FOUND) - message("* (ok) OpenGL found in ${OPENGL_INCLUDE_DIR}: ${OPENGL_LIBRARIES}") -endif(NOT OPENGL_FOUND) - -if(NOT GLUT_FOUND) - message("* GLUT could not be found.") -else(NOT GLUT_FOUND) - message("* (ok) GLUT found in ${GLUT_INCLUDE_DIR}: ${GLUT_LIBRARIES}") -endif(NOT GLUT_FOUND) - -if(NOT GLEW_FOUND) - message("* GLEW could not be found.") -else(NOT GLEW_FOUND) - message("* (ok) GLEW found at ${GLEW_INCLUDE_DIR}") -endif(NOT GLEW_FOUND) - -if(NOT JPEG_FOUND) - message("* JPEG libraries could not be found.") -else(NOT JPEG_FOUND) - message("* (ok) JPEG libraries found at ${JPEG_INCLUDE_DIR}: ${JPEG_LIBRARIES}") -endif(NOT JPEG_FOUND) - -if(NOT PNG_FOUND) - message("* PNG libraries could not be found.") -else(NOT PNG_FOUND) - message("* (ok) PNG libraries found at ${PNG_INCLUDE_DIR}") -endif(NOT PNG_FOUND) - -message("* V3D will be built: ---${BUILD_FLOW_BUILDER}---") - - -message("==================slowmoVideo========================") -message("* (info) slowmoVideo installation goes to ${CMAKE_INSTALL_PREFIX}.") -message(" (Can be adjusted with -DCMAKE_INSTALL_PREFIX=your_path. Default is ${SV_INST_DIR}.)") -if(NOT QT_LIBRARIES) - message("x Qt4 libraries could not be found.") -endif(NOT QT_LIBRARIES) -if(NOT FFMPEG_FOUND) - message("x ffmpeg libraries could not be found.") -else(NOT FFMPEG_FOUND) - message("* (ok) ffmpeg found at ${FFMPEG_LIBRARY_DIR}") -endif(NOT FFMPEG_FOUND) -if(NOT FFMPEG_SWSCALE_FOUND) - message("x libswscale could not be found.") -endif(NOT FFMPEG_SWSCALE_FOUND) -if(NOT OpenCV_VERSION) - message("x OpenCV could not be found.") -else(NOT OpenCV_VERSION) - message("* (ok) OpenCV ${OpenCV_VERSION} found at ${OPENCV_LIB_DIR}.") -endif(NOT OpenCV_VERSION) -message("* slowmoVideo will be built: ---${BUILD_SLOWMO}---") -message("=======================END===========================") -message("") - - -if(NOT BUILD_SLOWMO) - message(WARNING "Cannot build slowmoVideo, please install the missing packages first.") -endif(NOT BUILD_SLOWMO) - -if(NOT BUILD_FLOW_BUILDER) - message(WARNING "Cannot build V3D.") -endif(NOT BUILD_FLOW_BUILDER) - -
View file
slowmoVideo-0.4.tar.gz/src/V3D
Deleted
-(directory)
View file
slowmoVideo-0.4.tar.gz/src/V3D/Apps
Deleted
-(directory)
View file
slowmoVideo-0.4.tar.gz/src/V3D/Apps/CMakeLists.txt
Deleted
@@ -1,3 +0,0 @@ -if (V3DLIB_ENABLE_GPGPU) - add_subdirectory(GL) -endif (V3DLIB_ENABLE_GPGPU)
View file
slowmoVideo-0.4.tar.gz/src/V3D/Apps/GL
Deleted
-(directory)
View file
slowmoVideo-0.4.tar.gz/src/V3D/Apps/GL/CMakeLists.txt
Deleted
@@ -1,15 +0,0 @@ -include_directories(${V3D_INCLUDE_DIRS} ${EXTRA_INC_DIRS} ${slowmoVideo_SOURCE_DIR}/slowmoVideo/lib) -link_directories(${V3D_DIR} ${EXTRA_LIB_DIRS}) -link_libraries (V3D ${EXTRA_LIBRARIES}) - -if(V3DLIB_ENABLE_GPGPU) - add_v3d_executable( - slowmoFlowBuilder - flowBuilder.cpp - ${slowmoVideo_SOURCE_DIR}/slowmoVideo/lib/flowField_sV.cpp - ${slowmoVideo_SOURCE_DIR}/slowmoVideo/lib/flowRW_sV.cpp - ) -endif (V3DLIB_ENABLE_GPGPU) - -install(TARGETS slowmoFlowBuilder DESTINATION ${DEST}) -
View file
slowmoVideo-0.4.tar.gz/src/V3D/Apps/GL/flowBuilder.cpp
Deleted
@@ -1,317 +0,0 @@ -/// \todo Check that (width|height)/2^nLevels >= 1 - -#include "Base/v3d_image.h" -#include "Base/v3d_imageprocessing.h" -#include "Base/v3d_timer.h" - -#include "GL/v3d_gpucolorflow.h" - -#include <iostream> - -#include <GL/glew.h> -#ifdef __APPLE__ -#include <glut.h> -#elif defined(_WIN32) -#include <GL/glut.h> -#else -#define USE_RAW_X11 -#include<X11/X.h> -#include<X11/Xlib.h> -#include<GL/gl.h> -#include<GL/glx.h> -#endif - -#include "flowRW_sV.h" -#include "flowField_sV.h" - -using namespace V3D; -using namespace V3D_GPU; - -#define VERSION "2.0" - -//#define USE_LAB_COLORSPACE 1 - -int const nLevels = 6; // Must be large enough for big images. Number of pyramid levels. -int const startLevel = 0; -int nIterations = 200; -int const nOuterIterations = 4; -float const lambdaScale = 1.0; - -Image<unsigned char> leftImage, rightImage; -Image<float> leftImageLab, rightImageLab; -const char *outputFile; - -float lambda = 1.0f; - -float const tau = 0.249f; -float const theta = 0.1f; -typedef TVL1_ColorFlowEstimator_QR TVL1_FlowEstimator; - -TVL1_FlowEstimator::Config flowCfg(tau, theta); -TVL1_FlowEstimator * flowEstimator; - -#if !defined(USE_LAB_COLORSPACE) -PyramidWithDerivativesCreator leftPyrR(false), rightPyrR(false); -PyramidWithDerivativesCreator leftPyrG(false), rightPyrG(false); -PyramidWithDerivativesCreator leftPyrB(false), rightPyrB(false); -#else -char const * pyrTexSpec = "r=32f noRTT"; -PyramidWithDerivativesCreator leftPyrR(false, pyrTexSpec), rightPyrR(false, pyrTexSpec); -PyramidWithDerivativesCreator leftPyrG(false, pyrTexSpec), rightPyrG(false, pyrTexSpec); -PyramidWithDerivativesCreator leftPyrB(false, pyrTexSpec), rightPyrB(false, pyrTexSpec); -#endif - -#ifdef USE_LAB_COLORSPACE -inline void convertRGBImageToCIELab(Image<unsigned char> const& src, Image<float>& dst) -{ - int const w = src.width(); - int const h = src.height(); - dst.resize(w, h, 3); - - Vector3f rgb, xyz, lab; - - for (int y = 0; y < h; ++y) - for (int x = 0; x < w; ++x) - { - rgb0 = src(x, y, 0) / 255.0f; - rgb1 = src(x, y, 1) / 255.0f; - rgb2 = src(x, y, 2) / 255.0f; - - rgb = convertRGBPixelTo_sRGB(rgb); - xyz = convert_sRGBPixelToXYZ(rgb); - lab = convertXYZPixelToCIELab(xyz); - scaleVectorIP(0.01f, lab); - - dst(x, y, 0) = lab0; - dst(x, y, 1) = lab1; - dst(x, y, 2) = lab2; - } -} // end convertRGBImageToCIELab() -#endif - -void drawscene() -{ - int const w = leftImage.width(); - int const h = leftImage.height(); - - { - ScopedTimer st("glew/cg init"); - glewInit(); - } - { - ScopedTimer st("initialization flow"); - - flowEstimator = new TVL1_FlowEstimator(nLevels); - flowEstimator->configurePrecision(false, false, false); - flowEstimator->allocate(w, h); - flowEstimator->setLambda(lambda); - flowEstimator->configure(flowCfg); - flowEstimator->setInnerIterations(nIterations); - flowEstimator->setOuterIterations(nOuterIterations); - flowEstimator->setStartLevel(startLevel); - } - { - ScopedTimer st("allocating pyramids"); - - leftPyrR.allocate(w, h, nLevels); - rightPyrR.allocate(w, h, nLevels); - leftPyrG.allocate(w, h, nLevels); - rightPyrG.allocate(w, h, nLevels); - leftPyrB.allocate(w, h, nLevels); - rightPyrB.allocate(w, h, nLevels); - } - - unsigned int leftPyrTexIDs3; - unsigned int rightPyrTexIDs3; - - { - ScopedTimer st("building pyramids"); - -#if !defined(USE_LAB_COLORSPACE) - if (leftImage.numChannels() == 3) { - leftPyrR.buildPyramidForGrayscaleImage(leftImage.begin(0)); - leftPyrG.buildPyramidForGrayscaleImage(leftImage.begin(1)); - leftPyrB.buildPyramidForGrayscaleImage(leftImage.begin(2)); - } else { - leftPyrR.buildPyramidForGrayscaleImage(leftImage.begin(0)); - leftPyrG.buildPyramidForGrayscaleImage(leftImage.begin(0)); - leftPyrB.buildPyramidForGrayscaleImage(leftImage.begin(0)); - } - if (rightImage.numChannels() == 3) { - rightPyrR.buildPyramidForGrayscaleImage(rightImage.begin(0)); - rightPyrG.buildPyramidForGrayscaleImage(rightImage.begin(1)); - rightPyrB.buildPyramidForGrayscaleImage(rightImage.begin(2)); - } else { - rightPyrR.buildPyramidForGrayscaleImage(rightImage.begin(0)); - rightPyrG.buildPyramidForGrayscaleImage(rightImage.begin(0)); - rightPyrB.buildPyramidForGrayscaleImage(rightImage.begin(0)); - } -#else - leftPyrR.buildPyramidForGrayscaleImage(leftImageLab.begin(0)); - leftPyrG.buildPyramidForGrayscaleImage(leftImageLab.begin(1)); - leftPyrB.buildPyramidForGrayscaleImage(leftImageLab.begin(2)); - - rightPyrR.buildPyramidForGrayscaleImage(rightImageLab.begin(0)); - rightPyrG.buildPyramidForGrayscaleImage(rightImageLab.begin(1)); - rightPyrB.buildPyramidForGrayscaleImage(rightImageLab.begin(2)); -#endif - - leftPyrTexIDs0 = leftPyrR.textureID(); - leftPyrTexIDs1 = leftPyrG.textureID(); - leftPyrTexIDs2 = leftPyrB.textureID(); - rightPyrTexIDs0 = rightPyrR.textureID(); - rightPyrTexIDs1 = rightPyrG.textureID(); - rightPyrTexIDs2 = rightPyrB.textureID(); - } - - { - ScopedTimer st("flowEstimator"); - flowEstimator->run(leftPyrTexIDs, rightPyrTexIDs); - } - - // Save the generated flow field - float *data = new float2*leftImage.width()*leftImage.height(); - { - ScopedTimer st("readPixels"); - RTT_Buffer *buf = flowEstimator->getFlowBuffer(); - buf->makeCurrent(); - glReadBuffer(GL_COLOR_ATTACHMENT0); - glReadPixels(0,0,leftImage.width(), leftImage.height(), GL_RG, GL_FLOAT, data); - } - - { - ScopedTimer st("saving"); - FlowField_sV field(leftImage.width(), leftImage.height(), data, FlowField_sV::GLFormat_RG); - FlowRW_sV::save(outputFile, &field); - } - exit(0); -} - -int main( int argc, char** argv) -{ - if ((argc-1) == 1) { - if (strcmp(argv1, "--identify") == 0) { - std::cout << "slowmoFlowBuilder v" << VERSION << std::endl; - return 0; - } - } - - if ((argc-1) < 3) { - std::cout << "Usage: " << argv0 << " <left image> <right image> <outFilename> " - " <lambda=" << lambda << "> <nIterations=" << nIterations << "> " << std::endl; - return -1; - } - - { - ScopedTimer st("loading files"); - loadImageFile(argv1, leftImage); - loadImageFile(argv2, rightImage); - } - - outputFile = argv3; - - if ((argc-1) >= 4) { - lambda = atof(argv4); - if ((argc-1) >= 5) { - nIterations = atoi(argv5); - } - } - - if (leftImage.numChannels() != 3 || rightImage.numChannels() != 3) { - std::cout << "leftImage.numChannels() = " << leftImage.numChannels() << std::endl; - std::cout << "rightImage.numChannels() = " << rightImage.numChannels() << std::endl; - } - - { - ScopedTimer st("initialization GL"); -#ifdef USE_RAW_X11 - Display *dpy = XOpenDisplay(0); - if (!dpy) { - std::cerr << "ERROR: could not open display\n"; - exit(1); - } - - GLint att = { GLX_RGBA, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER, None, 0 }; - XVisualInfo *vi = glXChooseVisual(dpy,0,att); - if (!vi) { - std::cerr << "ERROR: could not choose a GLX visual\n"; - exit(1); - } - - Colormap cmap = XCreateColormap(dpy, DefaultRootWindow(dpy), vi->visual, AllocNone); - XSetWindowAttributes wattr; - wattr.colormap = cmap; - - Window win = XCreateWindow(dpy, DefaultRootWindow(dpy), 0, 0, 1, 1, 0, vi->depth, InputOutput, vi->visual,CWColormap, &wattr); - if (win == None) { - std::cerr << "ERROR: could not create window\n"; - exit(1); - } - GLXContext ctx = glXCreateContext(dpy, vi, NULL, GL_TRUE); - if (!ctx) { - std::cerr << "ERROR: could not create GL context\n"; - exit(1); - } - - if (!glXMakeCurrent(dpy,win,ctx)) { - std::cerr << "ERROR: could not make context current\n"; - exit(1); - } -#else - glutInitWindowPosition(0, 0); - glutInitWindowSize(100, 100); - glutInit(&argc, argv); -#endif - } - -#if !defined(USE_LAB_COLORSPACE) - if (leftImage.numChannels() < 3 || rightImage.numChannels() < 3) - cerr << "Warning: grayscale images provided." << std::endl; -#else - if (leftImage.numChannels() < 3 || rightImage.numChannels() < 3) - { - cerr << "Error: grayscale images provided." << std::endl; - return -2; - } - - convertRGBImageToCIELab(leftImage, leftImageLab); - convertRGBImageToCIELab(rightImage, rightImageLab); - - float maxL = -1e30f, minL = 1e30f; - float maxA = -1e30f, minA = 1e30f; - float maxB = -1e30f, minB = 1e30f; - maxL = std::max(maxL, *max_element(leftImageLab.begin(0), leftImageLab.end(0))); - minL = std::min(minL, *min_element(leftImageLab.begin(0), leftImageLab.end(0))); - maxL = std::max(maxL, *max_element(rightImageLab.begin(0), rightImageLab.end(0))); - minL = std::min(minL, *min_element(rightImageLab.begin(0), rightImageLab.end(0))); - std::cout << "minL = " << minL << " maxL = " << maxL << std::endl; - - maxA = std::max(maxA, *max_element(leftImageLab.begin(1), leftImageLab.end(1))); - minA = std::min(minA, *min_element(leftImageLab.begin(1), leftImageLab.end(1))); - maxA = std::max(maxA, *max_element(rightImageLab.begin(1), rightImageLab.end(1))); - minA = std::min(minA, *min_element(rightImageLab.begin(1), rightImageLab.end(1))); - std::cout << "minA = " << minA << " maxA = " << maxA << std::endl; - - maxB = std::max(maxB, *max_element(leftImageLab.begin(2), leftImageLab.end(2))); - minB = std::min(minB, *min_element(leftImageLab.begin(2), leftImageLab.end(2))); - maxB = std::max(maxB, *max_element(rightImageLab.begin(2), rightImageLab.end(2))); - minB = std::min(minB, *min_element(rightImageLab.begin(2), rightImageLab.end(2))); - std::cout << "minB = " << minB << " maxB = " << maxB << std::endl; -#endif - -#ifdef USE_RAW_X11 - drawscene(); -#else - glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE); - - if (!glutCreateWindow("GPU TV-L1 Optic Flow")) { - cerr << "Error, couldn't open window" << std::endl; - return -1; - } - - glutDisplayFunc(drawscene); - glutMainLoop(); -#endif - - return 0; -}
View file
slowmoVideo-0.4.tar.gz/src/V3D/Base
Deleted
-(directory)
View file
slowmoVideo-0.4.tar.gz/src/V3D/Base/v3d_exception.h
Deleted
@@ -1,64 +0,0 @@ -// -*- C++ -*- - -#ifndef V3D_EXCEPTION_H -#define V3D_EXCEPTION_H - -#include <exception> -#include <string> -#include <sstream> -#include <iostream> -#include <assert.h> - -#define verify(condition, message) do \ - { \ - if (!(condition)) { \ - std::cout << "VERIFY FAILED: " << (message) << "\n" \ - << " " << __FILE__ << ", " << __LINE__ << "\n"; \ - assert(false); \ - exit(0); \ - } \ - } while(false); - -#define throwV3DErrorHere(reason) throw V3D::Exception(__FILE__, __LINE__, reason) - -namespace V3D -{ - - struct Exception : public std::exception - { - Exception(char const * reason) - : _reason(reason) - { } - - Exception(std::string const& reason) - : _reason(reason) - { } - - Exception(char const * file, int line, char const * reason) - { - std::ostringstream os; - os << file << ":" << line << ": " << reason; - _reason = os.str(); - } - - Exception(char const * file, int line, std::string const& reason) - { - std::ostringstream os; - os << file << ":" << line << ": " << reason; - _reason = os.str(); - } - - virtual ~Exception() throw() { } - - virtual const char * what() const throw() - { - return _reason.c_str(); - } - - protected: - std::string _reason; - }; // end struct Exception - -} // end namespace V3D - -#endif
View file
slowmoVideo-0.4.tar.gz/src/V3D/Base/v3d_image.cpp
Deleted
@@ -1,808 +0,0 @@ -#include "Base/v3d_image.h" -#include "Base/v3d_exception.h" - -#include <cstdio> -#include <string> -#include <iostream> -#include <limits.h> // for INT_MAX - -#if defined(V3DLIB_ENABLE_LIBJPEG) -extern "C" -{ -# include <jpeglib.h> -} -#endif - -#if defined(V3DLIB_ENABLE_LIBPNG) -# include <png.h> -#endif - -using namespace std; - -namespace -{ - - // Adapted from netpbm - - inline bool - pnm_getc(FILE * const file, char& dst) - { - int ich; - - ich = getc(file); - if (ich == EOF) return false; // premature EOF - dst = (char) ich; - - // Skip comments - if (dst == '#') - { - do - { - ich = getc(file); - if (ich == EOF) return false; // premature EOF - dst = (char) ich; - } while (dst != '\n' && dst != '\r'); - } - - return true; - } // end pnm_getc() - - inline bool - pnm_getuint(FILE * const file, unsigned int& res) - { - char ch; - - do - { - if (!pnm_getc(file, ch)) return false; - } - while (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r'); - - if (ch < '0' || ch > '9') return false; - - res = 0; - do - { - unsigned int const digitVal = ch - '0'; - - if (res > INT_MAX/10 - digitVal) return false; - - res = res * 10 + digitVal; - - if (!pnm_getc(file, ch)) return false; - } - while (ch >= '0' && ch <= '9'); - - return true; - } // end pnm_getuint() - -//---------------------------------------------------------------------- - -#if defined(V3DLIB_ENABLE_LIBPNG) - /* our method that reads from a FILE* and fills up the buffer that - libpng wants when parsing a PNG file */ - void - user_read_callback(png_structp png_ptr, png_bytep data, png_uint_32 length) - { - unsigned readlen = fread(data, 1, length, (FILE *)png_get_io_ptr(png_ptr)); - if (readlen != length) - { - /* FIXME: then what? png_error()? 20020821 mortene */ - } - } - - /* our method that write compressed png image data to a FILE* */ - void - user_write_callback(png_structp png_ptr, png_bytep data, png_uint_32 length) - { - unsigned writelen = fwrite(data, 1, length, (FILE *)png_get_io_ptr(png_ptr)); - if (writelen != length) - { - /* FIXME: then what? png_error()? 20020821 mortene */ - } - } - - /* our method that flushes written compressed png image data */ - void - user_flush_callback(png_structp png_ptr) - { - int err = fflush((FILE *)png_get_io_ptr(png_ptr)); - if (err != 0) - { - /* FIXME: then what? png_error()? 20020821 mortene */ - } - } -#endif // defined(V3DLIB_ENABLE_LIBPNG) - -//---------------------------------------------------------------------- - - enum ImageFileType - { - V3D_IMAGE_FILE_TYPE_UNKNOWN = -1, - V3D_IMAGE_FILE_TYPE_PNM = 0, - V3D_IMAGE_FILE_TYPE_JPEG = 1, - V3D_IMAGE_FILE_TYPE_PNG = 2, - }; - - inline ImageFileType - determineImageFileType(string const& fileName) - { - size_t extStart = fileName.find_last_of("./\\"); - if (extStart == fileName.npos || fileNameextStart != '.') - return V3D_IMAGE_FILE_TYPE_UNKNOWN; - - string const extension = fileName.substr(extStart+1); - if (extension == "jpg" || extension == "JPG" || - extension == "jpeg" || extension == "JPEG") return V3D_IMAGE_FILE_TYPE_JPEG; - - if (extension == "png" || extension == "PNG") return V3D_IMAGE_FILE_TYPE_PNG; - - if (extension == "ppm" || extension == "PPM" || - extension == "pgm" || extension == "PGM") return V3D_IMAGE_FILE_TYPE_PNM; - - return V3D_IMAGE_FILE_TYPE_UNKNOWN; - } // end determineImageFileType() - -} // end namespace <> - -namespace V3D -{ - - void - statImageFile(char const * fileName, ImageFileStat& stat) - { - ImageFileType fileType = determineImageFileType(std::string(fileName)); - switch (fileType) - { - case V3D_IMAGE_FILE_TYPE_PNM: - statPNMImageFile(fileName, stat); - return; -#if defined(V3DLIB_ENABLE_LIBJPEG) - case V3D_IMAGE_FILE_TYPE_JPEG: - statJPGImageFile(fileName, stat); - return; -#endif -#if defined(V3DLIB_ENABLE_LIBPNG) - case V3D_IMAGE_FILE_TYPE_PNG: - statPNGImageFile(fileName, stat); - return; -#endif - default: - throw Exception(__FILE__, __LINE__, "Unkown or unsupported image file extension."); - } // end switch() - } // end statImageFile() - - void - loadImageFile(char const * fileName, Image<unsigned char>& image) - { - ImageFileType fileType = determineImageFileType(std::string(fileName)); - switch (fileType) - { - case V3D_IMAGE_FILE_TYPE_PNM: - loadPNMImageFile(fileName, image); - return; -#if defined(V3DLIB_ENABLE_LIBJPEG) - case V3D_IMAGE_FILE_TYPE_JPEG: - loadJPGImageFile(fileName, image); - return; -#endif -#if defined(V3DLIB_ENABLE_LIBPNG) - case V3D_IMAGE_FILE_TYPE_PNG: - loadPNGImageFile(fileName, image); - return; -#endif - default: - throw Exception(__FILE__, __LINE__, "Unkown or unsupported image file extension."); - } // end switch() - } // end loadImageFile() - - void - saveImageFile(Image<unsigned char> const& image, char const * fileName) - { - cout << "Writing image to " << fileName << endl; - ImageFileType fileType = determineImageFileType(std::string(fileName)); - switch (fileType) - { - case V3D_IMAGE_FILE_TYPE_PNM: - savePNMImageFile(image, fileName); - return; -#if defined(V3DLIB_ENABLE_LIBJPEG) - case V3D_IMAGE_FILE_TYPE_JPEG: - saveJPGImageFile(image, fileName); - return; -#endif -#if defined(V3DLIB_ENABLE_LIBPNG) - case V3D_IMAGE_FILE_TYPE_PNG: - savePNGImageFile(image, fileName); - return; -#endif - default: - throw Exception(__FILE__, __LINE__, "Unkown or unsupported image file extension."); - } // end switch() - } // end saveImageFile() - - void - statPNMImageFile(char const * fileName, ImageFileStat& stat) - { - stat.width = stat.height = stat.numChannels = stat.bitDepth = -1; - - FILE * file = fopen(fileName, "rb"); - if (!file) throw Exception(__FILE__, __LINE__, "Cannot open PNM image file.");; - - int magic2; - magic0 = getc(file); - magic1 = getc(file); - - if (magic0 != 'P' && (magic1 != '5' || magic1 != '6')) - throw Exception(__FILE__, __LINE__, "Wrong or unsupported PNM magic number."); - - unsigned int width, height, maxVal; - if (!pnm_getuint(file, width)) throw Exception(__FILE__, __LINE__, "Cannot read PNM header."); - if (!pnm_getuint(file, height)) throw Exception(__FILE__, __LINE__, "Cannot read PNM header."); - if (!pnm_getuint(file, maxVal)) throw Exception(__FILE__, __LINE__, "Cannot read PNM header."); - - stat.numChannels = (magic1 == '5') ? 1 : 3; - stat.width = width; - stat.height = height; - stat.bitDepth = (maxVal > 255) ? 16 : 8; - - fclose(file); - } // end statPNMImageFile() - - void - loadPNMImageFile(char const * fileName, Image<unsigned char>& image) - { - FILE * file = fopen(fileName, "rb"); - if (!file) throw Exception(__FILE__, __LINE__, "Cannot open PNM image file."); - - int magic2; - magic0 = getc(file); - magic1 = getc(file); - - if (magic0 == 'P' && magic1 == '6') - { - unsigned int width, height, maxVal; - if (!pnm_getuint(file, width)) throw Exception(__FILE__, __LINE__, "Cannot read PNM header."); - if (!pnm_getuint(file, height)) throw Exception(__FILE__, __LINE__, "Cannot read PNM header."); - if (!pnm_getuint(file, maxVal)) throw Exception(__FILE__, __LINE__, "Cannot read PNM header."); - - if (maxVal > 255) // Does not fit in unsigned char - throw Exception(__FILE__, __LINE__, "PNM image file has unsupported bit depth."); - - image.resize(width, height, 3); - unsigned char * pixels = new unsigned charwidth*height*3; - - fread(pixels, width*height*3, 1, file); - - for (int y = 0; y < (int)height; ++y) - { - int const rowOfs = 3*width*y; - for (int x = 0; x < (int)width; ++x) - { - image(x, y, 0) = pixelsrowOfs + 3*x + 0; - image(x, y, 1) = pixelsrowOfs + 3*x + 1; - image(x, y, 2) = pixelsrowOfs + 3*x + 2; - } - } - - delete pixels; - } - else if (magic0 == 'P' && magic1 == '5') - { - unsigned int width, height, maxVal; - if (!pnm_getuint(file, width)) throw Exception(__FILE__, __LINE__, "Cannot read PNM header."); - if (!pnm_getuint(file, height)) throw Exception(__FILE__, __LINE__, "Cannot read PNM header."); - if (!pnm_getuint(file, maxVal)) throw Exception(__FILE__, __LINE__, "Cannot read PNM header."); - - if (maxVal > 255) // Does not fit in unsigned char - throw Exception(__FILE__, __LINE__, "PNM image file has unsupported bit depth."); - - image.resize(width, height, 1); - - fread(image.begin(), width*height, 1, file); - } - - fclose(file); - } // end loadPNMImageFile() - - void - savePNMImageFile(Image<unsigned char> const& image, char const * fileName) - { - int const width = image.width(); - int const height = image.height(); - int const nPlanes = image.numChannels(); - - if (nPlanes == 3) - { - unsigned char * pixels = new unsigned charwidth*height*3; - - for (int y = 0; y < height; ++y) - { - int const rowOfs = 3*width*y; - for (int x = 0; x < width; ++x) - { - pixelsrowOfs + 3*x + 0 = image(x, y, 0); - pixelsrowOfs + 3*x + 1 = image(x, y, 1); - pixelsrowOfs + 3*x + 2 = image(x, y, 2); - } - } - - FILE * file = fopen(fileName, "wb"); - if (!file) throw Exception(__FILE__, __LINE__, "Cannot open PNM image file for writing."); - - fprintf(file, "P6\n%i %i\n%i\n", width, height, 255); - fwrite(pixels, 3*width*height, 1, file); - fclose(file); - - delete pixels; - } - else if (nPlanes == 1) - { - FILE * file = fopen(fileName, "wb"); - fprintf(file, "P5\n%i %i\n%i\n", width, height, 255); - fwrite(image.begin(), width*height, 1, file); - fclose(file); - } - } // end savePNMImageFile() - -#if defined(V3DLIB_ENABLE_LIBJPEG) - void - statJPGImageFile(char const * fileName, ImageFileStat& stat) - { - stat.width = stat.height = stat.numChannels = stat.bitDepth = -1; - - struct jpeg_decompress_struct cinfo; - struct jpeg_error_mgr jerr; - - FILE * infile; /* source file */ - - if ((infile = fopen(fileName, "rb")) == NULL) - throw Exception(__FILE__, __LINE__, "Cannot open JPG image file."); - - cinfo.err = jpeg_std_error(&jerr); - - /* Now we can initialize the JPEG decompression object. */ - jpeg_create_decompress(&cinfo); - - jpeg_stdio_src(&cinfo, infile); - jpeg_read_header(&cinfo, TRUE); - - stat.width = cinfo.image_width; - stat.height = cinfo.image_height; - stat.numChannels = cinfo.num_components; - stat.bitDepth = 8; - - jpeg_destroy_decompress(&cinfo); - fclose(infile); - } // end statJPGImageFile() - - void - loadJPGImageFile(char const * fileName, Image<unsigned char>& image) - { - struct jpeg_decompress_struct cinfo; - struct jpeg_error_mgr jerr; - - FILE * infile; /* source file */ - JSAMPARRAY buffer; /* Output row buffer */ - int row_stride; /* physical row width in output buffer */ - - if ((infile = fopen(fileName, "rb")) == NULL) - throw Exception(__FILE__, __LINE__, "Cannot open JPG image file."); - - cinfo.err = jpeg_std_error(&jerr); - - /* Now we can initialize the JPEG decompression object. */ - jpeg_create_decompress(&cinfo); - - jpeg_stdio_src(&cinfo, infile); - jpeg_read_header(&cinfo, TRUE); - jpeg_start_decompress(&cinfo); - - int const nPlanes = cinfo.num_components; - int const w = cinfo.image_width; - int const h = cinfo.image_height; - image.resize(w, h, nPlanes); - - row_stride = w * nPlanes; - /* Make a one-row-high sample array that will go away when done with image */ - buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1); - - while ((int)cinfo.output_scanline < h) - { - int const y = cinfo.output_scanline; - /* jpeg_read_scanlines expects an array of pointers to scanlines. - * Here the array is only one element long, but you could ask for - * more than one scanline at a time if that's more convenient. - */ - jpeg_read_scanlines(&cinfo, buffer, 1); - - for (int x = 0; x < w; ++x) - for (int plane = 0; plane < nPlanes; ++plane) - image(x, y, plane) = buffer0nPlanes*x + plane; - } // end while - - jpeg_finish_decompress(&cinfo); - jpeg_destroy_decompress(&cinfo); - fclose(infile); - } // end loadJPGImageFile() - - void - saveJPGImageFile(Image<unsigned char> const& image, char const * fileName, int quality) - { - struct jpeg_compress_struct cinfo; - struct jpeg_error_mgr jerr; - FILE * outfile; /* target file */ - JSAMPROW row_pointer1; /* pointer to JSAMPLE rows */ - int row_stride; /* physical row width in image buffer */ - - int const w = image.width(); - int const h = image.height(); - int const nPlanes = image.numChannels(); - - cinfo.err = jpeg_std_error(&jerr); - /* Now we can initialize the JPEG compression object. */ - jpeg_create_compress(&cinfo); - - if ((outfile = fopen(fileName, "wb")) == NULL) - throw Exception(__FILE__, __LINE__, "Cannot open JPG image file for writing."); - - jpeg_stdio_dest(&cinfo, outfile); - - cinfo.image_width = w; /* image width and height, in pixels */ - cinfo.image_height = h; - cinfo.input_components = nPlanes; /* # of color components per pixel */ - if (nPlanes == 3) - cinfo.in_color_space = JCS_RGB; /* colorspace of input image */ - else - cinfo.in_color_space = JCS_GRAYSCALE; /* grayscale of input image */ - - jpeg_set_defaults(&cinfo); - jpeg_set_quality(&cinfo, quality, TRUE /* limit to baseline-JPEG values */); - jpeg_start_compress(&cinfo, TRUE); - row_stride = w * nPlanes; /* JSAMPLEs per row in image_buffer */ - - row_pointer0 = new unsigned charrow_stride; - - while (cinfo.next_scanline < cinfo.image_height) - { - /* jpeg_write_scanlines expects an array of pointers to scanlines. - * Here the array is only one element long, but you could pass - * more than one scanline at a time if that's more convenient. - */ - int const y = cinfo.next_scanline; - for (int x = 0; x < w; ++x) - for (int plane = 0; plane < nPlanes; ++plane) - row_pointer0nPlanes*x + plane = image(x, y, plane); - - jpeg_write_scanlines(&cinfo, row_pointer, 1); - } - - delete row_pointer0; - - jpeg_finish_compress(&cinfo); - fclose(outfile); - - jpeg_destroy_compress(&cinfo); - } // end saveJPGImageFile() - -#endif // #defined(V3DLIB_ENABLE_LIBJPEG) - -#if defined(V3DLIB_ENABLE_LIBPNG) - void - statPNGImageFile(char const * fileName, ImageFileStat& stat) - { - stat.width = stat.height = stat.numChannels = stat.bitDepth = -1; - - FILE *fp = fopen(fileName, "rb"); - if (!fp) throw Exception(__FILE__, __LINE__, "Cannot open PNG image file."); - - unsigned char header8; - png_uint_32 width, height; - int bit_depth, color_type, interlace_type; - - fread(header, 1, 8, fp); - bool is_png = !png_sig_cmp(header, 0, 8); - if (!is_png) throw Exception(__FILE__, __LINE__, "Cannot read PNG image header."); - - png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0); - - png_infop info_ptr = png_create_info_struct(png_ptr); - - /* we're not using png_init_io(), as we don't want to pass a FILE* - into libpng, in case it's an MSWindows DLL with a different CRT - (C run-time library) */ - - fseek(fp, 0, SEEK_SET); - png_set_read_fn(png_ptr, (void *)fp, (png_rw_ptr)user_read_callback); - /* The call to png_read_info() gives us all of the information from the - * PNG file before the first IDAT (image data chunk). REQUIRED - */ - png_read_info(png_ptr, info_ptr); - - png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, - &interlace_type, NULL, NULL); - - stat.width = width; - stat.height = height; - stat.bitDepth = bit_depth; - - switch (color_type) - { - case PNG_COLOR_TYPE_GRAY: - stat.numChannels = 1; - break; - case PNG_COLOR_TYPE_GRAY_ALPHA: - stat.numChannels = 2; - break; - case PNG_COLOR_TYPE_RGB: - stat.numChannels = 3; - break; - case PNG_COLOR_TYPE_RGB_ALPHA: - stat.numChannels = 4; - break; - default: - throw Exception(__FILE__, __LINE__, "Unsupported number of channels in PNG image file."); - } - png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); - - fclose(fp); - } // end statPNGImageFile() - - void - loadPNGImageFile(char const * fileName, Image<unsigned char>& image) - { - FILE *fp = fopen(fileName, "rb"); - if (!fp) throw Exception(__FILE__, __LINE__, "Cannot open PNG image file."); - - unsigned char header8; - png_uint_32 width, height; - int bit_depth, color_type, interlace_type; - - fread(header, 1, 8, fp); - bool is_png = !png_sig_cmp(header, 0, 8); - if (!is_png) throw Exception(__FILE__, __LINE__, "Cannot read PNG image header."); - - { - png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0); - - png_infop info_ptr = png_create_info_struct(png_ptr); - - /* we're not using png_init_io(), as we don't want to pass a FILE* - into libpng, in case it's an MSWindows DLL with a different CRT - (C run-time library) */ - - fseek(fp, 0, SEEK_SET); - png_set_read_fn(png_ptr, (void *)fp, (png_rw_ptr)user_read_callback); - /* The call to png_read_info() gives us all of the information from the - * PNG file before the first IDAT (image data chunk). REQUIRED - */ - png_read_info(png_ptr, info_ptr); - - png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, - &interlace_type, NULL, NULL); - - /* tell libpng to strip 16 bit/color files down to 8 bits/color */ - png_set_strip_16(png_ptr); - - /* expand paletted colors into true RGB triplets */ - if (color_type == PNG_COLOR_TYPE_PALETTE) - png_set_expand(png_ptr); - - /* expand grayscale images to the full 8 bits from 1, 2, or 4 bits/pixel */ - if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) - png_set_expand(png_ptr); - - /* expand paletted or RGB images with transparency to full alpha channels - * so the data will be available as RGBA quartets */ - if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) - png_set_expand(png_ptr); - - png_read_update_info(png_ptr, info_ptr); - - int nChannels = png_get_channels(png_ptr, info_ptr); - - image.resize(width, height, nChannels); - - int bytes_per_row = png_get_rowbytes(png_ptr, info_ptr); - - unsigned char * buffer = new unsigned charbytes_per_row * height; - - png_bytepp row_pointers = new png_bytepheight; - for (unsigned y = 0; y < height; y++) - row_pointersy = buffer + y*bytes_per_row; - - png_read_image(png_ptr, row_pointers); - png_read_end(png_ptr, info_ptr); - - delete row_pointers; - - png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); - fclose(fp); - - for (int chan = 0; chan < nChannels; ++chan) - { - unsigned char * p = image.begin(chan); - for (unsigned y = 0; y < height; ++y) - for (unsigned x = 0; x < width; ++x, ++p) - *p = buffery*bytes_per_row + nChannels*x + chan; - } - - delete buffer; - } // end scope - } // end loadImageFilePNG() - - void - savePNGImageFile(Image<unsigned char> const& image, char const * fileName) - { - /* open the file */ - FILE * fp = fopen(fileName, "wb"); - if (!fp) throw Exception(__FILE__, __LINE__, "Cannot open PNG image file for writing."); - - /* Create and initialize the png_struct with the desired error handler - * functions. If you want to use the default stderr and longjump method, - * you can supply NULL for the last three parameters. We also check that - * the library version is compatible with the one used at compile time, - * in case we are using dynamically linked libraries. REQUIRED. - */ - png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, - NULL, NULL, NULL); - - if (png_ptr == NULL) throw Exception(__FILE__, __LINE__, "Cannot create PNG structures for writing."); - - /* Allocate/initialize the image information data. REQUIRED */ - png_infop info_ptr = png_create_info_struct(png_ptr); - if (info_ptr == NULL) throw Exception(__FILE__, __LINE__, "Cannot create PNG structures for writing."); - - /* Set error handling. REQUIRED if you aren't supplying your own - * error hadnling functions in the png_create_write_struct() call. - */ -// if (setjmp(png_ptr->jmpbuf)) { -// /* If we get here, we had a problem reading the file */ -// fclose(fp); -// png_destroy_write_struct(&png_ptr, (png_infopp)info_ptr); -// pngerror = ERR_PNGLIB_WRITE; -// return 0; -// } - - /* we're not using png_init_io(), as we don't want to pass a FILE* - into libpng, in case it's an MSWindows DLL with a different CRT - (C run-time library) */ - png_set_write_fn(png_ptr, (void *)fp, (png_rw_ptr)user_write_callback, - (png_flush_ptr)user_flush_callback); - - /* Set the image information here. Width and height are up to 2^31, - * bit_depth is one of 1, 2, 4, 8, or 16, but valid values also depend on - * the color_type selected. color_type is one of PNG_COLOR_TYPE_GRAY, - * PNG_COLOR_TYPE_GRAY_ALPHA, PNG_COLOR_TYPE_PALETTE, PNG_COLOR_TYPE_RGB, - * or PNG_COLOR_TYPE_RGB_ALPHA. interlace is either PNG_INTERLACE_NONE or - * PNG_INTERLACE_ADAM7, and the compression_type and filter_type MUST - * currently be PNG_COMPRESSION_TYPE_BASE and PNG_FILTER_TYPE_BASE. REQUIRED - */ - - int colortype = PNG_COLOR_TYPE_RGB; - - unsigned const width = image.width(); - unsigned const height = image.height(); - unsigned const nChannels = image.numChannels(); - - switch (nChannels) - { - case 1: - colortype = PNG_COLOR_TYPE_GRAY; - break; - case 3: - colortype = PNG_COLOR_TYPE_RGB; - break; - case 4: - colortype = PNG_COLOR_TYPE_RGB_ALPHA; - break; - default: - png_destroy_write_struct(&png_ptr, (png_infopp)NULL); - throw Exception(__FILE__, __LINE__, "Unsupported number of channels for writing a PNG image file."); - } - - png_set_IHDR(png_ptr, info_ptr, width, height, 8, colortype, - PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); - - /* Optional gamma chunk is strongly suggested if you have any guess - * as to the correct gamma of the image. */ - /* png_set_gAMA(png_ptr, info_ptr, gamma); */ - - /* other optional chunks like cHRM, bKGD, tRNS, tIME, oFFs, pHYs, */ - - /* Write the file header information. REQUIRED */ - png_write_info(png_ptr, info_ptr); - - /* Once we write out the header, the compression type on the text - * chunks gets changed to PNG_TEXT_COMPRESSION_NONE_WR or - * PNG_TEXT_COMPRESSION_zTXt_WR, so it doesn't get written out again - * at the end. - */ - - /* set up the transformations you want. Note that these are - * all optional. Only call them if you want them. */ - - /* invert monocrome pixels */ - /* png_set_invert(png_ptr); */ - - /* Shift the pixels up to a legal bit depth and fill in - * as appropriate to correctly scale the image */ - /* png_set_shift(png_ptr, &sig_bit);*/ - - /* pack pixels into bytes */ - /* png_set_packing(png_ptr); */ - - /* swap location of alpha bytes from ARGB to RGBA */ - /* png_set_swap_alpha(png_ptr); */ - - /* Get rid of filler (OR ALPHA) bytes, pack XRGB/RGBX/ARGB/RGBA into - * RGB (4 channels -> 3 channels). The second parameter is not used. */ - /* png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE); */ - - /* flip BGR pixels to RGB */ - /* png_set_bgr(png_ptr); */ - - /* swap bytes of 16-bit files to most significant byte first */ - /* png_set_swap(png_ptr); */ - - /* swap bits of 1, 2, 4 bit packed pixel formats */ - /* png_set_packswap(png_ptr); */ - - - /* The easiest way to write the image (you may have a different memory - * layout, however, so choose what fits your needs best). You need to - * use the first method if you aren't handling interlacing yourself. - */ - - /* If you are only writing one row at a time, this works */ - - unsigned const bytesperrow = width * nChannels; - - if (nChannels != 1) - { - unsigned char * buffer = new unsigned charbytesperrow; - - for (unsigned y = 0; y < height; ++y) - { - for (unsigned chan = 0; chan < nChannels; ++chan) - { - unsigned char const * p = image.begin(chan) + y*width; - - for (unsigned x = 0; x < width; ++x, ++p) - bufferx*nChannels + chan = *p; - } - - png_write_row(png_ptr, (png_bytep)buffer); - } // end for (y) - - delete buffer; - } - else - { - // Faster path for grayscale images - for (unsigned y = 0; y < height; ++y) - png_write_row(png_ptr, (png_bytep)(image.begin() + y*width)); - } // end if - - /* You can write optional chunks like tEXt, zTXt, and tIME at the end - * as well. - */ - - /* It is REQUIRED to call this to finish writing the rest of the file */ - png_write_end(png_ptr, info_ptr); - - /* if you allocated any text comments, free them here */ - - /* clean up after the write, and free any memory allocated */ - png_destroy_write_struct(&png_ptr, &info_ptr); - - /* close the file */ - fclose(fp); - - /* that's it */ - } // end saveImageFilePNG() - -#endif // defined(V3DLIB_ENABLE_LIBPNG) - -} // end namespace V3D -
View file
slowmoVideo-0.4.tar.gz/src/V3D/Base/v3d_image.h
Deleted
@@ -1,278 +0,0 @@ -// -*- C++ -*- - -#include "config.h" - -#ifndef V3D_IMAGE_H -#define V3D_IMAGE_H - -#include <assert.h> -#include <math.h> -#include <algorithm> -#include <string> -#include <Base/v3d_exception.h> -#include <fstream> -#include <vector> -#include <stack> -#include <Math/v3d_linear.h> -#ifdef V3DLIB_ENABLE_IMDEBUG -# include <imdebug.h> -#endif - -namespace V3D -{ - - template <typename Elem> - struct Image - { - typedef Elem value_type; - typedef Elem const * const_iterator; - typedef Elem * iterator; - - Image() - : _width(0), _height(0), _nChannels(0), _planeSize(0), _data(0) - { } - - // (Deep) Copy constructor. I wanted this for use with STL - // in non-performance-critical code. - // Otherwise, please degenerate the copy constructor by - // declaring it private and not defining it. - Image( const Image<Elem> &im ) - : _width(0), _height(0), _nChannels(0), _planeSize(0), _data(0) - { - copyFrom(im); - } - - Image(int w, int h, int nChannels = 1) - : _width(w), _height(h), _nChannels(nChannels), _data(0) - { - _planeSize = w*h; - _data = new Elemw*h*nChannels; - } - - Image(int w, int h, int nChannels, Elem const& value) - : _width(w), _height(h), _nChannels(nChannels), _data(0) - { - _planeSize = w*h; - _data = new Elemw*h*nChannels; - std::fill(_data, _data+w*h*nChannels, value); - } - - ~Image() - { - if (_data) delete _data; - } - - Image<Elem>& operator=(Image<Elem> const& rhs) - { - this->copyFrom(rhs); - return *this; - } - - void resize(int w, int h, int nChannels = 1) - { - if(w==_width && h==_height && nChannels==_nChannels) - return; - if (_data) delete _data; - _width = w; - _height = h; - _nChannels = nChannels; - _planeSize = w*h; - _data = new Elemw*h*nChannels; - } - - void resize(int w, int h, int nChannels, Elem const& value) - { - this->resize(w, h, nChannels); - std::fill(_data, _data+w*h*nChannels, value); - } - - template <typename Elem2> - void copyFrom( const Image<Elem2> &im ) - { - resize(im.width(),im.height(),im.numChannels()); - for(int i = 0; i < (int)im.numChannels(); i++) - std::copy(im.begin(i),im.end(i),begin(i)); - } - - void fill( Elem val ) - { - std::fill(_data, _data+_width*_height*_nChannels, val); - } - - unsigned int width() const { return _width; } - unsigned int height() const { return _height; } - unsigned int numChannels() const { return _nChannels; } - - bool contains( int x, int y ) const - { - return x>=0 && x<_width && y>=0 && y<_height; - } - - Elem const& operator()(int x, int y, int channel = 0) const - { - return _datachannel*_planeSize + y*_width + x; - } - - Elem& operator()(int x, int y, int channel = 0) - { - return _datachannel*_planeSize + y*_width + x; - } - - const_iterator begin(int channel = 0) const { return _data + channel*_planeSize; } - iterator begin(int channel = 0) { return _data + channel*_planeSize; } - - const_iterator end(int channel = 0) const { return _data + (channel+1)*_planeSize; } - iterator end(int channel = 0) { return _data + (channel+1)*_planeSize; } - - Elem const& minElement(int chan = 0) const { return *min_element(this->begin(chan), this->end(chan)); } - Elem& minElement(int chan = 0) { return *min_element(this->begin(chan), this->end(chan)); } - - Elem const& maxElement(int chan = 0) const { return *max_element(this->begin(chan), this->end(chan)); } - Elem& maxElement(int chan = 0) { return *max_element(this->begin(chan), this->end(chan)); } - - protected: - int _width, _height, _nChannels, _planeSize; - Elem * _data; - }; // end struct Image - -//---------------------------------------------------------------------- - - struct ImageFileStat - { - unsigned width, height; - unsigned numChannels; - unsigned bitDepth; - }; // end struct ImageFileStat - - void statImageFile(char const * fileName, ImageFileStat& stat); - void loadImageFile(char const * fileName, Image<unsigned char>& image); - void saveImageFile(Image<unsigned char> const& image, char const * fileName); - - //! Reads PPM (P6) and PGM (P5) image files. - void statPNMImageFile(char const * fileName, ImageFileStat& stat); - void loadPNMImageFile(char const * fileName, Image<unsigned char>& image); - void savePNMImageFile(Image<unsigned char> const& image, char const * fileName); - -#if defined(V3DLIB_ENABLE_LIBJPEG) - void statJPGImageFile(char const * fileName, ImageFileStat& stat); - void loadJPGImageFile(char const * fileName, Image<unsigned char>& image); - void saveJPGImageFile(Image<unsigned char> const& image, char const * fileName, int quality = 85); -#endif - -#if defined(V3DLIB_ENABLE_LIBPNG) - void statPNGImageFile(char const * fileName, ImageFileStat& stat); - void loadPNGImageFile(char const * fileName, Image<unsigned char>& image); - void savePNGImageFile(Image<unsigned char> const& image, char const * fileName); -#endif - - inline void statDataImageFile(const char *filename, ImageFileStat &stat) - { - std::ifstream in(filename,std::ios_base::binary|std::ios_base::in); - verify(in.is_open(),"Failed to open image data file."); - in.read((char*)&stat.width,sizeof(unsigned int)); - in.read((char*)&stat.height,sizeof(unsigned int)); - in.read((char*)&stat.numChannels,sizeof(unsigned int)); - in.read((char*)&stat.bitDepth,sizeof(unsigned int)); - } - - template<typename Elem> - void loadDataImageFile(const char *filename, Image<Elem> &image) - { - // Stat file. - ImageFileStat stat; - unsigned int type; - std::ifstream in(filename,std::ios_base::binary|std::ios_base::in); - verify(in.is_open(),"Failed to open image data file."); - in.read((char*)&stat.width,sizeof(unsigned int)); - in.read((char*)&stat.height,sizeof(unsigned int)); - in.read((char*)&stat.numChannels,sizeof(unsigned int)); - in.read((char*)&stat.bitDepth,sizeof(unsigned int)); - in.read((char*)&type,sizeof(unsigned int)); - // TODO: Create a mechanism for getting a type constant. - // Then type can be verified exactly. - // Verify bit depth of type. - verify(sizeof(Elem)*8==stat.bitDepth,"Image data incompatible with type."); - // Read image. - image.resize(stat.width,stat.height,stat.numChannels); - in.read((char*)&image(0,0,0),sizeof(Elem)*stat.width*stat.height*stat.numChannels); - } - - template<typename Elem> - void saveDataImageFile(const Image<Elem> &image, const char *filename) - { - // Open file. - std::ofstream out(filename,std::ios_base::out|std::ios_base::binary); - verify(out.is_open(),"Failed to open iamge data file."); - // Write image stat. - ImageFileStat stat; - stat.width = image.width(); - stat.height = image.height(); - stat.numChannels = image.numChannels(); - stat.bitDepth = sizeof(Elem)*8; - // TODO: Create a mechanism for getting a type constant. - // Then type can be stored exactly. - unsigned int type = 0xffffffff; - out.write((char*)&stat.width,sizeof(unsigned int)); - out.write((char*)&stat.height,sizeof(unsigned int)); - out.write((char*)&stat.numChannels,sizeof(unsigned int)); - out.write((char*)&stat.bitDepth,sizeof(unsigned int)); - out.write((char*)&type,sizeof(unsigned int)); - // Write image data. - out.write((char*)&image(0,0,0),sizeof(Elem)*image.width()*image.height()*image.numChannels()); - } - - template <typename Elem> - inline void - saveImageChannel(Image<Elem> const& im, int channel, Elem minVal, Elem maxVal, char const * name) - { - int const w = im.width(); - int const h = im.height(); - - Elem const len = maxVal - minVal; - Image<unsigned char> byteIm(w, h, 1); - - for (int y = 0; y < h; ++y) - for (int x = 0; x < w; ++x) - { - Elem c = std::max(Elem(0), std::min(Elem(255), Elem(255) * (im(x, y, channel) - minVal) / len)); - byteIm(x, y) = int(c); - } - - saveImageFile(byteIm, name); - } // end saveImageChannel() - - template <typename Elem> - inline void - saveImageChannel(Image<Elem> const& im, int channel, char const * name) - { - int const w = im.width(); - int const h = im.height(); - - if (w == 0 || h == 0) return; - - Elem minVal = im(0, 0, channel); - Elem maxVal = minVal; - - for (int y = 0; y < h; ++y) - for (int x = 0; x < w; ++x) - { - minVal = std::min(minVal, im(x, y, channel)); - maxVal = std::max(maxVal, im(x, y, channel)); - } - - saveImageChannel(im, channel, minVal, maxVal, name); - } // end saveImageChannel() - - template <typename Elem> - inline void - copyImageChannel(Image<Elem> const& im, int channel, Image<Elem> &out) - { - out.resize(im.width(),im.height(),1); - for(int y=0; y<im.height(); y++) - for(int x=0; x<im.width(); x++) - out(x,y) = im(x,y,channel); - } - -} // end namespace V3D - -#endif
View file
slowmoVideo-0.4.tar.gz/src/V3D/Base/v3d_imageprocessing.h
Deleted
@@ -1,854 +0,0 @@ -// -*- C++ -*- - -#include "config.h" - -#ifndef V3D_IMAGEPROCESSING_H -#define V3D_IMAGEPROCESSING_H - -#include "v3d_image.h" -#include "Math/v3d_linear.h" - -namespace V3D { - - template <typename Elem, typename Elem2> - Elem2 bilinearSample( const Image<Elem> &im, Elem2 x, Elem2 y, int c=0 ) - { - int x0 = floor(x); - int y0 = floor(y); - Elem2 xf = x-x0; - Elem2 yf = y-y0; - return (1-yf)*(1-xf)*im(x0 ,y0 ,c) + - (1-yf)*( xf)*im(x0+1,y0 ,c) + - ( yf)*(1-xf)*im(x0 ,y0+1,c) + - ( yf)*( xf)*im(x0+1,y0+1,c); - } - - template <typename Elem, typename Elem2> - Elem2 bilinearSampleBorder( const Image<Elem> &im, Elem2 x, Elem2 y, int c=0, - Elem2 border = 0 ) - { - int x0 = floor(x); - int y0 = floor(y); - Elem2 xf = x-x0; - Elem2 yf = y-y0; - if(x0>=0 && x0+1<im.width() && y0>=0 && y0+1<im.height()) { - return (1-yf)*(1-xf)*im(x0 ,y0 ,c) + - (1-yf)*( xf)*im(x0+1,y0 ,c) + - ( yf)*(1-xf)*im(x0 ,y0+1,c) + - ( yf)*( xf)*im(x0+1,y0+1,c); - } else { - return border; - } - } - - template<typename Elem, typename Elem2, typename Elem3> - inline void - convolveImage( const Image<Elem> &im, const Image<Elem2> &kernel, Image<Elem3> &out ) - { - // NOTE: This code could be much more optimized. - - verify(im.width() >= kernel.width(),"image must be larger than kernel"); - verify(im.height() >= kernel.height(),"image must be larger than kernel"); - verify(im.numChannels() == kernel.numChannels(),"number of channels must be the same"); - - if (out.width() != im.width() || - out.height() != im.height() || - out.numChannels() != im.numChannels()) - out.resize(im.width(), im.height(), im.numChannels()); - - int xx0, xx1, yy0, yy1, kx, ky, kx0, ky0; - Elem2 sum, denom; - - for (int ch = 0; ch < im.numChannels(); ++ch) - { - for(int y = 0; y < im.height(); ++y) - { - yy0 = y - kernel.height()/2; - yy1 = yy0 + kernel.height(); - yy0 = std::max(yy0, 0); - yy1 = std::min(yy1, int(im.height())); - - ky0 = yy0 - y + kernel.height()/2; - - for(int x = 0; x < im.width(); ++x) - { - xx0 = x - kernel.width()/2; - xx1 = xx0 + kernel.width(); - xx0 = std::max(xx0, 0); - xx1 = std::min(xx1, int(im.width())); - - kx0 = xx0 - x + kernel.width()/2; - - sum = 0; denom = 0; - for(int yy = yy0, ky = ky0; yy < yy1; ++yy, ++ky) { - for(int xx = xx0, kx = kx0; xx < xx1; ++xx, ++kx) - { - sum += im(xx, yy, ch) * kernel(kx, ky, ch); - denom += kernel(kx, ky, ch); - } - } - out(x, y, ch) = (Elem3)(sum / denom); - } // end for (x) - } // end for (y) - } // end for (ch) - } // end convolveImage() - - inline int choose(int n, int k) - { - if (k > n) - return 0; - - if (k > n/2) - k = n-k; // faster - - double accum = 1; - for (int i = 1; i <= k; i++) - accum = accum * (n-k+i) / i; - - return (int)(accum + 0.5); // avoid rounding error - } - - template<typename Elem> - inline void - boxFilterImage( const Image<Elem> &im, int boxWidth, int boxHeight, - Image<Elem> &out, Image<Elem>& temp) - { - int x,y; - int halfw = boxWidth/2; - int halfh = boxHeight/2; - double sum,weight; - temp.resize(im.width(),im.height()); - out.resize(im.width(),im.height(),im.numChannels()); - for(int i=0; i<im.numChannels(); i++) { - // Horizontal. - for(y=0; y<im.height(); y++) { - sum = 0; - weight = 0; - for(x=0; x<halfw; x++) { - sum += im(x,y,i); - weight++; - } - for(x=halfw; x<2*halfw+1; x++) { - sum += im(x,y,i); - weight++; - temp(x-halfw,y) = (Elem)(sum/weight); - } - for(x=halfw+1; x<im.width()-halfw; x++) { - sum -= im(x-halfw-1,y,i); - sum += im(x+halfw,y,i); - temp(x,y) = sum/weight; - } - for(; x<im.width(); x++) { - sum -= im(x-halfw-1,y,i); - weight--; - temp(x,y) = sum/weight; - } - } - // Vertical. - for(x=0; x<im.width(); x++) { - sum = 0; - weight = 0; - for(y=0; y<halfh; y++) { - sum += temp(x,y); - weight++; - } - for(y=halfh; y<2*halfh+1; y++) { - sum += temp(x,y); - weight++; - out(x,y-halfh,i) = (Elem)(sum/weight); - } - for(y=halfh+1; y<im.height()-halfh; y++) { - sum -= temp(x,y-halfh-1); - sum += temp(x,y+halfh); - out(x,y,i) = sum/weight; - } - for(; y<im.height(); y++) { - sum -= temp(x,y-halfh-1); - weight--; - out(x,y,i) = sum/weight; - } - } - } - } - - template<typename Elem> - inline void - boxFilterImage( const Image<Elem> &im, int boxWidth, int boxHeight, Image<Elem> &out) - { - Image<Elem> temp; - boxFilterImage(im, boxWidth, boxHeight, out, temp); - } - - // Note: boxWidth and boxHeight must be odd - template<typename Elem> - inline void - boxFilterImage_fast(Image<Elem> const& im, int boxWidth, int boxHeight, - Image<Elem>& out, Image<Elem>& temp) - { - int const w = im.width(); - int const h = im.height(); - int const nChannels = im.numChannels(); - - int const W2 = boxWidth/2; - int const H2 = boxHeight/2; - - Elem const WH = boxWidth*boxHeight; - - temp.resize(w, h, 1); - out.resize(w, h, nChannels); - - std::vector<Elem> row(w+boxWidth); - - for (int ch = 0; ch < nChannels; ++ch) - { - // Horizontal pass - for (int y = 0; y < h; ++y) - { - for (int x = 0; x < W2; ++x) rowx = im(0, y, ch); - for (int x = 0; x < w; ++x) rowx+W2 = im(x, y, ch); - for (int x = 0; x < W2; ++x) roww+x = im(w-1, y, ch); - - Elem sum = 0; - for (int x = 0; x < boxWidth; ++x) sum += rowx; - for (int x = 0; x < w-1; ++x) - { - temp(x, y) = sum; - sum -= rowx; - sum += rowx+boxWidth; - } - temp(w-1, y) = sum; - } // end for (y) - - // Vertical pass - for (int x = 0; x < w; ++x) rowx = (H2+1)*temp(x, 0); - for (int dy = 1; dy <= H2; ++dy) - for (int x = 0; x < w; ++x) rowx += temp(x, dy); - for (int y = 0; y < h; ++y) - { - int const Y0 = std::max(0, y-H2); - int const Y1 = std::min(h-1, y+H2+1); - - for (int x = 0; x < w; ++x) - { - out(x, y, ch) = rowx / WH; - rowx -= temp(x, Y0); - rowx += temp(x, Y1); - } // end for (x) - } // end for (y) - } // end for (ch) - } // end boxFilterImage_fast() - - template<typename Elem> - inline void - boxFilterImage_fast(Image<Elem> const& im, int boxWidth, int boxHeight, Image<Elem> &out) - { - Image<Elem> temp; - boxFilterImage_fast(im, boxWidth, boxHeight, out, temp); - } - - template <typename Elem, typename BinaryFunc> - inline void - boxFilterImage_fast(Image<Elem> const &im1, Image<Elem> const& im2, int boxWidth, int boxHeight, - BinaryFunc op, Image<Elem>& out, Image<Elem>& temp, Image<Elem>& temp2) - { - int const w = im1.width(); - int const h = im2.height(); - - temp2.resize(w, h, im1.numChannels()); - - for (int ch = 0; ch < im1.numChannels(); ++ch) - { - for (int y = 0; y < h; ++y) - for (int x = 0; x < w; ++x) - temp2(x, y, ch) = op(im1(x, y, ch), im2(x, y, ch)); - } - - boxFilterImage_fast(temp2, boxWidth, boxHeight, out, temp); - } // end boxFilterImage_fast() - - template <typename Elem, typename BinaryFunc> - inline void - boxFilterImage_fast(Image<Elem> const& im1, Image<Elem> const& im2, - int boxWidth, int boxHeight, BinaryFunc op, Image<Elem>& out) - { - Image<Elem> temp, temp2; - boxFilterImage_fast(im1, im2, boxWidth, boxHeight, op, out, temp, temp2); - } - - - template<typename Elem> - inline void binomialFilterImage( const Image<Elem> &im, int Nx, int Ny, Image<Elem> &out, - Image<Elem>& temp ) - { - // TODO: Use factored binomial kernels for better speed. - Image<float> kernelX(Nx+1,1,im.numChannels()); - Image<float> kernelY(1,Ny+1,im.numChannels()); - int x,y,i; - for(i=0; i<im.numChannels(); i++) - { - for(x=0; x<=Nx; x++) - kernelX(x,0,i) = (float)choose(Nx,x)/(float)(1<<Nx); - for(y=0; y<=Ny; y++) - kernelY(0,y,i) = (float)choose(Ny,y)/(float)(1<<Ny); - } - convolveImage(im,kernelX,temp); - convolveImage(temp,kernelY,out); - } - - template<typename Elem> - inline void - binomialFilterImage( const Image<Elem> &im, int Nx, int Ny, Image<Elem> &out) - { - Image<Elem> temp; - binomialFilterImage(im, Nx, Ny, out, temp); - } - - template<typename Elem> - void meanFilterImage( const Image<Elem> &in, int w, int h, Image<Elem> &out, - Elem bias, Image<Elem>& temp) - { - boxFilterImage(in,w,h,out,temp); - for(int i=0; i<in.numChannels(); i++) - for(int y=0; y<in.height(); y++) - for(int x=0; x<in.width(); x++) - out(x,y,i) = in(x,y,i) - out(x,y,i) + bias; - } - - template<typename Elem> - void meanFilterImage( const Image<Elem> &in, int w, int h, Image<Elem> &out, - Elem bias = 0) - { - Image<Elem> temp; - meanFilterImage(in, w, h, out, bias, temp); - } - - template<typename Elem,typename Elem2> - void rankFilterImage( const Image<Elem> &in, int w, int h, Image<Elem2> &out ) - { - out.resize(in.width(),in.height(),in.numChannels()); - w = (w/2)*2+1; - h = (h/2)*2+1; - for(int i=0; i<in.numChannels(); i++) { - for(int y=0; y<in.height(); y++) { - for(int x=0; x<in.width(); x++) { - int xx0 = max(0,x-w/2); - int xx1 = min<int>(in.width()-1,x+w/2); - int yy0 = max(0,y-h/2); - int yy1 = min<int>(in.height()-1,y+h/2); - out(x,y,i) = 0; - for(int xx=xx0; xx<=xx1; xx++) { - for(int yy=yy0; yy<=yy1; yy++) { - if(in(x,y,i) > in(xx,yy,i)) - out(x,y,i)++; - } - } - out(x,y,i) = double(out(x,y,i)) * w*h / ((xx1-xx0+1)*(yy1-yy0+1)); - } - } - } - } - - template<typename Elem, typename Elem2> - void resampleImage( const Image<Elem> &im, Image<Elem2> &out ) - { - // TODO: Apply low-pass filter if downsampling. - Image<Elem> im2(im.width(),im.height(),im.numChannels()); - binomialFilterImage(im,0,0,im2); - - verify(im.numChannels()==out.numChannels(),"number of channels must be the same"); - - for(int y=0; y<out.height(); y++) { - for(int x=0; x<out.width(); x++) { - for(int i=0; i<out.numChannels(); i++) { - float xp = (float)(x+0.5f)*im.width()/out.width()-0.5f; - int xx = floor(xp); - float xf = xp-xx; - float yp = (float)(y+0.5f)*im.height()/out.height()-0.5f; - int yy = floor(yp); - float yf = yp-yy; - if(xx<0) { - xx = 0; - xf = 0; - } - if(xx==im.width()-1) { - xf = 0; - } - if(yy<0) { - yy = 0; - yf = 0; - } - if(yy==im.height()-1) { - yf = 0; - } - out(x,y,i) = (1-xf)*(1-yf)*im2(xx ,yy ,i) + - ( xf)*(1-yf)*im2(xx+1,yy ,i) + - (1-xf)*( yf)*im2(xx ,yy+1,i) + - ( xf)*( yf)*im2(xx+1,yy+1,i); - } - } - } - } - - template<typename Elem> - void floodFill( Image<Elem> &im, int x0, int y0, Elem val ) - { - Elem initval = im(x0,y0); - if(initval==val) - return; - int imw = im.width(); - int imh = im.height(); - std::stack<std::pair<int,int> > flood; - flood.push(std::pair<int,int>(x0,y0)); - while(!flood.empty()) { - int x = flood.top().first; - int y = flood.top().second; - flood.pop(); - //if(x>=0 && x<imw && y>=0 && y<imh && im(x,y)==initval) { - im(x,y) = val; - if(x<imw-1 && im(x+1,y)==initval) - flood.push(std::pair<int,int>(x+1,y)); - if(x>0 && im(x-1,y)==initval) - flood.push(std::pair<int,int>(x-1,y)); - if(y<imh-1 && im(x,y+1)==initval) - flood.push(std::pair<int,int>(x,y+1)); - if(y>0 && im(x,y-1)==initval) - flood.push(std::pair<int,int>(x,y-1)); - //} - } - } - -//========================================================================= - - template<class Elem> - class ImagePyramid - { - public: - ImagePyramid() {} - - void resize( int w, int h, int channels, int levels ) - { - _levels.resize(levels); - for(int i=0; i<levels; i++) - _levelsi.resize(w>>i,h>>i,channels); - } - - void generate( const Image<Elem> &im, int levels ) - { - // Copy base level. - _levels.resize(levels); - _levels0.copyFrom(im); - // Build pyramid. - for(int i=1; i<_levels.size(); i++) { - _levelsi.resize(im.width()>>i,im.height()>>i,im.numChannels()); - for(int y=0; y<_levelsi.height(); y++) { - for(int x=0; x<_levelsi.width(); x++) { - for(int c=0; c<_levelsi.numChannels(); c++) { - _levelsi(x,y,c) = (Elem) - (((double)_levelsi-1(2*x+0,2*y+0,c) + - (double)_levelsi-1(2*x+1,2*y+0,c) + - (double)_levelsi-1(2*x+0,2*y+1,c) + - (double)_levelsi-1(2*x+1,2*y+1,c)) / 4); - } // channels - } // x - } // y - } // levels - } - - const Image<Elem> &level( int l ) const { return _levelsl; } - Image<Elem> &level( int l ) { return _levelsl; } - int numLevels() const { return _levels.size(); } - - private: - vector<Image<Elem> > _levels; - }; - - template<class Elem> - Elem warpMipmapTrilinear( const ImagePyramid<Elem> &in, - const Matrix3x3d &H, - int x, - int y, - int c = 1 ) - // TODO: Make this function able to return values for all channels in one call. - { - float area,level; - float mx0,my0,mx1,my1; - int xx0,yy0,xx1,yy1,ll; - float u0,v0,u1,v1,w; - - // TODO: Replace this code with derivative-based scale selection. - // Warp pixel corners and pixel center. - Vector3d m00 = H*Vector3d(x+0.0,y+0.0,1); - m00 = 1.0/m002 * m00; - Vector3d m01 = H*Vector3d(x+1.0,y+0.0,1); - m01 = 1.0/m012 * m01; - Vector3d m10 = H*Vector3d(x+0.0,y+1.0,1); - m10 = 1.0/m102 * m10; - Vector3d m11 = H*Vector3d(x+1.0,y+1.0,1); - m11 = 1.0/m112 * m11; - Vector3d m = H*Vector3d(x+0.5,y+0.5,1); - m = 1.0/m2 * m; - // Measure area of projected pixel (bounding box). - area = (max(max(m000,m010),max(m100,m110)) - min(min(m000,m010),min(m100,m110)))* - (max(max(m001,m011),max(m101,m111)) - min(min(m001,m011),min(m101,m111))); - // Compute pyramid level. 2^(2*level)=area -> level=log2(area)/2 - level = 0.5f*log(area)/log(2.0f); - level = max(min(level,(float)in.numLevels()-2.0f),0.0f); - - // Find pixels in pyramid. - ll = (int)level; - mx0 = m0/(1<<ll)-0.5f; - my0 = m1/(1<<ll)-0.5f; - mx1 = m0/(2<<ll)-0.5f; - my1 = m1/(2<<ll)-0.5f; - xx0 = (int)(floor(mx0)); - yy0 = (int)(floor(my0)); - xx1 = (int)(floor(mx1)); - yy1 = (int)(floor(my1)); - // Border handling (hack for now). - if(xx0<0 || xx1<0 || yy0<0 || yy1<0 || - xx0>=in.level(ll).width()-1 || xx1>=in.level(ll+1).width()-1 || - yy0>=in.level(ll).height()-1 || yy1>=in.level(ll+1).height()-1 || - ll<0 || ll>=in.numLevels()-1) - { - return (float)(rand()%256); - } - // Compute trilinear coefficients. - u0 = mx0-xx0; - v0 = my0-yy0; - u1 = mx1-xx1; - v1 = my1-yy1; - w = level-ll; - // Compute trilinear interpolation. - //return mx1; - //return in.level(ll)(xx0,yy0); - //return in.level(0)yx; - return (1-u0)*(1-v0)*(1-w)*in.level(ll )(xx0 ,yy0 ,c) + //yy0 xx0 + - ( u0)*(1-v0)*(1-w)*in.level(ll )(xx0+1,yy0 ,c) + //yy0 xx0+1 + - (1-u0)*( v0)*(1-w)*in.level(ll )(xx0 ,yy0+1,c) + //yy0+1xx0 + - ( u0)*( v0)*(1-w)*in.level(ll )(xx0+1,yy0+1,c) + //yy0+1xx0+1 + - (1-u1)*(1-v1)*( w)*in.level(ll+1)(xx1 ,yy1 ,c) + //yy1 xx1 + - ( u1)*(1-v1)*( w)*in.level(ll+1)(xx1+1,yy1 ,c) + //yy1 xx1+1 + - (1-u1)*( v1)*( w)*in.level(ll+1)(xx1 ,yy1+1,c) + //yy1+1xx1 + - ( u1)*( v1)*( w)*in.level(ll+1)(xx1+1,yy1+1,c); //yy1+1xx1+1; - } - - template<class Elem> - Elem warpBilinear( const ImagePyramid<Elem> &in, - const Matrix3x3d &H, - int x, - int y, - int c = 1 ) - { - Vector3d m = H*Vector3d(x+0.5,y+0.5,1); - /*Vector3d m; - m0 = H00*x + H01*y + H02; - m1 = H10*x + H11*y + H12; - m2 = H20*x + H21*y + H22;*/ - m = 1.0/m2 * m; - m0 -= 0.5; - m1 -= 0.5; - int xx0 = (int)(floor(m0)); - int yy0 = (int)(floor(m1)); - double u0 = m0-xx0; - double v0 = m1-yy0; - if(xx0<0 || yy0<0 || - xx0>=in.level(0).width()-1 || yy0>=in.level(0).height()-1) - { - return (float)(rand()%256); - } - return (1-u0)*(1-v0)*in.level(0)(xx0 ,yy0 ,c) + //yy0 xx0 + - ( u0)*(1-v0)*in.level(0)(xx0+1,yy0 ,c) + //yy0 xx0+1 + - (1-u0)*( v0)*in.level(0)(xx0 ,yy0+1,c) + //yy0+1xx0 + - ( u0)*( v0)*in.level(0)(xx0+1,yy0+1,c); //yy0+1xx0+1 + - } - - template<class Elem> - void warpImageBilinear( Image<Elem> &out, - const ImagePyramid<Elem> &in, - const Matrix3x3d &H ) - { - for(int y=0; y<out.height(); y++) - for(int x=0; x<out.width(); x++) - for(int c=0; c<out.numChannels(); c++) - out(x,y,c) = warpBilinear(in,H,x,y,c); - } - - template<class Elem> - void warpImageMipmapTrilinear( Image<Elem> &out, - const ImagePyramid<Elem> &in, - const Matrix3x3d &H ) - { - for(int y=0; y<out.height(); y++) - for(int x=0; x<out.width(); x++) - for(int c=0; c<out.numChannels(); c++) - out(x,y,c) = warpMipmapTrilinear(in,H,x,y,c); - } - -//====================================================================== - - template<typename Elem> - void convertRGBToGrayscale( const Image<Elem> &rgb, Image<Elem> &gray, - double rf=0.3, double gf=0.59, double bf=0.11 ) - { - // Ensure output size. - if(rgb.width()!=gray.width() || rgb.height()!=gray.height()) - gray.resize(rgb.width(),rgb.height(),1); - // Convert. - int x,y; - for(y=0; y<rgb.height(); y++) { - for(x=0; x<rgb.width(); x++) { - Elem r = rgb(x,y,0); - Elem g = rgb(x,y,1); - Elem b = rgb(x,y,2); - gray(x,y) = (Elem)(r*rf+g*gf+b*bf); - } - } - } - - template<typename Elem> - void convertRGBToRGBInterleaved( const Image<Elem> &rgb, Elem *rgbI, - int sizeBytes ) - { - verify(sizeBytes>=rgb.width()*rgb.height()*3*sizeof(Elem),"Buffer too small."); - int x,y; - for(y=0; y<rgb.height(); y++) { - for(x=0; x<rgb.width(); x++) { - int i = y*rgb.width()*3 + x*3; - rgbIi+0 = rgb(x,y,0); - rgbIi+1 = rgb(x,y,1); - rgbIi+2 = rgb(x,y,2); - } - } - } - - template<typename Elem> - void convertToUchar( const Image<Elem> &in, Image<unsigned char> &out, - double scale = 0.0, double bias = 0 ) - { - if(scale==0.0) { // auto scale - Elem maxval = *std::max_element(in.begin(0),in.end(in.numChannels()-1)); - scale = 255.0/(double)maxval; - } - if(in.width()!=out.width() || in.height()!=out.height() - || in.numChannels()!=out.numChannels()) - { - out.resize(in.width(),in.height(),in.numChannels()); - } - int x,y,c; - for(y=0; y<in.height(); y++) { - for(x=0; x<in.width(); x++) { - for(c=0; c<in.numChannels(); c++) { - double val = ((double)in(x,y,c)+bias)*scale; - out(x,y,c) = (unsigned char)std::min(std::max(val,0.0),255.0); - } - } - } - } - - template<typename Elem, typename Elem2, int channels> - void convertIndexedImage( const Image<Elem> &in, - const std::vector<InlineVector<Elem2,channels> > &map, - Image<Elem2> &out ) - { - if(in.width()!=out.width() || in.height()!=out.height() - || channels!=out.numChannels()) - { - out.resize(in.width(),in.height(),channels); - } - int x,y,c; - for(y=0; y<in.height(); y++) { - for(x=0; x<in.width(); x++) { - int i = in(x,y); - while(i<0) - i += map.size(); - i = i % map.size(); - for(c=0; c<channels; c++) { - out(x,y,c) = mapic; - } - } - } - } - -//====================================================================== - - // RGB values are expected to be in 0, 1 - inline Vector3f - convertRGBPixelToYUV(Vector3f const& rgb) - { - float const Wr = 0.299f; - float const Wb = 0.114f; - float const Wg = 1.0f - Wr - Wb; - - Vector3f yuv; - yuv0 = Wr*rgb0 + Wg*rgb1 + Wb*rgb2; - yuv1 = 0.436f * (rgb2 - yuv0)/(1.0f - Wb); - yuv2 = 0.615f * (rgb0 - yuv0)/(1.0f - Wr); - return yuv; - } - - inline void - convertRGBImageToYUV(Image<unsigned char> const& src, Image<float>& dst) - { - int const w = src.width(); - int const h = src.height(); - dst.resize(w, h, 3); - - Vector3f rgb, yuv; - - for (int y = 0; y < h; ++y) - for (int x = 0; x < w; ++x) - { - rgb0 = src(x, y, 0) / 255.0f; - rgb1 = src(x, y, 1) / 255.0f; - rgb2 = src(x, y, 2) / 255.0f; - yuv = convertRGBPixelToYUV(rgb); - dst(x, y, 0) = yuv0; - dst(x, y, 1) = yuv1; - dst(x, y, 2) = yuv2; - } - } // end convertRGBImageToYUV() - - // RGB values are expected to be in 0, 1, S and L results are in 0, 1 - inline Vector3f - convertRGBPixelToHSL(Vector3f const& rgb) - { - Vector3f hsl; - float const r = rgb0; - float const g = rgb1; - float const b = rgb2; - float h = 0.0f, s = 0.0f; - - float const minimum = std::min(std::min(r, g), b); - float const maximum = std::max(std::max(r, g), b); - float const delta = maximum - minimum; - float const l = (minimum+maximum)/2; - - if (delta > 0) - { - s = (l <= 0.5f) ? (delta / (2*l)) : (delta / (2.0f - 2*l)); - } - - if (delta > 0) - { - if (r == maximum) - h = (g - b) / delta; - else if (g == maximum) - h = 2 + (b - r) / delta; - else if (b == maximum) - h = 4 + (r - g) / delta; - } - h *= 60; - if (h < 0) h += 360; - - h /= 255.0f; - - hsl0 = h; hsl1 = s; hsl2 = l; - return hsl; - } - - inline void - convertRGBImageToHSL(Image<unsigned char> const& src, Image<float>& dst) - { - int const w = src.width(); - int const h = src.height(); - dst.resize(w, h, 3); - - Vector3f rgb, hsl; - - for (int y = 0; y < h; ++y) - for (int x = 0; x < w; ++x) - { - rgb0 = src(x, y, 0) / 255.0f; - rgb1 = src(x, y, 1) / 255.0f; - rgb2 = src(x, y, 2) / 255.0f; - hsl = convertRGBPixelToHSL(rgb); - dst(x, y, 0) = hsl0; - dst(x, y, 1) = hsl1; - dst(x, y, 2) = hsl2; - } - } // end convertRGBImageToHSL() - - // RGB values are expected to be in 0, 1 - inline Vector3f - convertRGBPixelTo_sRGB(Vector3f const& rgb) - { - float const th = 0.04045; - Vector3f srgb; - srgb0 = (rgb0 < th) ? (rgb0 / 12.92f) : powf((rgb0 + 0.055f) / 1.055f, 2.4f); - srgb1 = (rgb1 < th) ? (rgb1 / 12.92f) : powf((rgb1 + 0.055f) / 1.055f, 2.4f); - srgb2 = (rgb2 < th) ? (rgb2 / 12.92f) : powf((rgb2 + 0.055f) / 1.055f, 2.4f); - return srgb; - } - - inline Vector3f - convert_sRGBPixelToXYZ(Vector3f const& srgb) - { - float const R = srgb0, G = srgb1, B = srgb2; - - Vector3f xyz; - xyz0 = (float) (R * 0.412424 + G * 0.357579 + B * 0.180464); - xyz1 = (float) (R * 0.212656 + G * 0.715158 + B * 0.072186); - xyz2 = (float) (R * 0.019332 + G * 0.119193 + B * 0.950444); - return xyz; - } // end convertRGBPixelToXYZ() - - // RGB values are expected to be in 0, 1 - inline Vector3f - convertRGBPixelToXYZ(Vector3f const& rgb) - { - Vector3f srgb = convertRGBPixelTo_sRGB(rgb); - return convert_sRGBPixelToXYZ(srgb); - } // end convertRGBPixelToXYZ() - - inline Vector3f - convertXYZPixelToCIELab(Vector3f const& xyz) - { - float const one_over_3 = 1.0f/3.0f; - float const c2 = 16.0f/116.0f; - - float const X = (xyz0 > 0.0088565) ? pow(xyz0, one_over_3) : (7.787*xyz0 + c2); - float const Y = (xyz1 > 0.0088565) ? pow(xyz1, one_over_3) : (7.787*xyz1 + c2); - float const Z = (xyz2 > 0.0088565) ? pow(xyz2, one_over_3) : (7.787*xyz2 + c2); - - Vector3f lab; - lab0 = 116.0f*Y - 16.0f; - lab1 = 500.0f * (X - Y); - lab2 = 200.0f * (Y - Z); - return lab; - } // end convertXYZPixelToCIELab() - -//--------------------------------------------------------------------- - // Image display function. - template<typename Elem> - inline void showImage( const Image<Elem> &im, double scale = 0.0 ) - { -#ifdef V3DLIB_ENABLE_IMDEBUG - Image<unsigned char> out; - convertToUchar(im,out,scale); - if(im.numChannels()==3) { - unsigned char *rgb = new unsigned charim.width()*im.height()*im.numChannels(); - convertRGBToRGBInterleaved(out,rgb,im.width()*im.height()*im.numChannels()); - imdebug("rgb w=%d h=%d %p",im.width(),im.height(),rgb); - delete rgb; - } else if(im.numChannels()==1) { - imdebug("lum w=%d h=%d %p",im.width(),im.height(),out.begin()); - } else { - verify(false,"Num channels must be 1 or 3"); - } -#endif - } - - inline void showFloatImage( const Image<float> &im ) - { -#ifdef V3DLIB_ENABLE_IMDEBUG - if(im.numChannels()==1) { - imdebug("lum *auto b=32f w=%d h=%d %p",im.width(),im.height(),im.begin()); - } else { - verify(false,"Num channels must be 1"); - } -#endif - } - -} // namespace V3D - -#endif
View file
slowmoVideo-0.4.tar.gz/src/V3D/Base/v3d_serialization.h
Deleted
@@ -1,996 +0,0 @@ -// -*- C++ -*- - -#include "config.h" - -#ifndef V3D_SERIALIZATION_H -#define V3D_SERIALIZATION_H - -#include <string> -#include <iostream> -#include <fstream> -#include <vector> -#include <set> -#include <map> -#include <cstring> - -#include "Base/v3d_exception.h" - -//! Adds load and save routines to the serializable struct. -#define V3D_DEFINE_LOAD_SAVE(T) \ - template <typename Ar> \ - void save(Ar& ar) const { T& self = const_cast<T&>(*this); self.serialize(ar); } \ - template <typename Ar> \ - void load(Ar& ar) { this->serialize(ar); } - -//! Implements \c << and \c >> operators for streams for serializable structs. -#define V3D_DEFINE_IOSTREAM_OPS(T) \ - inline std::istream& operator>>(std::istream& is, T& v) \ - { \ - return V3D::loadFromIStream(is, v); \ - } \ - inline std::ostream& operator<<(std::ostream& os, T const& v) \ - { \ - return V3D::saveToOStream(os, v); \ - } - -//! Implements \c << and \c >> operators for streams for templated serializable structs. -#define V3D_DEFINE_TEMPLATE_IOSTREAM_OPS(T) \ - template <typename TT> \ - inline std::istream& operator>>(std::istream& is, T<TT>& v) \ - { \ - return V3D::loadFromIStream(is, v); \ - } \ - template <typename TT> \ - inline std::ostream& operator<<(std::ostream& os, T<TT> const& v) \ - { \ - return V3D::saveToOStream(os, v); \ - } - -namespace V3D -{ - - template <typename Archive> - struct OArchiveProtocol - { - Archive * archive() - { - return static_cast<Archive *>(this); - } - - static bool isLoading() { return false; } - static bool isSaving() { return true; } - - template <typename T> - Archive& operator<<(T const& val) - { - this->archive()->save(val); - return *this->archive(); - } - - template <typename T> - Archive& operator&(T const& val) - { - return (*this) << val; - } - - void serializeBlob(void * address, size_t count) - { - this->archive()->serializeBlob(address, count); - } - - //! Do not use whitespace in \param tag! - void tag(char const * tag) - { - this->archive()->saveTag(tag); - } - - void enterScope() { this->archive()->saveTag("{"); } - void leaveScope() { this->archive()->saveTag("}"); } - void endl() { this->archive()->endl(); } - }; - - template <typename Archive> - struct IArchiveProtocol - { - Archive * archive() - { - return static_cast<Archive *>(this); - } - - static bool isLoading() { return true; } - static bool isSaving() { return false; } - - template <typename T> - Archive& operator>>(T& val) - { - this->archive()->load(val); - return *this->archive(); - } - - template <typename T> - Archive& operator&(T& val) - { - return (*this) >> val; - } - - void serializeBlob(void * address, size_t count) - { - this->archive()->serializeBlob(address, count); - } - - //! Do not use whitespace in \param tag! - void tag(char const * tag) - { - std::string stag(tag); - std::string s; - this->archive()->loadTag(s); - if (stag != s) - throwV3DErrorHere(std::string("Tag mismatch <" + s + "> instead of <") + stag + std::string(">")); - } - - void enterScope() - { - std::string s; - this->archive()->loadTag(s); - if (s != "{") throwV3DErrorHere("Bracket mismatch <{>"); - } - - void leaveScope() - { - std::string s; - this->archive()->loadTag(s); - if (s != "}") throwV3DErrorHere("Bracket mismatch <}>"); - } - - void endl() { } - }; - - template <typename Archive> - struct SerializationScope - { - SerializationScope(Archive& ar) - : _ar(ar) - { - ar.enterScope(); - } - - SerializationScope(Archive& ar, char const * tag) - : _ar(ar) - { - ar.tag(tag); - ar.enterScope(); - } - - ~SerializationScope() - { - _ar.leaveScope(); - } - - protected: - Archive& _ar; - }; // end struct SerializationScope - -//---------------------------------------------------------------------- - - struct TextOStreamArchive : public OArchiveProtocol<TextOStreamArchive> - { - private: - typedef OArchiveProtocol<TextOStreamArchive> Base; - - public: - TextOStreamArchive(std::ostream& os) - : Base(), _os(os), - _indentation(0) - { } - - template <typename T> void save(T const& v) { v.T::save(*this); } - - void save(bool val) { this->put((int)val); } - void save(unsigned int val) { this->put(val); } - void save(int val) { this->put(val); } - void save(long val) { this->put(val); } - void save(unsigned long val) { this->put(val); } - void save(short int val) { this->put(val); } - void save(unsigned short int val) { this->put(val); } - void save(float val) { this->put(val); } - void save(double val) { this->put(val); } - void save(char val) { this->put(int(val)); } - void save(unsigned char val) { this->put((unsigned int)val); } - - void save(char const * str) - { - unsigned int len = std::strlen(str); - this->save(len); - _os.write(str, len); - _os << " "; - } - - void save(std::string const& str) - { - unsigned int len = str.length(); - this->save(len); - _os.write(str.c_str(), len); - _os << " "; - } - - void serializeBlob(void * address, size_t count) - { - char const * buffer = static_cast<const char *>(address); - _os.write(buffer, count); - } - - void saveTag(char const * tag) { this->put(tag); } - - void enterScope() - { - _indentation += 2; - Base::enterScope(); - } - - void leaveScope() - { - _indentation -= 2; - Base::leaveScope(); - this->endl(); - } - - void endl() - { - _os << std::endl; - this->indent(); - } - - protected: - template <typename T> - void put(T const& v) - { - _os << v << " "; - } - - void indent() - { - for (int i = 0; i < _indentation; ++i) _os << " "; - } - - std::ostream& _os; - int _indentation; - }; - - struct TextIStreamArchive : public IArchiveProtocol<TextIStreamArchive> - { - private: - typedef IArchiveProtocol<TextIStreamArchive> Base; - - public: - TextIStreamArchive(std::istream& is) - : Base(), _is(is) - { } - - template <typename T> void load(T& v) { v.T::load(*this); } - - void load(bool& val) { int v; get(v); val = (v != 0) ? true : false; } - void load(unsigned int& val) { get(val); } - void load(int& val) { get(val); } - void load(long& val) { get(val); } - void load(unsigned long& val) { get(val); } - void load(short int& val) { get(val); } - void load(unsigned short int& val) { get(val); } - void load(float& val) { get(val); } - void load(double& val) { get(val); } - void load(char& val) { int v; get(v); val = v; } - void load(unsigned char& val) { unsigned v; get(v); val = v; } - - void load(char * str) - { - unsigned int len; - this->load(len); - _is.ignore(); // Ignore the extra blank after len - _is.read(str, len); - strlen = 0; - } - - void load(std::string& str) - { - unsigned int len; - this->load(len); - _is.ignore(); // Ignore the extra blank after len - std::vector<char> buf(len+1); - _is.read(&buf0, len); - buflen = 0; - str = &buf0; - } - - void serializeBlob(void * address, size_t count) - { - char * buffer = static_cast<char *>(address); - _is.read(buffer, count); - } - - void loadTag(std::string& tag) - { - _is >> std::ws >> tag; - } - - void enterScope() { Base::enterScope(); } - void leaveScope() { Base::leaveScope(); } - - protected: - template <typename T> - void get(T& v) - { - _is >> v; - } - - std::istream& _is; - }; - -//---------------------------------------------------------------------- - - //! Output archive using a binary stream to write. - /*! Integer values (short, int, long) are stored as 32 bit entities. - * Hence binary serialization is not dependent on sizeof(int) etc. - * Floating point types are directly written, but all relevant platforms use - * IEEE fp format anyway. - * Chars and bools are written as 8 bit entities. - * Do not forget the ios::binary attribute for stream opening! - */ - struct BinaryOStreamArchive : public OArchiveProtocol<BinaryOStreamArchive> - { - private: - typedef OArchiveProtocol<BinaryOStreamArchive> Base; - - public: - BinaryOStreamArchive(std::ostream& os) - : Base(),_os(os) - { } - - template <typename T> void save(T const& v) { v.save(*this); } - - void save(bool val) { this->put_byte(val); } - void save(unsigned int val) { this->put_uint32(val); } - void save(int val) { this->put_int32(val); } - void save(long val) { this->put_int32(val); } - void save(unsigned long val) { this->put_uint32(val); } - void save(short int val) { this->put_int32(val); } - void save(unsigned short int val) { this->put_uint32(val); } - void save(float val) { this->put_blob(val); } - void save(double val) { this->put_blob(val); } - void save(char val) { this->put_byte(val); } - void save(unsigned char val) { this->put_byte(val); } - - void save(char const * str) - { - //assert(static_cast<unsigned int>(std::strlen(str)) < std::numeric_limits<unsigned int>::max()); - unsigned int len = static_cast<unsigned int>(std::strlen(str)); - save(len); - _os.write(str, len); - } - - void save(std::string const& str) - { - //assert(static_cast<unsigned int>(str.length()) < std::numeric_limits<unsigned int>::max()); - unsigned int len = static_cast<unsigned int>(str.length()); - save(len); - _os.write(str.c_str(), len); - } - - void serializeBlob(void * address, size_t count) - { - char const * buffer = static_cast<const char *>(address); - _os.write(buffer, count); - } - - void saveTag(char const *) { } - void enterScope() { } - void leaveScope() { } - void endl() { } - - protected: - template <typename T> - void put_byte(T v) - { - char val = v; - _os.write(&val, 1); - } - - void put_int32(signed long v) - { - unsigned char buf4; - buf0 = static_cast<unsigned char>(v & 0xff); - buf1 = static_cast<unsigned char>((v >> 8) & 0xff); - buf2 = static_cast<unsigned char>((v >> 16) & 0xff); - buf3 = static_cast<unsigned char>((v >> 24) & 0xff); - _os.write((char *)buf, 4); - } - - void put_uint32(unsigned long v) - { - unsigned char buf4; - buf0 = static_cast<unsigned char>(v & 0xff); - buf1 = static_cast<unsigned char>((v >> 8) & 0xff); - buf2 = static_cast<unsigned char>((v >> 16) & 0xff); - buf3 = static_cast<unsigned char>((v >> 24) & 0xff); - _os.write((char *)buf, 4); - } - - template <typename T> - void put_blob(T v) - { - _os.write((char *)&v, sizeof(v)); - } - - std::ostream& _os; - }; - - struct BinaryIStreamArchive : public IArchiveProtocol<BinaryIStreamArchive> - { - private: - typedef IArchiveProtocol<BinaryIStreamArchive> Base; - - public: - BinaryIStreamArchive(std::istream& is) - : Base(), _is(is) - { } - - template <typename T> void load(T& v) { v.load(*this); } - - void load(bool& val) { get_uchar(val); } - void load(unsigned int& val) { getUnsigned(val); } - void load(int& val) { getSigned(val); } - void load(long& val) { getSigned(val); } - void load(unsigned long& val) { getUnsigned(val); } - void load(short int& val) { getSigned(val); } - void load(unsigned short int& val) { getUnsigned(val); } - void load(float& val) { getGeneric(val); } - void load(double& val) { getGeneric(val); } - void load(char& val) { get_schar(val); } - void load(unsigned char& val) { get_uchar(val); } - - void load(char * str) - { - unsigned int len; - load(len); - _is.read(str, len); - strlen = 0; - } - - void load(std::string& str) - { - unsigned int len; - this->load(len); - std::vector<char> buf(len+1); - _is.read(&buf0, len); - buflen = 0; - str = &buf0; - } - - void serializeBlob(void * address, size_t count) - { - char * buffer = static_cast<char *>(address); - _is.read(buffer, count); - } - - void loadTag(std::string& /*tag*/) { } - void tag(std::string const& /*tag*/) { } - void enterScope() { } - void leaveScope() { } - - void skip(unsigned int nBytes) { _is.ignore(nBytes); } - - protected: - template <typename T> - void get_uchar(T& v) - { - unsigned char val; - _is.read((char *)&val, 1); - v = val; - } - - template <typename T> - void get_schar(T& v) - { - char val; - _is.read((char *)&val, 1); - v = val; - } - - template <typename T> - void getSigned(T& v) - { - signed long val; - get_int32(val); - v = val; - } - - template <typename T> - void getUnsigned(T& v) - { - unsigned long val; - get_uint32(val); - v = val; - } - - void get_uint32(unsigned long& v) - { - unsigned char buf4; - _is.read((char *)buf, 4); - v = buf0 + (buf1 << 8) + (buf2 << 16) + (buf3 << 24); - } - - void get_int32(signed long& v) - { - unsigned char buf4; - _is.read((char *)buf, 4); - v = buf0 + (buf1 << 8) + (buf2 << 16); - // The following is somewhat magic, interpret the most significant byte as signed char. - v += (signed char)(buf3) << 24; - } - - template <typename T> - void getGeneric(T& v) - { - _is.read((char *)&v, sizeof(v)); - } - - std::istream& _is; - }; - -//---------------------------------------------------------------------- - - struct BinaryArchiveSizeAccumulator : public OArchiveProtocol<BinaryArchiveSizeAccumulator> - { - BinaryArchiveSizeAccumulator() - : _byteSize(0) - { } - - template <typename T> void save(T const& v) { v.save(*this); } - - void save(bool) { _byteSize += 1; } - void save(unsigned int) { _byteSize += 4; } - void save(int) { _byteSize += 4; } - void save(long) { _byteSize += 4; } - void save(unsigned long) { _byteSize += 4; } - void save(short int) { _byteSize += 4; } - void save(unsigned short int) { _byteSize += 4; } - void save(float) { _byteSize += 4; } - void save(double) { _byteSize += 8; } - void save(char) { _byteSize += 1; } - void save(unsigned char) { _byteSize += 1; } - - void save(char const * str) - { - unsigned int len = std::strlen(str); - this->save(len); - _byteSize += len; - } - - void save(std::string const& str) - { - unsigned int len = str.length(); - this->save(len); - _byteSize += len; - } - - void serializeBlob(void *, size_t count) - { - _byteSize += count; - } - - void tag(std::string const&) { } - void enterScope() { } - void leaveScope() { } - void endl() { } - - unsigned int byteSize() const { return _byteSize; } - - protected: - unsigned int _byteSize; - }; // end struct BinaryArchiveSizeAccumulator - -//---------------------------------------------------------------------- - - // Serialize to a blob (contiguous memory) - struct BlobOArchive : public OArchiveProtocol<BlobOArchive> - { - private: - typedef OArchiveProtocol<BlobOArchive> Base; - - public: - BlobOArchive(int sz = 0) - : Base() - { - if (sz > 0) _blob.reserve(sz); - } - - void clear() { _blob.clear(); } - - unsigned char const * getBlob() const { return &_blob0; } - int blobSize() const { return _blob.size(); } - - template <typename T> void save(T const& v) { v.save(*this); } - - void save(bool val) { this->put_byte(val); } - void save(unsigned int val) { this->put_uint32(val); } - void save(int val) { this->put_int32(val); } - void save(long val) { this->put_int32(val); } - void save(unsigned long val) { this->put_uint32(val); } - void save(short int val) { this->put_int32(val); } - void save(unsigned short int val) { this->put_uint32(val); } - void save(float val) { this->put_blob(val); } - void save(double val) { this->put_blob(val); } - void save(char val) { this->put_byte(val); } - void save(unsigned char val) { this->put_byte(val); } - - void save(char const * str) - { - unsigned int len = static_cast<unsigned int>(std::strlen(str)); - this->save(len); - this->serializeBlob(str, len); - } - - void save(std::string const& str) - { - unsigned int len = static_cast<unsigned int>(str.length()); - this->save(len); - this->serializeBlob(str.c_str(), len); - } - - void serializeBlob(void const * address, size_t count) - { - unsigned char const * buffer = static_cast<unsigned char const *>(address); - for (size_t i = 0; i < count; ++i) - _blob.push_back(bufferi); - } - - void saveTag(char const *) { } - void enterScope() { } - void leaveScope() { } - void endl() { } - - protected: - template <typename T> - void put_byte(T v) - { - unsigned char val = v; - _blob.push_back(val); - } - - void put_int32(signed long v) - { - unsigned char buf4; - buf0 = static_cast<unsigned char>(v & 0xff); - buf1 = static_cast<unsigned char>((v >> 8) & 0xff); - buf2 = static_cast<unsigned char>((v >> 16) & 0xff); - buf3 = static_cast<unsigned char>((v >> 24) & 0xff); - _blob.push_back(buf0); - _blob.push_back(buf1); - _blob.push_back(buf2); - _blob.push_back(buf3); - } - - void put_uint32(unsigned long v) - { - unsigned char buf4; - buf0 = static_cast<unsigned char>(v & 0xff); - buf1 = static_cast<unsigned char>((v >> 8) & 0xff); - buf2 = static_cast<unsigned char>((v >> 16) & 0xff); - buf3 = static_cast<unsigned char>((v >> 24) & 0xff); - _blob.push_back(buf0); - _blob.push_back(buf1); - _blob.push_back(buf2); - _blob.push_back(buf3); - } - - template <typename T> - void put_blob(T v) - { - this->serializeBlob(&v, sizeof(v)); - } - - std::vector<unsigned char> _blob; - }; - - struct BlobIArchive : public IArchiveProtocol<BlobIArchive> - { - private: - typedef IArchiveProtocol<BlobIArchive> Base; - - public: - BlobIArchive(unsigned char const * blobStart) - : Base(), _blobPtr(blobStart) - { } - - template <typename T> void load(T& v) { v.load(*this); } - - void load(bool& val) { get_uchar(val); } - void load(unsigned int& val) { getUnsigned(val); } - void load(int& val) { getSigned(val); } - void load(long& val) { getSigned(val); } - void load(unsigned long& val) { getUnsigned(val); } - void load(short int& val) { getSigned(val); } - void load(unsigned short int& val) { getUnsigned(val); } - void load(float& val) { getGeneric(val); } - void load(double& val) { getGeneric(val); } - void load(char& val) { get_schar(val); } - void load(unsigned char& val) { get_uchar(val); } - - void load(char * str) - { - unsigned int len; - this->load(len); - this->serializeBlob(str, len); - strlen = 0; - } - - void load(std::string& str) - { - unsigned int len; - this->load(len); - std::vector<char> buf(len+1); - this->serializeBlob(&buf0, len); - buflen = 0; - str = &buf0; - } - - void serializeBlob(void * address, size_t count) - { - unsigned char * buffer = static_cast<unsigned char *>(address); - for (size_t i = 0; i < count; ++i) - bufferi = _blobPtri; - _blobPtr += count; - } - - void loadTag(std::string& /*tag*/) { } - void tag(std::string const& /*tag*/) { } - void enterScope() { } - void leaveScope() { } - - void skip(unsigned int nBytes) { _blobPtr += nBytes; } - - protected: - template <typename T> - void get_uchar(T& v) - { - v = *_blobPtr++; - } - - template <typename T> - void get_schar(T& v) - { - v = *_blobPtr++; - } - - template <typename T> - void getSigned(T& v) - { - signed long val; - get_int32(val); - v = val; - } - - template <typename T> - void getUnsigned(T& v) - { - unsigned long val; - get_uint32(val); - v = val; - } - - void get_uint32(unsigned long& v) - { - unsigned char const * buf = _blobPtr; - v = buf0 + (buf1 << 8) + (buf2 << 16) + (buf3 << 24); - _blobPtr += 4; - } - - void get_int32(signed long& v) - { - unsigned char const * buf = _blobPtr; - v = buf0 + (buf1 << 8) + (buf2 << 16); - // The following is somewhat magic, interpret the most significant byte as signed char. - v += (signed char)(buf3) << 24; - _blobPtr += 4; - } - - template <typename T> - void getGeneric(T& v) - { - this->serializeBlob(&v, sizeof(v)); - } - - unsigned char const * _blobPtr; - }; - -//---------------------------------------------------------------------- - - //! Serializes a vector of serializable items. - template <typename Archive, typename T> - inline void - serializeVector(std::vector<T>& v, Archive& ar) - { - unsigned int sz = v.size(); - ar & sz; - if (ar.isLoading()) v.resize(sz); - SerializationScope<Archive> s(ar); - for (unsigned i = 0; i < sz; ++i) ar & vi; - } - - template <typename Archive, typename T> - inline void - serializeVector(char const * tag, std::vector<T>& v, Archive& ar) - { - ar.tag(tag); - serializeVector(v, ar); - } - - template <typename Archive, typename T> - inline void - serializeSet(std::set<T>& v, Archive& ar) - { - unsigned int sz = v.size(); - ar & sz; - - SerializationScope<Archive> s(ar); - - if (ar.isLoading()) - { - T elem; - for (unsigned i = 0; i < sz; ++i) - { - ar & elem; - v.insert(elem); - } - } - else - { - T elem; - for (typename std::set<T>::iterator p = v.begin(); p != v.end(); ++p) - { - elem = *p; - ar & elem; - } - } // end if - } // end serializeSet() - - template <typename Archive, typename Key, typename T> - inline void - serializeMap(std::map<Key, T>& v, Archive& ar) - { - unsigned int sz = v.size(); - ar & sz; - - SerializationScope<Archive> s(ar); - - if (ar.isLoading()) - { - v.clear(); - Key key; - T elem; - for (unsigned i = 0; i < sz; ++i) - { - ar & key & elem; - v.insert(make_pair(key, elem)); - } - } - else - { - Key key; - for (typename std::map<Key, T>::iterator p = v.begin(); p != v.end(); ++p) - { - key = p->first; - ar & key & p->second; - } - } // end if - } // end serializeMap() - - template <typename T> - inline void - serializeDataToFile(char const * archiveName, T const& data, bool writeBinary = true) - { - using namespace std; - - int const tagLength = 6; - - if (writeBinary) - { - char const * magicTag = "V3DBIN"; - ofstream os(archiveName, ios::binary); - os.write(magicTag, tagLength); - BinaryOStreamArchive ar(os); - ar & data; - } - else - { - char const * magicTag = "V3DTXT"; - ofstream os(archiveName); - os << magicTag << endl; - TextOStreamArchive ar(os); - ar & data; - } - } // end serializeDataToFile() - - template <typename T> - inline void - serializeDataFromFile(char const * archiveName, T& data) - { - using namespace std; - - int const tagLength = 6; - - bool isBinary = true; - - { - // Determine archive format from the first 8 chars - char magicTagtagLength; - ifstream is(archiveName, ios::binary); - is.read(magicTag, tagLength); - if (strncmp(magicTag, "V3DBIN", tagLength) == 0) - isBinary = true; - else if (strncmp(magicTag, "V3DTXT", tagLength) == 0) - isBinary = false; - else - throwV3DErrorHere("Unknown archive magic tag"); - } - - if (isBinary) - { - ifstream is(archiveName, ios::binary); - is.ignore(tagLength); - BinaryIStreamArchive ar(is); - ar & data; - } - else - { - ifstream is(archiveName); - is.ignore(tagLength); - TextIStreamArchive ar(is); - ar & data; - } - } // end serializeDataFromFile() - - template <typename T> - inline std::ostream& - saveToOStream(std::ostream& os, T const& v) - { - using namespace std; - TextOStreamArchive ar(os); - ar << v; - return os; - } - - template <typename T> - inline std::istream& - loadFromIStream(std::istream& is, T& v) - { - using namespace std; - TextIStreamArchive ar(is); - ar >> v; - return is; - } - -//---------------------------------------------------------------------- - - template <typename Feature> - struct SerializableVector : public std::vector<Feature> - { - SerializableVector() - : std::vector<Feature>() - { } - - SerializableVector(size_t sz) - : std::vector<Feature>(sz) - { } - - template <typename Archive> void serialize(Archive& ar) - { - serializeVector(*this, ar); - } - - V3D_DEFINE_LOAD_SAVE(SerializableVector); - }; // end struct SerializableVector - - V3D_DEFINE_TEMPLATE_IOSTREAM_OPS(SerializableVector); - -} // end namespace V3D - -#endif
View file
slowmoVideo-0.4.tar.gz/src/V3D/Base/v3d_timer.h
Deleted
@@ -1,147 +0,0 @@ -// -*- C++ -*- - -#include "config.h" - -#ifndef V3D_TIMER_H -#define V3D_TIMER_H - -#include <cstdio> -#include <ctime> -#include <algorithm> - -#if defined(WIN32) -# include <windows.h> -#else -# include <cstring> -# include <sys/time.h> -#endif - - -namespace V3D -{ - using namespace std; - - class Timer - { - public: - Timer(const char *name = "<unnamed timer>", int history_size = 0) - : _total_time(0), _history(0), _history_index(0), _count(0) - { - _name0 = '\0'; - -#ifdef _MSC_VER - LARGE_INTEGER freq; - QueryPerformanceFrequency(&freq); - _freq = freq.QuadPart; - if (name) - strcpy_s(_name, sizeof(_name), name); - else - strcpy_s(_name, sizeof(_name), "<unnamed timer>"); -#else - _freq = 1000000; // gettimeofday() return microseconds. - if (name) - strncpy(_name, name, sizeof(_name)); - else - strncpy(_name, "<unnamed timer>", sizeof(_name)); -#endif - if (history_size > 0) - _history = new unsigned long longhistory_size; - _history_size = history_size; - std::fill(_history,_history+_history_size,0); - } - - ~Timer() - { - delete _history; - } - - void start() - { -#ifdef WIN32 - LARGE_INTEGER start_time; - QueryPerformanceCounter(&start_time); - _start_time = start_time.QuadPart; -#else - timeval tv; - gettimeofday(&tv, 0); - _start_time = tv.tv_sec*_freq + tv.tv_usec; -#endif - } - - void stop() - { -#ifdef WIN32 - LARGE_INTEGER cur_time; - QueryPerformanceCounter(&cur_time); - unsigned long long elapsed = cur_time.QuadPart - _start_time; -#else - timeval tv; - gettimeofday(&tv, 0); - unsigned long long elapsed = tv.tv_sec*_freq + tv.tv_usec - _start_time; -#endif - _total_time += elapsed; - if (_history) - { - if ((int)_count == _history_size) - _total_time -= _history_history_index; - else - ++_count; - _history_history_index = elapsed; - ++_history_index; - if(_history_index >= _history_size) - _history_index = 0; - } - else - ++_count; - } // end stop() - - double getHertz() const { return _freq*(double)_count/_total_time; } - double getTime() const { return (double)_total_time/_freq; } - - unsigned long getCount() const { return _count; } - const char *getName() const { return _name; } - - void printHertz() const { printf("TIMING: %s: %.03f Hz\n",_name, this->getHertz()); } - void printTime() const { printf("TIMING: %s: %.03f s\n",_name, this->getTime()); } - - void print() const - { - printf("TIMING: %s: %.03f Hz, %.03f s/exec, %ld execs, %.03f s\n", _name, - getHertz(), getTime()/getCount(), getCount(), getTime()); - } - - private: - unsigned long long _freq; - unsigned long long _total_time; - unsigned long long * _history; - int _history_size; - int _history_index; - unsigned long _count; - unsigned long long _start_time; - char _name80; - }; // end struct Timer - - - struct ScopedTimer - { - ScopedTimer(const char *name = "<unnamed timer>") : - _timer(name,0) - { - _timer.start(); - } - - ~ScopedTimer() - { - _timer.stop(); -#ifndef NDEBUG - _timer.print(); -#endif - } - - private: - Timer _timer; - }; - -} // end namespace V3D - -#endif
View file
slowmoVideo-0.4.tar.gz/src/V3D/Base/v3d_utilities.h
Deleted
@@ -1,133 +0,0 @@ -// -*- C++ -*- - -#include "config.h" - -// General utility procedures that do not fit anywhere else. -#ifndef V3D_UTILITIES_H -#define V3D_UTILITIES_H - -#include "Base/v3d_image.h" -#include "Math/v3d_linear.h" - -#include <cmath> -#include <map> -#include <set> - -#ifdef _WIN32 -# define M_PI 3.14159265358979323846 -#endif - -namespace V3D -{ -//---------------------------------------------------------------------- - - inline Image<unsigned char> - makeColorWheelImage() - { - // relative lengths of color transitions: - // these are chosen based on perceptual similarity - // (e.g. one can distinguish more shades between red and yellow - // than between yellow and green) -#if 0 - int const RY = 15; - int const YG = 6; - int const GC = 4; - int const CB = 11; - int const BM = 13; - int const MR = 6; -#else - // Make a ramp of 64 colors (instead of 55). - int const RY = 17; - int const YG = 7; - int const GC = 5; - int const CB = 13; - int const BM = 15; - int const MR = 7; -#endif - - int const w = RY + YG + GC + CB + BM + MR; - Image<unsigned char> I(w, 1, 3); - - int x = 0; - for (int i = 0; i < RY; ++i, ++x) { I(x, 0, 0) = 255; I(x, 0, 1) = 255*i/RY; I(x, 0, 2) = 0; } - for (int i = 0; i < YG; ++i, ++x) { I(x, 0, 0) = 255-255*i/YG; I(x, 0, 1) = 255; I(x, 0, 2) = 0; } - for (int i = 0; i < GC; ++i, ++x) { I(x, 0, 0) = 0; I(x, 0, 1) = 255; I(x, 0, 2) = 255*i/GC; } - for (int i = 0; i < CB; ++i, ++x) { I(x, 0, 0) = 0; I(x, 0, 1) = 255-255*i/CB; I(x, 0, 2) = 255; } - for (int i = 0; i < BM; ++i, ++x) { I(x, 0, 0) = 255*i/BM; I(x, 0, 1) = 0; I(x, 0, 2) = 255; } - for (int i = 0; i < MR; ++i, ++x) { I(x, 0, 0) = 255; I(x, 0, 1) = 0; I(x, 0, 2) = 255-255*i/MR; } - - return I; - } // end makeColorWheelImage() - - inline Vector3b - getVisualColorForFlowVector(float u, float v, bool useSqrtMap = false) - { - using namespace std; - - static Image<unsigned char> const wheel = makeColorWheelImage(); - - int const w = wheel.width(); - - float r = sqrtf(u*u + v*v); - if (useSqrtMap) r = sqrtf(r); - float const phi = atan2f(-v, -u) / M_PI; - float const fk = (phi + 1.0) / 2.0 * w; - int const k0 = (int)fk; - int const k1 = (k0 + 1) % w; - float const f = fk - k0; - - Vector3b res; - - for (int b = 0; b < 3; ++b) - { - float const col0 = float(wheel(k0, 0, b)); - float const col1 = float(wheel(k1, 0, b)); - float col = (1-f)*col0 + f*col1; - if (r <= 1) - col = 255.0f - r * (255.0f - col); // increase saturation with radius - else - col *= .75f; // out of range - resb = (int)col; - } // end for (b) - return res; - } // end getVisualColorForFlowVector() - - inline Image<unsigned char> - getVisualImageForFlowField(Image<float> const& u, Image<float> const& v, float scale, - bool useSqrtMap = false) - { - int const w = u.width(); - int const h = u.height(); - - Image<unsigned char> res(w, h, 3); - for (int y = 0; y < h; ++y) - for (int x = 0; x < w; ++x) - { - Vector3b const c = getVisualColorForFlowVector(scale * u(x, y), scale * v(x, y), useSqrtMap); - res(x, y, 0) = c0; - res(x, y, 1) = c1; - res(x, y, 2) = c2; - } - return res; - } // end getVisualImageForFlowField() - - template <typename T> - inline void - flipImageUpsideDown(Image<T>& I) - { - int const w = I.width(); - int const h = I.height(); - int const nChannels = I.numChannels(); - - for (int c = 0; c < nChannels; ++c) - for (int y = 0; y < h/2; ++y) - { - int const y1 = h - 1 - y; - for (int x = 0; x < w; ++x) - std::swap(I(x, y, c), I(x, y1, c)); - } - } // end flipImageUpsideDown() - -} // end namespace V3D - -#endif
View file
slowmoVideo-0.4.tar.gz/src/V3D/COPYING.TXT
Deleted
@@ -1,165 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - - This version of the GNU Lesser General Public License incorporates -the terms and conditions of version 3 of the GNU General Public -License, supplemented by the additional permissions listed below. - - 0. Additional Definitions. - - As used herein, "this License" refers to version 3 of the GNU Lesser -General Public License, and the "GNU GPL" refers to version 3 of the GNU -General Public License. - - "The Library" refers to a covered work governed by this License, -other than an Application or a Combined Work as defined below. - - An "Application" is any work that makes use of an interface provided -by the Library, but which is not otherwise based on the Library. -Defining a subclass of a class defined by the Library is deemed a mode -of using an interface provided by the Library. - - A "Combined Work" is a work produced by combining or linking an -Application with the Library. The particular version of the Library -with which the Combined Work was made is also called the "Linked -Version". - - The "Minimal Corresponding Source" for a Combined Work means the -Corresponding Source for the Combined Work, excluding any source code -for portions of the Combined Work that, considered in isolation, are -based on the Application, and not on the Linked Version. - - The "Corresponding Application Code" for a Combined Work means the -object code and/or source code for the Application, including any data -and utility programs needed for reproducing the Combined Work from the -Application, but excluding the System Libraries of the Combined Work. - - 1. Exception to Section 3 of the GNU GPL. - - You may convey a covered work under sections 3 and 4 of this License -without being bound by section 3 of the GNU GPL. - - 2. Conveying Modified Versions. - - If you modify a copy of the Library, and, in your modifications, a -facility refers to a function or data to be supplied by an Application -that uses the facility (other than as an argument passed when the -facility is invoked), then you may convey a copy of the modified -version: - - a) under this License, provided that you make a good faith effort to - ensure that, in the event an Application does not supply the - function or data, the facility still operates, and performs - whatever part of its purpose remains meaningful, or - - b) under the GNU GPL, with none of the additional permissions of - this License applicable to that copy. - - 3. Object Code Incorporating Material from Library Header Files. - - The object code form of an Application may incorporate material from -a header file that is part of the Library. You may convey such object -code under terms of your choice, provided that, if the incorporated -material is not limited to numerical parameters, data structure -layouts and accessors, or small macros, inline functions and templates -(ten or fewer lines in length), you do both of the following: - - a) Give prominent notice with each copy of the object code that the - Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the object code with a copy of the GNU GPL and this license - document. - - 4. Combined Works. - - You may convey a Combined Work under terms of your choice that, -taken together, effectively do not restrict modification of the -portions of the Library contained in the Combined Work and reverse -engineering for debugging such modifications, if you also do each of -the following: - - a) Give prominent notice with each copy of the Combined Work that - the Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the Combined Work with a copy of the GNU GPL and this license - document. - - c) For a Combined Work that displays copyright notices during - execution, include the copyright notice for the Library among - these notices, as well as a reference directing the user to the - copies of the GNU GPL and this license document. - - d) Do one of the following: - - 0) Convey the Minimal Corresponding Source under the terms of this - License, and the Corresponding Application Code in a form - suitable for, and under terms that permit, the user to - recombine or relink the Application with a modified version of - the Linked Version to produce a modified Combined Work, in the - manner specified by section 6 of the GNU GPL for conveying - Corresponding Source. - - 1) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (a) uses at run time - a copy of the Library already present on the user's computer - system, and (b) will operate properly with a modified version - of the Library that is interface-compatible with the Linked - Version. - - e) Provide Installation Information, but only if you would otherwise - be required to provide such information under section 6 of the - GNU GPL, and only to the extent that such information is - necessary to install and execute a modified version of the - Combined Work produced by recombining or relinking the - Application with a modified version of the Linked Version. (If - you use option 4d0, the Installation Information must accompany - the Minimal Corresponding Source and Corresponding Application - Code. If you use option 4d1, you must provide the Installation - Information in the manner specified by section 6 of the GNU GPL - for conveying Corresponding Source.) - - 5. Combined Libraries. - - You may place library facilities that are a work based on the -Library side by side in a single library together with other library -facilities that are not Applications and are not covered by this -License, and convey such a combined library under terms of your -choice, if you do both of the following: - - a) Accompany the combined library with a copy of the same work based - on the Library, uncombined with any other library facilities, - conveyed under the terms of this License. - - b) Give prominent notice with the combined library that part of it - is a work based on the Library, and explaining where to find the - accompanying uncombined form of the same work. - - 6. Revised Versions of the GNU Lesser General Public License. - - The Free Software Foundation may publish revised and/or new versions -of the GNU Lesser General Public License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. - - Each version is given a distinguishing version number. If the -Library as you received it specifies that a certain numbered version -of the GNU Lesser General Public License "or any later version" -applies to it, you have the option of following the terms and -conditions either of that published version or of any later version -published by the Free Software Foundation. If the Library as you -received it does not specify a version number of the GNU Lesser -General Public License, you may choose any version of the GNU Lesser -General Public License ever published by the Free Software Foundation. - - If the Library as you received it specifies that a proxy can decide -whether future versions of the GNU Lesser General Public License shall -apply, that proxy's public statement of acceptance of any version is -permanent authorization for you to choose that version for the -Library.
View file
slowmoVideo-0.4.tar.gz/src/V3D/Config
Deleted
-(directory)
View file
slowmoVideo-0.4.tar.gz/src/V3D/Config/config.h
Deleted
@@ -1,20 +0,0 @@ -#ifndef CONFIG_H -#define CONFIG_H - -/** - - This header file is for directly including the shader files in the binary - which makes it easier to ship an exectuable. - - The #defines are only for QtCreator which does not support the CMake add_definitions yet. - - -- Simon A. Eugster - */ - -#ifndef DISABLE_REDEFINITIONS -#define V3DLIB_ENABLE_LIBJPEG -#define V3DLIB_ENABLE_LIBPNG -#define V3DLIB_ENABLE_GPGPU -#endif - -#endif // CONFIG_H
View file
slowmoVideo-0.4.tar.gz/src/V3D/Config/v3d_macros.cmake
Deleted
@@ -1,42 +0,0 @@ -# -*- CMake -*- - -macro (enable_feature feature) - set (${feature} 1) - add_definitions(-D${feature}) -endmacro (enable_feature) - -macro (enable_conditional_feature feature dep_feature) - if (${dep_feature}) - set (${feature} 1) - add_definitions(-D${feature}) - endif (${dep_feature}) -endmacro (enable_conditional_feature) - -macro (enable_feature_inc_path feature) - if (${feature}) - set (EXTRA_INC_DIRS ${EXTRA_INC_DIRS} ${ARGN}) - endif (${feature}) -endmacro (enable_feature_inc_path) - -macro (enable_feature_lib_path feature) - if (${feature}) - set (EXTRA_LIB_DIRS ${EXTRA_LIB_DIRS} ${ARGN}) - endif (${feature}) -endmacro (enable_feature_lib_path) - -macro (enable_feature_libraries feature) - if (${feature}) - set (EXTRA_LIBRARIES ${EXTRA_LIBRARIES} ${ARGN}) - endif (${feature}) -endmacro (enable_feature_libraries) - -macro (add_v3d_executable target) - #message(STATUS "ARGN variable contains: ${ARGN}") - add_executable(${target} ${ARGN}) - add_dependencies(${target} V3d2) -endmacro (add_v3d_executable) - -macro (add_simple_v3d_executable target) - add_executable(${target} ${target}.cpp) - add_dependencies(${target} V3d2) -endmacro (add_simple_v3d_executable)
View file
slowmoVideo-0.4.tar.gz/src/V3D/GL
Deleted
-(directory)
View file
slowmoVideo-0.4.tar.gz/src/V3D/GL/glsl_shaders.cpp
Deleted
@@ -1,583 +0,0 @@ -#include "glsl_shaders.h" - -namespace GLSL_Shaders -{ - const std::string tvl1_flow_new_update_p = - "#version 330\n" - "\n" - "uniform sampler2D uv_src;\n" - "uniform sampler2D p_uv_src;\n" - "\n" - "in vec4 gl_TexCoord4;\n" - "\n" - "out vec4 my_FragColor;\n" - "\n" - "uniform float timestep;\n" - "uniform float rcpLambda_p;\n" - "\n" - "const float eps_dual = 0.0f;\n" - "\n" - "vec2 tv(vec4 uv_grad)\n" - "{\n" - " return vec2(length(uv_grad.xz), length(uv_grad.yw));\n" - "}\n" - "\n" - "void main(void)\n" - "{\n" - " vec2 st0 = gl_TexCoord0.st;\n" - " vec4 stEW = gl_TexCoord1;\n" - " vec4 stSN = gl_TexCoord2;\n" - "\n" - " vec2 uv = texture2D(uv_src, st0).xy;\n" - " vec4 uv_ES = vec4(0.0f);\n" - " uv_ES.xy = texture2D(uv_src, stEW.xy).xy;\n" - " uv_ES.zw = texture2D(uv_src, stSN.xy).xy;\n" - "\n" - " vec4 p_uv = texture2D(p_uv_src, st0);\n" - "\n" - " // The right clamping mode should handle the boundary conditions.\n" - " vec4 uv_grad = uv_ES - uv.xyxy;\n" - "\n" - " p_uv -= timestep * (uv_grad + eps_dual * p_uv);\n" - "\n" - "#if 0\n" - " const float denom = max(1.0f, rcpLambda_p * length(p_uv));\n" - " p_uv /= denom;\n" - "#else\n" - " vec2 denom = max(vec2(1.0f), rcpLambda_p * tv(p_uv));\n" - " p_uv /= denom.xyxy;\n" - "#endif\n" - " my_FragColor = p_uv;\n" - "}\n" - "\n"; - - const std::string flow_warp_image = - "#version 330\n" - "\n" - "uniform sampler2D uv_src;\n" - "uniform sampler2D I0_tex;\n" - "uniform sampler2D I1_tex;\n" - "\n" - "in vec4 gl_TexCoord4;\n" - "\n" - "out vec4 my_FragColor;\n" - "\n" - "float signum(float value)\n" - "{\n" - " return (value < 0) ? -1 : 1;\n" - "}\n" - "\n" - "void main()\n" - "{\n" - " vec2 st0 = gl_TexCoord0.st;\n" - " vec3 st3 = gl_TexCoord3.stp;\n" - "\n" - " const float eps = 0.001f;\n" - "\n" - " vec2 uv = texture2D(uv_src, st0).xy;\n" - " vec3 I0 = texture2D(I0_tex, st0).xyz;\n" - " vec3 I1 = texture2D(I1_tex, st0 + st3.xy*uv).xyz;\n" - " I1.yz *= st3.z;\n" - "\n" - " // Central differences and use gradients from both images\n" - " const vec2 ds0 = vec2(1, 0); // I0_tex has nearest texture filtering\n" - " const vec2 dt0 = vec2(0, 1);\n" - " const vec2 ds = vec2(0.5, 0);\n" - " const vec2 dt = vec2(0, 0.5);\n" - " vec2 I0grad;\n" - " vec2 I1grad;\n" - " I0grad.x = 0.5f * (texture2D(I0_tex, st0 + st3.xy*ds0).x - texture2D(I0_tex, st0 - st3.xy*ds0).x);\n" - " I0grad.y = 0.5f * (texture2D(I0_tex, st0 + st3.xy*dt0).x - texture2D(I0_tex, st0 - st3.xy*dt0).x);\n" - " I1grad.x = texture2D(I1_tex, st0 + st3.xy*(uv+ds)).x - texture2D(I1_tex, st0 + st3.xy*(uv-ds)).x;\n" - " I1grad.y = texture2D(I1_tex, st0 + st3.xy*(uv+dt)).x - texture2D(I1_tex, st0 + st3.xy*(uv-dt)).x;\n" - " I1.yz = 0.5f * (I0grad + I1grad);\n" - "\n" - " // Avoid zero gradients\n" - " I1.y = (abs(I1.y) < eps) ? (signum(I1.y) * eps) : I1.y;\n" - " I1.z = (abs(I1.z) < eps) ? (signum(I1.z) * eps) : I1.z;\n" - "\n" - " vec4 color_out;\n" - " color_out.x = I1.x - dot(I1.yz, uv) - I0.x;\n" - " color_out.yz = I1.yz;\n" - " color_out.w = abs(I1.x-I0.x);\n" - "\n" - " my_FragColor = color_out;\n" - "}\n"; - - const std::string pyramid_with_derivative_pass1v = - "#version 330\n" - "\n" - "uniform sampler2D src_tex;\n" - "\n" - "uniform int presmoothing;\n" - "\n" - "in vec4 gl_TexCoord4;\n" - "\n" - "out vec4 my_FragColor;\n" - "\n" - "void main()\n" - "{\n" - " vec4 st0 = gl_TexCoord0;\n" - " vec4 st1 = gl_TexCoord1;\n" - " vec4 st2 = gl_TexCoord2;\n" - " vec4 st3 = gl_TexCoord3;\n" - " if (presmoothing == 3) {\n" - " // This is the (odd) binomial kernel 0 1 6 15 20 15 6 1 0\n" - " const vec4 f1 = vec4(0, 1, 6, 15) / 64.0f;\n" - " const vec4 f2 = vec4(20, 15, 6, 1) / 64.0f;\n" - "\n" - " const vec4 df = vec4(1, 6, 14, 14) / 128.0f;\n" - "\n" - " vec2 ds = st0.zw - st0.xy;\n" - "\n" - " vec4 g1, g2;\n" - " float g3;\n" - " g1.x = texture2D(src_tex, st0.xy - ds).x;\n" - " g1.y = texture2D(src_tex, st0.xy).x;\n" - " g1.z = texture2D(src_tex, st0.zw).x;\n" - " g1.w = texture2D(src_tex, st1.xy).x;\n" - " g2.x = texture2D(src_tex, st1.zw).x;\n" - " g2.y = texture2D(src_tex, st2.xy).x;\n" - " g2.z = texture2D(src_tex, st2.zw).x;\n" - " g2.w = texture2D(src_tex, st3.xy).x;\n" - " g3 = texture2D(src_tex, st3.zw).x;\n" - "\n" - " g1 *= 255.0f;\n" - " g2 *= 255.0f;\n" - " g3 *= 255.0f;\n" - "\n" - " float v = dot(f1, g1) + dot(f2, g2);\n" - " float dv = -dot(df, g1) + dot(df, vec4(g2.yzw, g3));\n" - " my_FragColor.x = v;\n" - " my_FragColor.y = dv;\n" - " } else if (presmoothing == 2) {\n" - " // This is the (odd) binomial kernel 0 1 4 6 4 1 0\n" - " const vec4 f1 = vec4(0, 1, 4, 6) / 16.0f;\n" - " const vec3 f2 = vec3(4, 1, 0) / 16.0f;\n" - "\n" - " const vec4 df1 = vec4(-1, -4, -5, 0) / 32.0f;\n" - " const vec3 df2 = vec3(5, 4, 1) / 32.0f;\n" - "\n" - " vec4 g1;\n" - " vec3 g2;\n" - "\n" - " g1.x = texture2D(src_tex, st0.xy).x;\n" - " g1.y = texture2D(src_tex, st0.zw).x;\n" - " g1.z = texture2D(src_tex, st1.xy).x;\n" - " g1.w = texture2D(src_tex, st1.zw).x;\n" - " g2.x = texture2D(src_tex, st2.xy).x;\n" - " g2.y = texture2D(src_tex, st2.zw).x;\n" - " g2.z = texture2D(src_tex, st3.xy).x;\n" - "\n" - " g1 *= 255.0f;\n" - " g2 *= 255.0f;\n" - "\n" - " float v = dot(f1, g1) + dot(f2, g2);\n" - " float dv = dot(df1, g1) + dot(df2, g2);\n" - " my_FragColor.x = v;\n" - " my_FragColor.y = dv;\n" - " } else if (presmoothing == 1) {\n" - " // This is the (odd) binomial kernel 0 1 2 1 0\n" - " const vec4 f1 = vec4(0, 1, 2, 1) / 4.0f;\n" - "\n" - " const vec4 df1 = vec4(-1, -2, 0, 2) / 8.0f;\n" - " const float df2 = 1.0 / 8.0f;\n" - "\n" - " vec4 g1;\n" - " float g2;\n" - "\n" - " g1.x = texture2D(src_tex, st0.zw).x;\n" - " g1.y = texture2D(src_tex, st1.xy).x;\n" - " g1.z = texture2D(src_tex, st1.zw).x;\n" - " g1.w = texture2D(src_tex, st2.xy).x;\n" - " g2 = texture2D(src_tex, st2.zw).x;\n" - "\n" - " g1 *= 255.0f;\n" - " g2 *= 255.0f;\n" - "\n" - " float v = dot(f1, g1);\n" - " float dv = dot(df1, g1) + df2*g2;\n" - " my_FragColor.x = v;\n" - " my_FragColor.y = dv;\n" - " } else if (presmoothing == 4) {\n" - " // This is the (odd) kernel 0 1 6 1 0\n" - " const vec4 f1 = vec4(0, 1, 6, 1) / 8.0f;\n" - "\n" - " const vec4 df1 = vec4(-1, -6, 0, 6) / 16.0f;\n" - " const float df2 = 1.0 / 16.0f;\n" - "\n" - " vec4 g1;\n" - " float g2;\n" - "\n" - " g1.x = texture2D(src_tex, st0.zw).x;\n" - " g1.y = texture2D(src_tex, st1.xy).x;\n" - " g1.z = texture2D(src_tex, st1.zw).x;\n" - " g1.w = texture2D(src_tex, st2.xy).x;\n" - " g2 = texture2D(src_tex, st2.zw).x;\n" - "\n" - " g1 *= 255.0f;\n" - " g2 *= 255.0f;\n" - "\n" - " float v = dot(f1, g1);\n" - " float dv = dot(df1, g1) + df2*g2;\n" - " my_FragColor.x = v;\n" - " my_FragColor.y = dv;\n" - " } else {\n" - "\n" - " const vec4 f1 = vec4(0, 0, 1, 0);\n" - "\n" - " const vec4 df1 = vec4(0, -1, 0, 1) / 2.0f;\n" - "\n" - " vec4 g1;\n" - "\n" - " g1.x = 0;\n" - " g1.y = texture2D(src_tex, st1.xy).x;\n" - " g1.z = texture2D(src_tex, st1.zw).x;\n" - " g1.w = texture2D(src_tex, st2.xy).x;\n" - "\n" - " g1 *= 255.0f;\n" - "\n" - " float v = dot(f1, g1);\n" - " float dv = dot(df1, g1);\n" - " my_FragColor.x = v;\n" - " my_FragColor.y = dv;\n" - " }\n" - "}\n"; - - const std::string pyramid_with_derivative_pass1h = - "#version 330\n" - "\n" - "uniform sampler2D src_tex;\n" - "\n" - "uniform int presmoothing;\n" - "\n" - "in vec4 gl_TexCoord4;\n" - "\n" - "out vec4 my_FragColor;\n" - "\n" - "void main()\n" - "{\n" - " vec4 st0 = gl_TexCoord0;\n" - " vec4 st1 = gl_TexCoord1;\n" - " vec4 st2 = gl_TexCoord2;\n" - " vec4 st3 = gl_TexCoord3;\n" - "\n" - " vec3 color;\n" - " if (presmoothing == 3) {\n" - " // This is the (odd) binomial kernel 0 1 6 15 20 15 6 1 0\n" - " const vec4 f1 = vec4(0, 1, 6, 15) / 64.0f;\n" - " const vec4 f2 = vec4(20, 15, 6, 1) / 64.0f;\n" - "\n" - " const vec4 df = vec4(1, 6, 14, 14) / 128.0f;\n" - "\n" - " vec2 ds = st0.zw - st0.xy;\n" - "\n" - " vec4 rawVal1, rawVal2, rawVal3, rawVal4, rawVal5, rawVal6, rawVal7, rawVal8, rawVal9;\n" - "\n" - " rawVal1 = texture2D(src_tex, st0.xy - ds);\n" - " rawVal2 = texture2D(src_tex, st0.xy);\n" - " rawVal3 = texture2D(src_tex, st0.zw);\n" - " rawVal4 = texture2D(src_tex, st1.xy);\n" - " rawVal5 = texture2D(src_tex, st1.zw);\n" - " rawVal6 = texture2D(src_tex, st2.xy);\n" - " rawVal7 = texture2D(src_tex, st2.zw);\n" - " rawVal8 = texture2D(src_tex, st3.xy);\n" - " rawVal9 = texture2D(src_tex, st3.zw);\n" - "\n" - " vec4 g1, g2, dg1, dg2;\n" - " float g3, dg3;\n" - " g1.x = rawVal1.x;\n" - " dg1.x = rawVal1.y;\n" - " g1.y = rawVal2.x;\n" - " dg1.y = rawVal2.y;\n" - " g1.z = rawVal3.x;\n" - " dg1.z = rawVal3.y;\n" - " g1.w = rawVal4.x;\n" - " dg1.w = rawVal4.y;\n" - " g2.x = rawVal5.x;\n" - " dg2.x = rawVal5.y;\n" - " g2.y = rawVal6.x;\n" - " dg2.y = rawVal6.y;\n" - " g2.z = rawVal7.x;\n" - " dg2.z = rawVal7.y;\n" - " g2.w = rawVal8.x;\n" - " dg2.w = rawVal8.y;\n" - " g3 = rawVal9.x;\n" - " dg3 = rawVal9.y;\n" - "\n" - " float v = dot(f1, g1) + dot(f2, g2);\n" - " float dv_dx = -dot(df, g1) + dot(df, vec4(g2.yzw, g3));\n" - " float dv_dy = dot(f1, dg1) + dot(f2, dg2);\n" - "\n" - " color.x = v;\n" - " color.y = dv_dx;\n" - " color.z = dv_dy;\n" - " } else if (presmoothing == 2) {\n" - " // This is the (odd) binomial kernel 0 1 4 6 4 1 0\n" - " const vec4 f1 = vec4(0, 1, 4, 6) / 16.0f;\n" - " const vec3 f2 = vec3(4, 1, 0) / 16.0f;\n" - "\n" - " const vec4 df1 = vec4(-1, -4, -5, 0) / 32.0f;\n" - " const vec3 df2 = vec3(5, 4, 1) / 32.0f;\n" - "\n" - " vec4 rawVal1, rawVal2, rawVal3, rawVal4, rawVal5, rawVal6, rawVal7;\n" - "\n" - " rawVal1 = texture2D(src_tex, st0.xy);\n" - " rawVal2 = texture2D(src_tex, st0.zw);\n" - " rawVal3 = texture2D(src_tex, st1.xy);\n" - " rawVal4 = texture2D(src_tex, st1.zw);\n" - " rawVal5 = texture2D(src_tex, st2.xy);\n" - " rawVal6 = texture2D(src_tex, st2.zw);\n" - " rawVal7 = texture2D(src_tex, st3.xy);\n" - "\n" - " vec4 g1, dg1;\n" - " vec3 g2, dg2;\n" - "\n" - " g1.x = rawVal1.x;\n" - " dg1.x = rawVal1.y;\n" - " g1.y = rawVal2.x;\n" - " dg1.y = rawVal2.y;\n" - " g1.z = rawVal3.x;\n" - " dg1.z = rawVal3.y;\n" - " g1.w = rawVal4.x;\n" - " dg1.w = rawVal4.y;\n" - " g2.x = rawVal5.x;\n" - " dg2.x = rawVal5.y;\n" - " g2.y = rawVal6.x;\n" - " dg2.y = rawVal6.y;\n" - " g2.z = rawVal7.x;\n" - " dg2.z = rawVal7.y;\n" - "\n" - " float v = dot(f1, g1) + dot(f2, g2);\n" - " float dv_dx = dot(df1, g1) + dot(df2, g2);\n" - " float dv_dy = dot(f1, dg1) + dot(f2, dg2);\n" - "\n" - " color.x = v;\n" - " color.y = dv_dx;\n" - " color.z = dv_dy;\n" - " } else if (presmoothing == 1) {\n" - " // This is the (odd) binomial kernel 0 1 2 1 0\n" - " const vec4 f1 = vec4(0, 1, 2, 1) / 4.0f;\n" - " // Note: f2 = 0.\n" - "\n" - " const vec4 df1 = vec4(-1, -2, 0, 2) / 8.0f;\n" - " const float df2 = 1.0 / 8.0f;\n" - "\n" - " vec4 rawVal1, rawVal2, rawVal3, rawVal4, rawVal5;\n" - "\n" - " rawVal1 = texture2D(src_tex, st0.zw);\n" - " rawVal2 = texture2D(src_tex, st1.xy);\n" - " rawVal3 = texture2D(src_tex, st1.zw);\n" - " rawVal4 = texture2D(src_tex, st2.xy);\n" - " rawVal5 = texture2D(src_tex, st2.zw);\n" - "\n" - " vec4 g1, dg1;\n" - " float g2, dg2;\n" - "\n" - " g1.x = rawVal1.x;\n" - " dg1.x = rawVal1.y;\n" - " g1.y = rawVal2.x;\n" - " dg1.y = rawVal2.y;\n" - " g1.z = rawVal3.x;\n" - " dg1.z = rawVal3.y;\n" - " g1.w = rawVal4.x;\n" - " dg1.w = rawVal4.y;\n" - " g2 = rawVal5.x;\n" - " dg2 = rawVal5.y;\n" - "\n" - " float v = dot(f1, g1);\n" - " float dv_dx = dot(df1, g1) + df2*g2;\n" - " float dv_dy = dot(f1, dg1);\n" - "\n" - " color.x = v;\n" - " color.y = dv_dx;\n" - " color.z = dv_dy;\n" - " } else if (presmoothing == 4) {\n" - " // This is the (odd) kernel 0 1 6 1 0\n" - " const vec4 f1 = vec4(0, 1, 6, 1) / 8.0f;\n" - " // Note: f2 = 0.\n" - "\n" - " const vec4 df1 = vec4(-1, -6, 0, 6) / 16.0f;\n" - " const float df2 = 1.0 / 16.0f;\n" - "\n" - " vec4 rawVal1, rawVal2, rawVal3, rawVal4, rawVal5;\n" - "\n" - " rawVal1 = texture2D(src_tex, st0.zw);\n" - " rawVal2 = texture2D(src_tex, st1.xy);\n" - " rawVal3 = texture2D(src_tex, st1.zw);\n" - " rawVal4 = texture2D(src_tex, st2.xy);\n" - " rawVal5 = texture2D(src_tex, st2.zw);\n" - "\n" - " vec4 g1, dg1;\n" - " float g2, dg2;\n" - "\n" - " g1.x = rawVal1.x;\n" - " dg1.x = rawVal1.y;\n" - " g1.y = rawVal2.x;\n" - " dg1.y = rawVal2.y;\n" - " g1.z = rawVal3.x;\n" - " dg1.z = rawVal3.y;\n" - " g1.w = rawVal4.x;\n" - " dg1.w = rawVal4.y;\n" - " g2 = rawVal5.x;\n" - " dg2 = rawVal5.y;\n" - "\n" - " float v = dot(f1, g1);\n" - " float dv_dx = dot(df1, g1) + df2*g2;\n" - " float dv_dy = dot(f1, dg1);\n" - "\n" - " color.x = v;\n" - " color.y = dv_dx;\n" - " color.z = dv_dy;\n" - " } else {\n" - " // This is the (odd and degenerate) binomial kernel 0 0 1 0 0\n" - " const vec4 f1 = vec4(0, 0, 1, 0);\n" - " // Note: f2 = 0.\n" - "\n" - " const vec4 df1 = vec4(0, -1, 0, 1) / 2.0f;\n" - "\n" - " vec4 rawVal1, rawVal2, rawVal3, rawVal4, rawVal5;\n" - "\n" - " rawVal1 = texture2D(src_tex, st0.zw);\n" - " rawVal2 = texture2D(src_tex, st1.xy);\n" - " rawVal3 = texture2D(src_tex, st1.zw);\n" - " rawVal4 = texture2D(src_tex, st2.xy);\n" - " rawVal5 = texture2D(src_tex, st2.zw);\n" - "\n" - " vec4 g1;\n" - " vec4 dg1;\n" - "\n" - " g1.x = rawVal1.x;\n" - " dg1.x = rawVal1.y;\n" - " g1.y = rawVal2.x;\n" - " dg1.y = rawVal2.y;\n" - " g1.z = rawVal3.x;\n" - " dg1.z = rawVal3.y;\n" - " g1.w = rawVal4.x;\n" - " dg1.w = rawVal4.y;\n" - "\n" - " float v = dot(f1, g1);\n" - " float dv_dx = dot(df1, g1);\n" - " float dv_dy = dot(f1, dg1);\n" - "\n" - " color.x = v;\n" - " color.y = dv_dx;\n" - " color.z = dv_dy;\n" - " }\n" - "\n" - " my_FragColor.rgb = color;\n" - "}\n" - "\n"; - - const std::string pyramid_with_derivative_pass2 = - "#version 330\n" - "\n" - "uniform sampler2D src_tex;\n" - "\n" - "in vec4 gl_TexCoord4;\n" - "\n" - "out vec4 my_FragColor;\n" - "\n" - "void main()\n" - "{\n" - " vec4 st0 = gl_TexCoord0;\n" - " vec4 st1 = gl_TexCoord1;\n" - "\n" - " vec3 val1 = texture2D(src_tex, st0.xy).xyz;\n" - " vec3 val2 = texture2D(src_tex, st0.zw).xyz;\n" - " vec3 val3 = texture2D(src_tex, st1.xy).xyz;\n" - " vec3 val4 = texture2D(src_tex, st1.zw).xyz;\n" - "\n" - " // This is the (even) binomial kernel 1 3 3 1\n" - " my_FragColor.rgb = (val1 + 3*val2 + 3*val3 + val4) / 8.0f;\n" - " //my_FragColor.rgb = (0*val1 + val2 + 2*val3 + val4) / 4.0f;\n" - " //my_FragColor.rgb = (val2 + val3) / 2.0f;\n" - "}\n"; - - const std::string tvl1_color_flow_QR_update_uv = - "#version 330\n" - "\n" - "uniform sampler2D uv_src;\n" - "uniform sampler2D p_uv_src;\n" - "uniform sampler2D warped_R_tex;\n" - "uniform sampler2D warped_G_tex;\n" - "uniform sampler2D warped_B_tex;\n" - "\n" - "in vec4 gl_TexCoord4;\n" - "\n" - "out vec4 my_FragColor;" - "\n" - "uniform float lambda_theta;\n" - "uniform float theta;\n" - "\n" - "vec3 thresholdingStep(vec3 a2, vec3 b, float lambda_theta)\n" - "{\n" - " vec3 lam_a2 = lambda_theta * a2;\n" - " vec3 result;\n" - " result.x = (b.x + lam_a2.x < 0) ? lambda_theta : ((b.x - lam_a2.x > 0) ? -lambda_theta : (-b.x/a2.x));\n" - " result.y = (b.y + lam_a2.y < 0) ? lambda_theta : ((b.y - lam_a2.y > 0) ? -lambda_theta : (-b.y/a2.y));\n" - " result.z = (b.z + lam_a2.z < 0) ? lambda_theta : ((b.z - lam_a2.z > 0) ? -lambda_theta : (-b.z/a2.z));\n" - " return result;\n" - "}\n" - "\n" - "void main(void)\n" - "{\n" - " vec2 st0 = gl_TexCoord0.st;\n" - " vec4 stEW = gl_TexCoord1;\n" - " vec4 stSN = gl_TexCoord2;\n" - "\n" - " vec3 warped_R = texture2D(warped_R_tex, st0).xyz;\n" - " vec3 warped_G = texture2D(warped_G_tex, st0).xyz;\n" - " vec3 warped_B = texture2D(warped_B_tex, st0).xyz;\n" - "\n" - " // Normalize here to allow lower precision for the warped buffer\n" - " warped_R /= 255;\n" - " warped_G /= 255;\n" - " warped_B /= 255;\n" - "\n" - " vec2 stW = stEW.zw;\n" - " vec2 stN = stSN.zw;\n" - "\n" - " bool isLeftBorder = (stW.x < 0);\n" - " bool isRightBorder = (stEW.x > 1);\n" - " bool isTopBorder = (stN.y < 0);\n" - " bool isBottomBorder = (stSN.y > 1);\n" - "\n" - " vec2 uv = texture2D(uv_src, st0).xy;\n" - "\n" - " vec4 p_uv = texture2D(p_uv_src, st0);\n" - " vec2 p1_W_uv = texture2D(p_uv_src, stW).xy;\n" - " vec2 p2_N_uv = texture2D(p_uv_src, stN).zw;\n" - "\n" - " p1_W_uv = isLeftBorder ? vec2(0.0f) : p1_W_uv;\n" - " p2_N_uv = isTopBorder ? vec2(0.0f) : p2_N_uv;\n" - " p_uv.xy = isRightBorder ? vec2(0.0f) : p_uv.xy;\n" - " p_uv.zw = isBottomBorder ? vec2(0.0f) : p_uv.zw;\n" - "\n" - " vec2 div_p = p_uv.xy - p1_W_uv + p_uv.zw - p2_N_uv;\n" - "\n" - " // new u and v\n" - " vec3 b = vec3(0);\n" - " b.x = dot(warped_R, vec3(1, uv));\n" - " b.y = dot(warped_G, vec3(1, uv));\n" - " b.z = dot(warped_B, vec3(1, uv));\n" - "\n" - " vec3 r2 = vec3(0);\n" - " r2.x = dot(warped_R.yz, warped_R.yz);\n" - " r2.y = dot(warped_G.yz, warped_G.yz);\n" - " r2.z = dot(warped_B.yz, warped_B.yz);\n" - "\n" - " vec3 step = thresholdingStep(r2, b, lambda_theta);\n" - "\n" - " vec2 UV = vec2(0.0f);\n" - " UV.x += dot(step, vec3(warped_R.y, warped_G.y, warped_B.y));\n" - " UV.y += dot(step, vec3(warped_R.z, warped_G.z, warped_B.z));\n" - " UV /= 3.0;\n" - " UV += uv;\n" - "\n" - " vec2 uv_out = UV + theta * div_p;\n" - "\n" - " my_FragColor = vec4(uv_out.x, uv_out.y, 0.0f, 0.0f);\n" - "}\n" - "\n"; -}
View file
slowmoVideo-0.4.tar.gz/src/V3D/GL/glsl_shaders.h
Deleted
@@ -1,16 +0,0 @@ -#ifndef GLSL_SHADERS_H -#define GLSL_SHADERS_H - -#include <string> - -namespace GLSL_Shaders -{ - extern const std::string flow_warp_image; - extern const std::string pyramid_with_derivative_pass1h; - extern const std::string pyramid_with_derivative_pass1v; - extern const std::string pyramid_with_derivative_pass2; - extern const std::string tvl1_color_flow_QR_update_uv; - extern const std::string tvl1_flow_new_update_p; -} - -#endif
View file
slowmoVideo-0.4.tar.gz/src/V3D/GL/v3d_gpubase.cpp
Deleted
@@ -1,1230 +0,0 @@ - -#include "config.h" - -#if defined(V3DLIB_ENABLE_GPGPU) - -#include "v3d_gpubase.h" -#include "Base/v3d_exception.h" - -#include <sstream> -#include <iostream> -#include <fstream> -#include <stdlib.h> -#include <string.h> - -#include <GL/glew.h> - -#ifdef WIN32 -#include <stdio.h> -#endif - -namespace -{ - unsigned int const extPixelFormat = { 0, GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_RGB, GL_RGBA }; - - inline int - intFromString(std::string const& value, int defaultVal) - { - if (value.empty()) return defaultVal; - return atoi(value.c_str()); - } // end intFromString() - - template <typename T> - inline void - interleavePixels(int const w, int const h, T const * red, T const * green, T const * blue, T * pixels) - { - for (int p = 0; p < w*h; ++p) - { - pixels3*p+0 = redp; - pixels3*p+1 = greenp; - pixels3*p+2 = bluep; - } - } // end interleavePixels() - - template <typename T> - inline void - interleavePixels(int const w, int const h, T const * red, T const * green, T const * blue, T const * alpha, - T * pixels) - { - for (int p = 0; p < w*h; ++p) - { - pixels4*p+0 = redp; - pixels4*p+1 = greenp; - pixels4*p+2 = bluep; - pixels4*p+3 = alphap; - } - } // end interleavePixels() - -} // end namespace <> - -namespace V3D_GPU -{ - - using namespace std; - - TextureSpecification::TextureSpecification(char const * specString) - : nChannels(3), nBitsPerChannel(8), isFloatTexture(false), isDepthTexture(false), - isRTT(true), enableTextureRG(false) - { - istringstream is(specString); - - string token, key, value; - - while (!is.eof()) - { - is >> token; - - string::size_type pos = 0; - - if ((pos = token.find("=")) != token.npos) - { - key = token.substr(0, pos); - value = token.substr(pos+1, token.length()-pos+1); - } - else - { - key = token; - value = ""; - } - - if (key == "r") - { - this->nChannels = 1; - if (value.find("f") != value.npos) - this->isFloatTexture = true; - this->nBitsPerChannel = intFromString(value, this->isFloatTexture ? 32 : 8); - } - else if (key == "rg") - { - this->nChannels = 2; - if (value.find("f") != value.npos) - this->isFloatTexture = true; - this->nBitsPerChannel = intFromString(value, this->isFloatTexture ? 32 : 8); - } - else if (key == "rgb") - { - this->nChannels = 3; - if (value.find("f") != value.npos) - this->isFloatTexture = true; - this->nBitsPerChannel = intFromString(value, this->isFloatTexture ? 32 : 8); - } - else if (key == "rgba") - { - this->nChannels = 4; - if (value.find("f") != value.npos) - this->isFloatTexture = true; - this->nBitsPerChannel = intFromString(value, this->isFloatTexture ? 32 : 8); - } - else if (key == "depth") - { - this->isDepthTexture = true; - this->nBitsPerChannel = intFromString(value, 24); - } - else if (key == "RTT") - { - this->isRTT = true; - } - else if (key == "noRTT") - { - this->isRTT = false; - } - else if (key == "enableTextureRG") - { -#if defined(GL_ARB_texture_rg) - this->enableTextureRG = true; -#endif - } - else if (key == "tex2D") - { - // Ignore that keyword - } - else - { - cerr << "TextureSpecification::TextureSpecification(): " - << "Warning Unknown keyword: '" << key << "'; ignored." << endl; - } - } // end while - - if ((this->nChannels < 3) && this->isRTT && !this->enableTextureRG) - { - cerr << "TextureSpecification::TextureSpecification(): " - << "Warning: luminance or luminance/alpha texture will not work as render target." << endl; - } - } // end TextureSpecification::TextureSpecification() - - unsigned int - TextureSpecification::getGLInternalFormat() const - { - if (!this->isDepthTexture) - { - if (!this->enableTextureRG) - { - if (!this->isFloatTexture) - { - if (this->nBitsPerChannel == 8) - { - unsigned int const formats5 = { 0, - GL_LUMINANCE8, - GL_LUMINANCE8_ALPHA8, - GL_RGB8, - GL_RGBA8 }; - return formatsthis->nChannels; - } - else if (this->nBitsPerChannel == 16) - { - unsigned int const formats5 = { 0, - GL_LUMINANCE16, - GL_LUMINANCE16_ALPHA16, - GL_RGB16, - GL_RGBA16 }; - return formatsthis->nChannels; - } - else - { - raiseGLErrorHere1("Unsupported number of bits for int texture (8 or 16 bits)."); - } - } - else - { - if (this->nBitsPerChannel == 32) - { - unsigned int const formats5 = { 0, - GL_LUMINANCE32F_ARB, - GL_LUMINANCE_ALPHA32F_ARB, - GL_RGB32F_ARB, - GL_RGBA32F_ARB }; - return formatsthis->nChannels; - } - else if (this->nBitsPerChannel == 16) - { - unsigned int const formats5 = { 0, - GL_LUMINANCE16F_ARB, - GL_LUMINANCE_ALPHA16F_ARB, - GL_RGB16F_ARB, - GL_RGBA16F_ARB }; - return formatsthis->nChannels; - } - else - { - raiseGLErrorHere1("Unsupported number of bits for float texture (16 or 32 bits)."); - } - } // end if (!useFloat) - } - else - { -#if defined(GL_ARB_texture_rg) - // Note: this requires the ARB_texture_rg extension - if (!this->isFloatTexture) - { - if (this->nBitsPerChannel == 8) - { - unsigned int const formats5 = { 0, - GL_R8, - GL_RG8, - GL_RGB8, - GL_RGBA8 }; - return formatsthis->nChannels; - } - else if (this->nBitsPerChannel == 16) - { - unsigned int const formats5 = { 0, - GL_R16, - GL_RG16, - GL_RGB16, - GL_RGBA16 }; - return formatsthis->nChannels; - } - else - { - raiseGLErrorHere1("Unsupported number of bits for int texture (8 or 16 bits)."); - } - } - else - { - if (this->nBitsPerChannel == 32) - { - unsigned int const formats5 = { 0, - GL_R32F, - GL_RG32F, - GL_RGB32F_ARB, - GL_RGBA32F_ARB }; - return formatsthis->nChannels; - } - else if (this->nBitsPerChannel == 16) - { - unsigned int const formats5 = { 0, - GL_R16F, - GL_RG16F, - GL_RGB16F_ARB, - GL_RGBA16F_ARB }; - return formatsthis->nChannels; - } - else - { - raiseGLErrorHere1("Unsupported number of bits for float texture (16 or 32 bits)."); - } - } // end if (!useFloat) -#else - raiseGLErrorHere1("Attempting to use ARB_texture_rg, but support is not compiled in."); -#endif - } // end if ((!this->enableTextureRG) - } - else - { - switch (nBitsPerChannel) - { - case 16: - return GL_DEPTH_COMPONENT16_ARB; - case 24: - return GL_DEPTH_COMPONENT24_ARB; - case 32: - return GL_DEPTH_COMPONENT32_ARB; - default: - raiseGLErrorHere1("Unsupported number of bits for depth texture (16, 24 or 32 bits)."); - } - } // end if (!isDepthTexture) - return 0; - } // end TextureSpecification::getGLInternalFormat() - -//---------------------------------------------------------------------- - - bool - ImageTexture2D::allocateID() - { - _textureTarget = GL_TEXTURE_2D; - glGenTextures(1, &_textureID); - - glBindTexture(_textureTarget, _textureID); - - // Default is clamp to edge and nearest filtering. - glTexParameteri(_textureTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(_textureTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(_textureTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(_textureTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - checkGLErrorsHere1(_texName); - return true; - } - - void - ImageTexture2D::deallocateID() - { - if (_textureID == 0) return; - this->clear(); - glDeleteTextures(1, &_textureID); - _textureID = 0; - checkGLErrorsHere1(_texName); - } - - void - ImageTexture2D::reserve(int width, int height, TextureSpecification const& texSpec) - { - _width = width; - _height = height; - - unsigned internalFormat = texSpec.getGLInternalFormat(); - unsigned format = texSpec.isDepthTexture ? GL_DEPTH_COMPONENT : GL_RGBA; - unsigned type = texSpec.isFloatTexture ? GL_FLOAT : GL_UNSIGNED_BYTE; - - glBindTexture(_textureTarget, _textureID); - glTexImage2D(_textureTarget, 0, internalFormat, _width, _height, 0, format, type, 0); - checkGLErrorsHere1(_texName); - } - - void - ImageTexture2D::overwriteWith(uchar const * pixels, int nChannels) - { - unsigned const format = extPixelFormatnChannels; - unsigned const type = GL_UNSIGNED_BYTE; - - glBindTexture(_textureTarget, _textureID); - glTexSubImage2D(_textureTarget, 0, 0, 0, _width, _height, format, type, pixels); - checkGLErrorsHere1(_texName); - } - - void - ImageTexture2D::overwriteWith(uchar const * redPixels, uchar const * greenPixels, uchar const * bluePixels) - { - unsigned const format = extPixelFormat3; - unsigned const type = GL_UNSIGNED_BYTE; - - unsigned char * pixels = new unsigned char3 * _width * _height; - - interleavePixels(_width, _height, redPixels, greenPixels, bluePixels, pixels); - glBindTexture(_textureTarget, _textureID); - glTexSubImage2D(_textureTarget, 0, 0, 0, _width, _height, format, type, pixels); - - delete pixels; - checkGLErrorsHere1(_texName); - } - - void - ImageTexture2D::overwriteWith(uchar const * redPixels, uchar const * greenPixels, - uchar const * bluePixels, uchar const * alphaPixels) - { - unsigned const format = extPixelFormat4; - unsigned const type = GL_UNSIGNED_BYTE; - - unsigned char * pixels = new unsigned char4 * _width * _height; - - interleavePixels(_width, _height, redPixels, greenPixels, bluePixels, alphaPixels, pixels); - glBindTexture(_textureTarget, _textureID); - glTexSubImage2D(_textureTarget, 0, 0, 0, _width, _height, format, type, pixels); - - delete pixels; - checkGLErrorsHere1(_texName); - } - - void - ImageTexture2D::overwriteWith(float const * pixels, int nChannels) - { - unsigned const format = extPixelFormatnChannels; - unsigned const type = GL_FLOAT; - - glBindTexture(_textureTarget, _textureID); - glTexSubImage2D(_textureTarget, 0, 0, 0, _width, _height, format, type, pixels); - checkGLErrorsHere1(_texName); - } - - void - ImageTexture2D::overwriteWith(float const * redPixels, float const * greenPixels, float const * bluePixels) - { - unsigned const format = extPixelFormat3; - unsigned const type = GL_FLOAT; - - float * pixels = new float3 * _width * _height; - - interleavePixels(_width, _height, redPixels, greenPixels, bluePixels, pixels); - glBindTexture(_textureTarget, _textureID); - glTexSubImage2D(_textureTarget, 0, 0, 0, _width, _height, format, type, pixels); - - delete pixels; - checkGLErrorsHere1(_texName); - } - - void - ImageTexture2D::overwriteWith(float const * redPixels, float const * greenPixels, - float const * bluePixels, float const * alphaPixels) - { - unsigned const format = extPixelFormat4; - unsigned const type = GL_FLOAT; - - float * pixels = new float4 * _width * _height; - - interleavePixels(_width, _height, redPixels, greenPixels, bluePixels, alphaPixels, pixels); - glBindTexture(_textureTarget, _textureID); - glTexSubImage2D(_textureTarget, 0, 0, 0, _width, _height, format, type, pixels); - - delete pixels; - checkGLErrorsHere1(_texName); - } - - void - ImageTexture2D::clear() - { - glBindTexture(_textureTarget, _textureID); - glTexImage2D(_textureTarget, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); - checkGLErrorsHere1(_texName); - } - - void - ImageTexture2D::bind() - { - glBindTexture(_textureTarget, _textureID); - } - - void - ImageTexture2D::bind(unsigned texUnit) - { - glActiveTexture(texUnit); - this->bind(); - } - - void - ImageTexture2D::enable() - { - glBindTexture(_textureTarget, _textureID); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - glEnable(_textureTarget); - } - - void - ImageTexture2D::enable(unsigned texUnit) - { - glActiveTexture(texUnit); - this->enable(); - } - - void - ImageTexture2D::disable() - { - glDisable(_textureTarget); - } - - void - ImageTexture2D::disable(unsigned texUnit) - { - glActiveTexture(texUnit); - this->disable(); - } - -//---------------------------------------------------------------------- - - bool - FrameBufferObject::allocate() - { - glGenFramebuffersEXT(1, &_fboID); - checkGLErrorsHere1(_fboName); - return true; - } - - void - FrameBufferObject::deallocate() - { - std::fill(_attachedColorTextures, _attachedColorTextures+16, (ImageTexture2D *)0); - glDeleteFramebuffersEXT(1, &_fboID); - checkGLErrorsHere1(_fboName); - } - - void - FrameBufferObject::makeCurrent() - { - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, _fboID); - checkGLErrorsHere1(_fboName); - } - - void - FrameBufferObject::activate(bool setViewport) - { - this->makeCurrent(); - if (this->checkValidity()) - { - if (setViewport) - glViewport(0, 0, this->width(), this->height()); - } - } - - bool - FrameBufferObject::isCurrent() - { - GLint curFboID; - glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &curFboID); - return ((int)_fboID == curFboID); - } - - void - FrameBufferObject::attachTexture2D(ImageTexture2D& texture, GLenum attachment, int mipLevel) - { - if (this->checkBinding("FrameBufferObject::attachTexture2D()")) - { - if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT) - { - glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, attachment, - texture.textureTarget(), texture.textureID(), mipLevel); - _attachedColorTexturesattachment - GL_COLOR_ATTACHMENT0_EXT = &texture; - } - else if (attachment == GL_DEPTH_ATTACHMENT_EXT) - { - glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, attachment, - texture.textureTarget(), texture.textureID(), mipLevel); - _attachedDepthTexture = &texture; - } - else - raiseGLErrorHere2("Unknown/unsupported attachment specifier", _fboName.c_str()); - } - checkGLErrorsHere1(_fboName); - } - - void - FrameBufferObject::attachTextures2D(int numTextures, ImageTexture2D * textures, - GLenum * attachment, int * mipLevel) - { - for (int i = 0; i < numTextures; ++i) - this->attachTexture2D(texturesi, - (attachment != 0) ? attachmenti : (GL_COLOR_ATTACHMENT0_EXT + i), - (mipLevel != 0) ? mipLeveli : 0); - } - - void - FrameBufferObject::detach(GLenum attachment) - { - if (this->checkBinding("FrameBufferObject::detach()")) - { - if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT) - { - glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, attachment, GL_TEXTURE_2D, 0, 0); - _attachedColorTexturesattachment - GL_COLOR_ATTACHMENT0_EXT = 0; - } - else if (attachment == GL_DEPTH_ATTACHMENT_EXT) - { - glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, attachment, GL_TEXTURE_2D, 0, 0); - _attachedDepthTexture = 0; - } - else - raiseGLErrorHere2("Unknown/unsupported attachment specifier", _fboName.c_str()); - } - checkGLErrorsHere1(_fboName); - } - - void - FrameBufferObject::detachAll() - { - int const numAttachments = this->getMaxColorAttachments(); - for (int i = 0; i < numAttachments; ++i) - this->detach(GL_COLOR_ATTACHMENT0_EXT + i); - } - -# ifndef NDEBUG_GL - bool - FrameBufferObject::checkValidity(std::ostream& os) - { - if (!this->checkBinding("FrameBufferObject::checkValidity()")) - return false; - - GLenum const status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); - - switch(status) - { - case GL_FRAMEBUFFER_COMPLETE_EXT: // Everything's OK - return true; - case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT: - raiseGLErrorHere2("Frame buffer is incomplete (GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT) ", _fboName.c_str()); - return false; - case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT: - raiseGLErrorHere2("Frame buffer is incomplete (GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT) ", _fboName.c_str()); - return false; - case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT: - raiseGLErrorHere2("Frame buffer is incomplete (GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT) ", _fboName.c_str()); - return false; - case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT: - raiseGLErrorHere2("Frame buffer is incomplete (GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT) ", _fboName.c_str()); - return false; - case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT: - raiseGLErrorHere2("Frame buffer is incomplete (GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT) ", _fboName.c_str()); - return false; - case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT: - raiseGLErrorHere2("Frame buffer is incomplete (GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT) ", _fboName.c_str()); - return false; - case GL_FRAMEBUFFER_UNSUPPORTED_EXT: - raiseGLErrorHere2("Frame buffer is incomplete (GL_FRAMEBUFFER_UNSUPPORTED_EXT) ", _fboName.c_str()); - return false; - default: - raiseGLErrorHere2("Frame buffer is incomplete (unknown error code) ", _fboName.c_str()); - return false; - } - return false; - } -# endif - - int - FrameBufferObject::getMaxColorAttachments() - { - GLint res = 0; - glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS_EXT, &res); - return res; - } - - void - FrameBufferObject::disableFBORendering() - { - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); - } - - bool - FrameBufferObject::checkBinding(char const * what) - { - GLint curFboID; - glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &curFboID); - - ostringstream oss; - oss << "FBO operation (" << what << ") on unbound frame buffer attempted"; - - if (curFboID != (int)_fboID) - { - raiseGLErrorHere2(oss.str().c_str(), this->_fboName); - return false; - } - return true; - } - -//---------------------------------------------------------------------- - -# ifndef NDEBUG_GL - void - checkGLErrors(char const * location, ostream& os) - { - GLuint errnum; - char const * errstr; - bool hasError = false; - std::cout << "error checking\n"; - while ((errnum = glGetError())) - { - errstr = reinterpret_cast<const char *>(gluErrorString(errnum)); - if (errstr) - os << errstr; - else - os << "Error " << errnum; - - os << " at " << location << endl; -#ifdef WIN32 - break; -#endif - } - if(hasError) - throwV3DErrorHere(""); - } - - void - checkGLErrors(char const * file, int line, ostream& os) - { - GLuint errnum; - char const * errstr; - bool hasError = false; - std::cout << "error checking\n"; - while ((errnum = glGetError())) - { - hasError = true; - errstr = reinterpret_cast<const char *>(gluErrorString(errnum)); - if (errstr) - os << errstr; - else - os << "Error " << errnum; - - os << " at " << file << ":" << line << endl; -#ifdef WIN32 - break; -#endif - } - if(hasError) - throwV3DErrorHere(""); - } - - void - checkGLErrors(char const * file, int line, string const& name, ostream& os) - { - GLuint errnum; - char const * errstr; - bool hasError = false; - std::cout << "error checking\n"; - while ((errnum = glGetError())) - { - errstr = reinterpret_cast<const char *>(gluErrorString(errnum)); - if (errstr) - os << errstr; - else - os << "Error " << errnum; - - os << " with " << name << " at " << file << ":" << line << endl; -#ifdef WIN32 - break; -#endif - } - if(hasError) - throwV3DErrorHere(""); - } - - bool - checkFrameBufferStatus(char const * file, int line, std::string const& name, std::ostream& os) - { - GLenum const status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); - - char const * msg = 0; - - switch(status) - { - case GL_FRAMEBUFFER_COMPLETE_EXT: // Everything's OK - return true; - case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT: - msg = "Frame buffer is incomplete (GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT) "; - break; - case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT: - msg = "Frame buffer is incomplete (GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT) "; - break; - case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT: - msg = "Frame buffer is incomplete (GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT) "; - break; - case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT: - msg = "Frame buffer is incomplete (GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT) "; - break; - case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT: - msg = "Frame buffer is incomplete (GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT) "; - break; - case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT: - msg = "Frame buffer is incomplete (GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT) "; - break; - case GL_FRAMEBUFFER_UNSUPPORTED_EXT: - msg = "Frame buffer is incomplete (GL_FRAMEBUFFER_UNSUPPORTED_EXT) "; - break; - default: - msg = "Frame buffer is incomplete (unknown error code) "; - break; - } - os << msg << " with " << name << " at " << file << ":" << line << endl; - return false; - } // end checkFrameBufferStatus() - -# endif - - void - raiseGLError(char const * file, int line, char const * msg, std::ostream& os) - { - os << msg << " at " << file << ":" << line << endl; - } - - void - raiseGLError(char const * file, int line, char const * msg, std::string const& name, std::ostream& os) - { - os << msg << " with " << name << " at " << file << ":" << line << endl; - } - -} // end namespace V3D_GPU - -//---------------------------------------------------------------------- -// CG SHADER ROUTINES -//---------------------------------------------------------------------- - -namespace V3D_GPU -{ - - void - GLSL_FragmentProgram::setProgram(char const * source) - { - _source = source; - // To enforce recompilation. - if (_program) glDeleteObjectARB(_program); - _program = 0; - } - - void - GLSL_FragmentProgram::compile(char const * * compilerArgs, char const *entry) - { - if (compilerArgs != 0) - cerr << "GLSL_FragmentProgram::compile(): arguments to the compiler are not supported (and ignored)." << endl; - if(entry != 0) - cerr << "GLSL_FragmentProgram::compile(): named entry point is not supported (and ignored)." << endl; - - checkGLErrorsHere1(_shaderName); - - if (_program == 0) - { - int len = _source.length() + 1; - GLcharARB * str = new charlen; - strcpy(str, _source.c_str()); - - GLint success = GL_FALSE; - GLint logLength; - - _program = glCreateProgramObjectARB(); - - unsigned fragmentProgram = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB); - glShaderSourceARB(fragmentProgram, 1, (GLcharARB const * *)&str, &len); - glCompileShaderARB(fragmentProgram); - delete str; - - glGetObjectParameterivARB(fragmentProgram, GL_OBJECT_COMPILE_STATUS_ARB, &success); - - if (!success) - { - glGetObjectParameterivARB(fragmentProgram, GL_OBJECT_INFO_LOG_LENGTH_ARB, &logLength); - - GLcharARB * logStr = new GLcharARBlogLength; - glGetInfoLogARB(fragmentProgram, logLength, NULL, logStr); - cout << logStr << endl; - delete logStr; - - glDeleteObjectARB(_program); - _program = 0; - return; - } // end if - - checkGLErrorsHere1(_shaderName); - - glAttachObjectARB(_program, fragmentProgram); - glDeleteObjectARB(fragmentProgram); // To delete the shader if the program is deleted. - - glLinkProgramARB(_program); - - glGetObjectParameterivARB(_program, GL_OBJECT_LINK_STATUS_ARB, &success); - - if (!success) - { - glGetObjectParameterivARB(_program, GL_OBJECT_INFO_LOG_LENGTH_ARB, &logLength); - - GLcharARB * logStr = new GLcharARBlogLength; - glGetInfoLogARB(_program, logLength, NULL, logStr); - cout << logStr << endl; - delete logStr; - - glDeleteObjectARB(_program); - _program = 0; - return; - } // end if - - checkGLErrorsHere1(_shaderName); - - glUseProgramObjectARB(_program); - - { - // Build a mapping from texture parameters to texture units. - _texUnitMap.clear(); - int count, size; - GLenum type; - char paramName1024; - - int texUnit = 0; - - glGetObjectParameterivARB(_program, GL_OBJECT_ACTIVE_UNIFORMS_ARB, &count); - for (int i = 0; i < count; ++i) - { - glGetActiveUniformARB(_program, i, 1024, NULL, &size, &type, paramName); - - switch (type) - { - case GL_SAMPLER_1D_ARB: - case GL_SAMPLER_2D_ARB: - case GL_SAMPLER_3D_ARB: - case GL_SAMPLER_CUBE_ARB: - case GL_SAMPLER_1D_SHADOW_ARB: - case GL_SAMPLER_2D_SHADOW_ARB: - case GL_SAMPLER_2D_RECT_ARB: - case GL_SAMPLER_2D_RECT_SHADOW_ARB: - { - _texUnitMap.insert(make_pair(string(paramName), texUnit)); - int location = glGetUniformLocationARB(_program, paramName); - glUniform1iARB(location, texUnit); - ++texUnit; - break; - } - default: - break; - } // end switch() - } // end for (i) - } - glUseProgramObjectARB(0); - } // end if - - checkGLErrorsHere1(_shaderName); - } // end GLSL_FragmentProgram::compile() - - void - GLSL_FragmentProgram::compile(std::vector<std::string> const& compilerArgs, char const *entry) - { - if (compilerArgs.size() != 0) - cerr << "GLSL_FragmentProgram::compile(): arguments to the compiler are not supported (and ignored)." << endl; - if(entry != 0) - cerr << "GLSL_FragmentProgram::compile(): named entry point is not supported (and ignored)." << endl; - this->compile(); - } - - void - GLSL_FragmentProgram::bindFragDataLocation(const std::string& var) - { - glBindFragDataLocation(_program, 0, var.c_str()); - } - - void - GLSL_FragmentProgram::enable() - { - // implicitly bind FragDataLocation. Maybe this can be done elsewhere once an apropriate interface is available. - bindFragDataLocation("my_FragColor"); - glUseProgramObjectARB(_program); - _inUse = true; - } - - void - GLSL_FragmentProgram::disable() - { - _inUse = false; - glUseProgramObjectARB(0); - } - - void - GLSL_FragmentProgram::bindTexture(const std::string& name, unsigned int unit) - { - glUniform1i(glGetUniformLocation(_program, name.c_str()), unit); - } - - void - GLSL_FragmentProgram::parameter(char const * param, int x) - { - glUseProgramObjectARB(_program); - glUniform1iARB(glGetUniformLocationARB(_program, param), x); - if (!_inUse) glUseProgramObjectARB(0); - } - - void - GLSL_FragmentProgram::parameter(char const * param, float x) - { - glUseProgramObjectARB(_program); - glUniform1fARB(glGetUniformLocationARB(_program, param), x); - if (!_inUse) glUseProgramObjectARB(0); - } - - void - GLSL_FragmentProgram::parameter(char const * param, float x, float y) - { - glUseProgramObjectARB(_program); - glUniform2fARB(glGetUniformLocationARB(_program, param), x, y); - if (!_inUse) glUseProgramObjectARB(0); - } - - void - GLSL_FragmentProgram::parameter(char const * param, float x, float y, float z) - { - glUseProgramObjectARB(_program); - glUniform3fARB(glGetUniformLocationARB(_program, param), x, y, z); - if (!_inUse) glUseProgramObjectARB(0); - } - - void - GLSL_FragmentProgram::parameter(char const * param, float x, float y, float z, float w) - { - glUseProgramObjectARB(_program); - glUniform4fARB(glGetUniformLocationARB(_program, param), x, y, z, w); - if (!_inUse) glUseProgramObjectARB(0); - } - - void - GLSL_FragmentProgram::parameter(char const * param, int len, float const * array) - { - glUseProgramObjectARB(_program); - glUniform1fvARB(glGetUniformLocationARB(_program, param), len, array); - if (!_inUse) glUseProgramObjectARB(0); - } - - void - GLSL_FragmentProgram::matrixParameterR(char const * param, int rows, int cols, double const * values) - { - float * fvalues = new floatrows*cols; - std::copy(values, values+rows*cols, fvalues); - - glUseProgramObjectARB(_program); - - if (rows == 2 && cols == 2) - { - glUniformMatrix2fvARB(glGetUniformLocationARB(_program, param), - 1, GL_TRUE, fvalues); - } - else if (rows == 3 && cols == 3) - { - glUniformMatrix3fvARB(glGetUniformLocationARB(_program, param), - 1, GL_TRUE, fvalues); - } - else if (rows == 4 && cols == 4) - { - glUniformMatrix4fvARB(glGetUniformLocationARB(_program, param), - 1, GL_TRUE, fvalues); - } - else - raiseGLErrorHere2("Matrix parameter should be 2x2, 3x3 or 4x4.", _shaderName.c_str()); - - delete fvalues; - - if (!_inUse) glUseProgramObjectARB(0); - } - - void - GLSL_FragmentProgram::matrixParameterC(char const * param, int rows, int cols, double const * values) - { - float * fvalues = new floatrows*cols; - std::copy(values, values+rows*cols, fvalues); - - glUseProgramObjectARB(_program); - - if (rows == 2 && cols == 2) - { - glUniformMatrix2fvARB(glGetUniformLocationARB(_program, param), - 1, GL_FALSE, fvalues); - } - else if (rows == 3 && cols == 3) - { - glUniformMatrix3fvARB(glGetUniformLocationARB(_program, param), - 1, GL_FALSE, fvalues); - } - else if (rows == 4 && cols == 4) - { - glUniformMatrix4fvARB(glGetUniformLocationARB(_program, param), - 1, GL_FALSE, fvalues); - } - else - raiseGLErrorHere2("Matrix parameter should be 2x2, 3x3 or 4x4.", _shaderName.c_str()); - - delete fvalues; - - if (!_inUse) glUseProgramObjectARB(0); - } - - unsigned - GLSL_FragmentProgram::getTexUnit(char const * param) - { - map<string, int>::const_iterator p = _texUnitMap.find(string(param)); - if (p != _texUnitMap.end()) - return GL_TEXTURE0_ARB + (*p).second; - else - raiseGLErrorHere2("Parameter name denotes no texture sampler.", _shaderName.c_str()); - return 0; - } - -} // end namespace V3D_GPU - -//---------------------------------------------------------------------- - -namespace V3D_GPU -{ - - void - setupNormalizedProjection(bool flipY) - { - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - - if (!flipY) - glOrtho(0, 1, 0, 1, -1, 1); - else - glOrtho(0, 1, 1, 0, -1, 1); - - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - } - - void - renderNormalizedQuad() - { - // It is usually recommended to draw a large (clipped) triangle - // instread of a single quad, therefore avoiding the diagonal edge. - glBegin(GL_TRIANGLES); - glMultiTexCoord2f(GL_TEXTURE0_ARB, 0, 0); - glMultiTexCoord4f(GL_TEXTURE1_ARB, 0, 0, 0, 0); - glMultiTexCoord4f(GL_TEXTURE2_ARB, 0, 0, 0, 0); - glVertex2f(0, 0); - glMultiTexCoord2f(GL_TEXTURE0_ARB, 2, 0); - glMultiTexCoord4f(GL_TEXTURE1_ARB, 2, 0, 2, 0); - glMultiTexCoord4f(GL_TEXTURE2_ARB, 2, 0, 2, 0); - glVertex2f(2, 0); - glMultiTexCoord2f(GL_TEXTURE0_ARB, 0, 2); - glMultiTexCoord4f(GL_TEXTURE1_ARB, 0, 2, 0, 2); - glMultiTexCoord4f(GL_TEXTURE2_ARB, 0, 2, 0, 2); - glVertex2f(0, 2); - glEnd(); - } - - void - renderNormalizedQuad(GPUTextureSamplingPattern pattern, float ds, float dt) - { - switch (pattern) - { - case GPU_SAMPLE_NEIGHBORS: - { - glBegin(GL_TRIANGLES); - glMultiTexCoord2f(GL_TEXTURE0_ARB, 0, 0); - glMultiTexCoord4f(GL_TEXTURE1_ARB, 0-ds, 0, 0+ds, 0); - glMultiTexCoord4f(GL_TEXTURE2_ARB, 0, 0-dt, 0, 0+dt); - glVertex2f(0, 0); - glMultiTexCoord2f(GL_TEXTURE0_ARB, 2, 0); - glMultiTexCoord4f(GL_TEXTURE1_ARB, 2-ds, 0, 2+ds, 0); - glMultiTexCoord4f(GL_TEXTURE2_ARB, 2, 0-dt, 2, 0+dt); - glVertex2f(2, 0); - glMultiTexCoord2f(GL_TEXTURE0_ARB, 0, 2); - glMultiTexCoord4f(GL_TEXTURE1_ARB, 0-ds, 2, 0+ds, 2); - glMultiTexCoord4f(GL_TEXTURE2_ARB, 0, 2-dt, 0, 2+dt); - glVertex2f(0, 2); - glEnd(); - break; - } - case GPU_SAMPLE_REVERSE_NEIGHBORS: - { - glBegin(GL_TRIANGLES); - glMultiTexCoord2f(GL_TEXTURE0_ARB, 0, 0); - glMultiTexCoord4f(GL_TEXTURE1_ARB, 0+ds, 0, 0-ds, 0); - glMultiTexCoord4f(GL_TEXTURE2_ARB, 0, 0+dt, 0, 0-dt); - glVertex2f(0, 0); - glMultiTexCoord2f(GL_TEXTURE0_ARB, 2, 0); - glMultiTexCoord4f(GL_TEXTURE1_ARB, 2+ds, 0, 2-ds, 0); - glMultiTexCoord4f(GL_TEXTURE2_ARB, 2, 0+dt, 2, 0-dt); - glVertex2f(2, 0); - glMultiTexCoord2f(GL_TEXTURE0_ARB, 0, 2); - glMultiTexCoord4f(GL_TEXTURE1_ARB, 0+ds, 2, 0-ds, 2); - glMultiTexCoord4f(GL_TEXTURE2_ARB, 0, 2+dt, 0, 2-dt); - glVertex2f(0, 2); - glEnd(); - break; - } - case GPU_SAMPLE_DIAG_NEIGBORS: - { - glBegin(GL_TRIANGLES); - glMultiTexCoord2f(GL_TEXTURE0_ARB, 0, 0); - glMultiTexCoord4f(GL_TEXTURE1_ARB, 0-ds, 0-dt, 0+ds, 0+dt); - glMultiTexCoord4f(GL_TEXTURE2_ARB, 0+ds, 0-dt, 0-ds, 0+dt); - glVertex2f(0, 0); - glMultiTexCoord2f(GL_TEXTURE0_ARB, 2, 0); - glMultiTexCoord4f(GL_TEXTURE1_ARB, 2-ds, 0-dt, 2+ds, 0+dt); - glMultiTexCoord4f(GL_TEXTURE2_ARB, 2+ds, 0-dt, 2-ds, 0+dt); - glVertex2f(2, 0); - glMultiTexCoord2f(GL_TEXTURE0_ARB, 0, 2); - glMultiTexCoord4f(GL_TEXTURE1_ARB, 0-ds, 2-dt, 0+ds, 2+dt); - glMultiTexCoord4f(GL_TEXTURE2_ARB, 0+ds, 2-dt, 0-ds, 2+dt); - glVertex2f(0, 2); - glEnd(); - break; - } - case GPU_SAMPLE_2X2_BLOCK: - { - glBegin(GL_TRIANGLES); - glMultiTexCoord2f(GL_TEXTURE0_ARB, 0, 0); - glMultiTexCoord4f(GL_TEXTURE1_ARB, 0, 0, 0+ds, 0 ); - glMultiTexCoord4f(GL_TEXTURE2_ARB, 0, 0+dt, 0+ds, 0+dt); - glVertex2f(0, 0); - glMultiTexCoord2f(GL_TEXTURE0_ARB, 2, 0); - glMultiTexCoord4f(GL_TEXTURE1_ARB, 2, 0, 2+ds, 0 ); - glMultiTexCoord4f(GL_TEXTURE2_ARB, 2, 0+dt, 2+ds, 0+dt); - glVertex2f(2, 0); - glMultiTexCoord2f(GL_TEXTURE0_ARB, 0, 2); - glMultiTexCoord4f(GL_TEXTURE1_ARB, 0, 2, 0+ds, 2 ); - glMultiTexCoord4f(GL_TEXTURE2_ARB, 0, 2+dt, 0+ds, 2+dt); - glVertex2f(0, 2); - glEnd(); - break; - } - default: - raiseGLErrorHere1("Unknown sampling pattern."); - } // end switch (pattern) - } // end renderQuadWithTexSampling() - -} // end namespace V3D_GPU - -namespace -{ - V3D_GPU::GLSL_FragmentProgram * trivialTexture2DShader = 0; -} - -namespace V3D_GPU -{ - - void - enableTrivialTexture2DShader() - { - if (trivialTexture2DShader == 0) - { - trivialTexture2DShader = new GLSL_FragmentProgram("trivialTexture2DShader"); - char const * source = - "void main(uniform sampler2D texture, \n" - " float2 st : TEXCOORD0, \n" - " out float4 color : COLOR) \n" - "{ \n" - " color = tex2D(texture, st); \n" - "} \n"; - trivialTexture2DShader->setProgram(source); - trivialTexture2DShader->compile(); - checkGLErrorsHere0(); - } - trivialTexture2DShader->enable(); - } - - void - disableTrivialTexture2DShader() - { - if (trivialTexture2DShader) trivialTexture2DShader->disable(); - } - -} // end namespace V3D_GPU - -#endif // defined(V3DLIB_ENABLE_GPGPU)
View file
slowmoVideo-0.4.tar.gz/src/V3D/GL/v3d_gpubase.h
Deleted
@@ -1,331 +0,0 @@ -// -*- C++ -*- - -#include "config.h" - -#ifndef V3D_GPUBASE_H -#define V3D_GPUBASE_H - -# if defined(V3DLIB_ENABLE_GPGPU) - -#include <vector> -#include <string> -#include <map> -#include <iostream> - -#include <GL/glew.h> - -#define checkGLErrorsHere0() { V3D_GPU::checkGLErrors(__FILE__, __LINE__); } -#define checkGLErrorsHere1(NAME) { V3D_GPU::checkGLErrors(__FILE__, __LINE__, NAME); } -#define raiseGLErrorHere1(MSG) { V3D_GPU::raiseGLError(__FILE__, __LINE__, MSG); } -#define raiseGLErrorHere2(MSG, NAME) { V3D_GPU::raiseGLError(__FILE__, __LINE__, MSG, NAME); } - -namespace V3D_GPU -{ - typedef unsigned char uchar; - - struct TextureSpecification - { - TextureSpecification() - : nChannels(3), nBitsPerChannel(8), isFloatTexture(false), isDepthTexture(false), - isRTT(true), enableTextureRG(false) - { } - - TextureSpecification(char const * specString); - - unsigned int getGLInternalFormat() const; - - uchar nChannels, nBitsPerChannel; - bool isFloatTexture, isDepthTexture; - bool isRTT, enableTextureRG; - }; // end struct TextureSpecification - - struct ImageTexture2D - { - ImageTexture2D(char const * texName = "<unnamed 2D texture>") - : _texName(texName), _textureID(0), _textureTarget(0), _width(0), _height(0) - { } - - virtual ~ImageTexture2D() { } - - bool allocateID(); - void deallocateID(); - - void reserve(int width, int height, TextureSpecification const& texSpec); - - void overwriteWith(uchar const * pixels, int nChannels); - void overwriteWith(uchar const * redPixels, uchar const * greenPixels, uchar const * bluePixels); - void overwriteWith(uchar const * redPixels, uchar const * greenPixels, - uchar const * bluePixels, uchar const * alphaPixels); - - void overwriteWith(float const * pixels, int nChannels); - void overwriteWith(float const * redPixels, float const * greenPixels, float const * bluePixels); - void overwriteWith(float const * redPixels, float const * greenPixels, - float const * bluePixels, float const * alphaPixels); - - void clear(); - - void bind(); - void bind(unsigned texUnit); - - void enable(); - void enable(unsigned texUnit); - void disable(); - void disable(unsigned texUnit); - - unsigned width() const { return _width; } - unsigned height() const { return _height; } - unsigned textureID() const { return _textureID; } - unsigned textureTarget() const { return _textureTarget; } - - protected: - std::string _texName; - - unsigned _textureID; - unsigned _textureTarget; - unsigned _width, _height; - }; // end struct ImageTexture2D - - struct FrameBufferObject - { - FrameBufferObject(char const * fboName = "<unnamed frame buffer object>") - : _fboName(fboName), _attachedDepthTexture(0) - { - std::fill(_attachedColorTextures, _attachedColorTextures+16, (ImageTexture2D *)0); - } - - virtual ~FrameBufferObject() { } - - bool allocate(); - void deallocate(); - - void makeCurrent(); - void activate(bool setViewport = true); - - bool isCurrent(); - - void attachTexture2D(ImageTexture2D& texture, - GLenum attachment = GL_COLOR_ATTACHMENT0_EXT, - int mipLevel = 0); - void attachTextures2D(int numTextures, ImageTexture2D * textures, - GLenum * attachment = 0, int * mipLevel = 0); - - void detach(GLenum attachment); - void detachAll(); - -# ifndef NDEBUG_GL - bool checkValidity(std::ostream& os = std::cerr); -# else - bool checkValidity(std::ostream& os = std::cerr) { return true; } -# endif - - unsigned width() const - { - for (int i = 0; i < 16; ++i) - if (_attachedColorTexturesi) - return _attachedColorTexturesi->width(); - return 0; - } - - unsigned height() const - { - for (int i = 0; i < 16; ++i) - if (_attachedColorTexturesi) - return _attachedColorTexturesi->height(); - return 0; - } - - unsigned frameBufferID() const { return _fboID; } - - ImageTexture2D& getColorTexture(int i) const { return *_attachedColorTexturesi; } - - static int getMaxColorAttachments(); - - static void disableFBORendering(); - - protected: - bool checkBinding(char const * what); - - std::string _fboName; - GLuint _fboID; - ImageTexture2D * _attachedColorTextures16; - ImageTexture2D * _attachedDepthTexture; - }; // end struct FrameBufferObject - - struct RTT_Buffer - { - RTT_Buffer(char const * texSpec = "rgb=8", - char const * rttName = "<unnamed RTT buffer object>") - : _texSpec(texSpec), _tex(rttName), _fbo(rttName) - { } - - virtual ~RTT_Buffer() { } - - bool allocate(int const w, int const h) - { - _tex.allocateID(); - _tex.reserve(w, h, TextureSpecification(_texSpec.c_str())); - _fbo.allocate(); - _fbo.makeCurrent(); - _fbo.attachTexture2D(_tex); - _fbo.checkValidity(); - return true; - } - - bool allocate(char const * texSpec, int const w, int const h) - { - _texSpec = texSpec; - return allocate(w,h); - } - - bool reallocate(int w, int h) - { - _tex.reserve(w, h, TextureSpecification(_texSpec.c_str())); - return true; - } - - void deallocate() - { - _fbo.deallocate(); - _tex.deallocateID(); - } - - unsigned width() const { return _tex.width(); } - unsigned height() const { return _tex.height(); } - unsigned textureID() const { return _tex.textureID(); } - unsigned textureTarget() const { return _tex.textureTarget(); } - - void bindTexture() { _tex.bind(); } - void bindTexture(unsigned texUnit) { _tex.bind(texUnit); } - void enableTexture() { _tex.enable(); } - void enableTexture(unsigned texUnit) { _tex.enable(texUnit); } - void disableTexture() { _tex.disable(); } - void disableTexture(unsigned texUnit) { _tex.disable(texUnit); } - - void makeCurrent() { _fbo.makeCurrent(); } - void activate(bool setViewport = true) { _fbo.activate(setViewport); } - bool isCurrent() { return _fbo.isCurrent(); } - - ImageTexture2D& getTexture() { return _tex; } - FrameBufferObject& getFBO() { return _fbo; } - - protected: - std::string _texSpec; - - ImageTexture2D _tex; - FrameBufferObject _fbo; - }; // end struct RTT_Buffer - -//---------------------------------------------------------------------- - - struct ProgramBase - { - ProgramBase(char const * shaderName) - : _shaderName(shaderName) - { } - - virtual ~ProgramBase() { } - - virtual void setProgram(char const * source) = 0; - virtual void setProgram(std::string const& source) { this->setProgram(source.c_str()); } - - virtual void compile(char const * * compilerArgs = 0, char const *entry = 0) = 0; - virtual void compile(std::vector<std::string> const& compilerArgs, char const *entry = 0) = 0; - virtual void enable() = 0; - virtual void disable() = 0; - - virtual void parameter(char const * param, float x) = 0; - virtual void parameter(char const * param, float x, float y) = 0; - virtual void parameter(char const * param, float x, float y, float z) = 0; - virtual void parameter(char const * param, float x, float y, float z, float w) = 0; - virtual void parameter(char const * param, int len, float const * array) = 0; - virtual void matrixParameterR(char const * param, int rows, int cols, double const * values) = 0; - virtual void matrixParameterC(char const * param, int rows, int cols, double const * values) = 0; - - virtual unsigned getTexUnit(char const * param) = 0; - - std::string const& shaderName() const { return _shaderName; } - - protected: - std::string _shaderName; - }; - - struct GLSL_FragmentProgram : public ProgramBase - { - GLSL_FragmentProgram(char const * shaderName) - : ProgramBase(shaderName), _source(), _program(0), _inUse(false), _texUnitMap() - { } - - virtual ~GLSL_FragmentProgram() { } - - virtual void setProgram(char const * source); - - virtual void compile(char const * * compilerArgs = 0, char const *entry = 0); - virtual void compile(std::vector<std::string> const& compilerArgs, char const *entry = 0); - virtual void bindFragDataLocation(const std::string& var); - virtual void enable(); - virtual void disable(); - - virtual void bindTexture(const std::string& name, unsigned int unit); - virtual void parameter(char const * param, int x); - virtual void parameter(char const * param, float x); - virtual void parameter(char const * param, float x, float y); - virtual void parameter(char const * param, float x, float y, float z); - virtual void parameter(char const * param, float x, float y, float z, float w); - virtual void parameter(char const * param, int len, float const * array); - virtual void matrixParameterR(char const * param, int rows, int cols, double const * values); - virtual void matrixParameterC(char const * param, int rows, int cols, double const * values); - - virtual unsigned getTexUnit(char const * param); - - protected: - std::string _source; - GLhandleARB _program; - bool _inUse; - - std::map<std::string, int> _texUnitMap; - }; - -//---------------------------------------------------------------------- - -# ifndef NDEBUG_GL - void checkGLErrors(char const * location, std::ostream& os = std::cerr); - void checkGLErrors(char const * file, int line, std::ostream& os = std::cerr); - void checkGLErrors(char const * file, int line, std::string const& name, std::ostream& os = std::cerr); - bool checkFrameBufferStatus(char const * file, int line, std::string const& name, std::ostream& os = std::cerr); -# else - inline void checkGLErrors(char const * location, std::ostream& os = std::cerr) { } - inline void checkGLErrors(char const * file, int line, std::ostream& os = std::cerr) { } - inline void checkGLErrors(char const * file, int line, std::string const& name, std::ostream& os = std::cerr) { } - inline bool checkFrameBufferStatus(char const * file, int line, std::string const& name, std::ostream& os = std::cerr) - { - return true; - } -# endif - - void raiseGLError(char const * file, int line, char const * msg, std::ostream& os = std::cerr); - void raiseGLError(char const * file, int line, char const * msg, std::string const& name, std::ostream& os = std::cerr); - - -//---------------------------------------------------------------------- - - enum GPUTextureSamplingPattern - { - GPU_SAMPLE_NONE = 0, - GPU_SAMPLE_NEIGHBORS = 1, //!< Sample the 4 direct neighbors (E, W, N, S) - GPU_SAMPLE_REVERSE_NEIGHBORS = 2, //!< Sample the 4 direct neighbors (W, E, S, N) - GPU_SAMPLE_DIAG_NEIGBORS = 3, //!< Sample the diagonal neighbors (NE, SW, NW, SE) - GPU_SAMPLE_2X2_BLOCK = 4, //!< Sample the 2x2 block (here, E, S, SE) - }; - - void setupNormalizedProjection(bool flipY = false); - void renderNormalizedQuad(); - void renderNormalizedQuad(GPUTextureSamplingPattern pattern, float ds, float dt); - - void enableTrivialTexture2DShader(); - void disableTrivialTexture2DShader(); - -} // end namespace V3D_GPU - -# endif // defined(V3DLIB_ENABLE_GPGPU) - -#endif // defined(V3D_GPUBASE_H)
View file
slowmoVideo-0.4.tar.gz/src/V3D/GL/v3d_gpucolorflow.cpp
Deleted
@@ -1,317 +0,0 @@ -#include "config.h" - -#include "Base/v3d_utilities.h" -#include "v3d_gpucolorflow.h" -#include "glsl_shaders.h" - -#include <iostream> -#include <cmath> -#include <GL/glew.h> - -using namespace std; -using namespace V3D_GPU; - -namespace -{ - const std::string SOURCE( - "#version 330\n" - "\n" - "uniform sampler2D src_tex;\n" - "\n" - "in vec4 gl_TexCoord4;\n" - "\n" - "out vec4 my_FragColor;" - "\n" - "void main(void)\n" - "{\n" - " my_FragColor = gl_TexCoord3 * texture2D(src_tex, gl_TexCoord0.st);\n" - "}\n"); - - void - upsampleDisparities(unsigned uvSrcTex, unsigned pSrcTex, float pScale, - RTT_Buffer& ubuffer, RTT_Buffer& pbuffer) - { - static GLSL_FragmentProgram * upsampleShader = 0; - - if (upsampleShader == 0) - { - upsampleShader = new GLSL_FragmentProgram("v3d_gpuflow::upsampleDisparities::upsampleShader"); - - char const * source = SOURCE.c_str(); - upsampleShader->setProgram(source); - upsampleShader->compile(); - checkGLErrorsHere0(); - } // end if - - setupNormalizedProjection(); - ubuffer.activate(); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, uvSrcTex); - glEnable(GL_TEXTURE_2D); - upsampleShader->enable(); - // Provide uniform paramter via texcoord to avoid recompilation of shaders - glMultiTexCoord4f(GL_TEXTURE3_ARB, 2, 2, 1, 1); - //glMultiTexCoord4f(GL_TEXTURE3_ARB, 0, 0, 0, 0); - renderNormalizedQuad(); - //upsampleShader->disable(); - glDisable(GL_TEXTURE_2D); - checkGLErrorsHere0(); - - pbuffer.activate(); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, pSrcTex); - glEnable(GL_TEXTURE_2D); - //upsampleShader->enable(); - // Provide uniform paramter via texcoord to avoid recompilation of shaders - glMultiTexCoord4f(GL_TEXTURE3_ARB, pScale, pScale, pScale, pScale); - renderNormalizedQuad(); - upsampleShader->disable(); - glDisable(GL_TEXTURE_2D); - checkGLErrorsHere0(); - } // upsampleDisparities() - - void - upsampleDisparities(unsigned uvSrcTex, unsigned pSrcTex, unsigned qSrcTex, float pScale, - RTT_Buffer& ubuffer, RTT_Buffer& pbuffer, RTT_Buffer& qbuffer) - { - static GLSL_FragmentProgram * upsampleShader = 0; - - if (upsampleShader == 0) - { - upsampleShader = new GLSL_FragmentProgram("v3d_gpuflow::upsampleDisparities::upsampleShader"); - - char const * source = SOURCE.c_str(); - upsampleShader->setProgram(source); - upsampleShader->compile(); - checkGLErrorsHere0(); - } // end if - - setupNormalizedProjection(); - ubuffer.activate(); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, uvSrcTex); - glEnable(GL_TEXTURE_2D); - upsampleShader->enable(); - // Provide uniform paramter via texcoord to avoid recompilation of shaders - glMultiTexCoord4f(GL_TEXTURE3_ARB, 2, 2, 1, 1); - //glMultiTexCoord4f(GL_TEXTURE3_ARB, 0, 0, 0, 0); - renderNormalizedQuad(); - //upsampleShader->disable(); - glDisable(GL_TEXTURE_2D); - checkGLErrorsHere0(); - - pbuffer.activate(); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, pSrcTex); - glEnable(GL_TEXTURE_2D); - //upsampleShader->enable(); - // Provide uniform paramter via texcoord to avoid recompilation of shaders - glMultiTexCoord4f(GL_TEXTURE3_ARB, pScale, pScale, pScale, pScale); - renderNormalizedQuad(); - upsampleShader->disable(); - glDisable(GL_TEXTURE_2D); - checkGLErrorsHere0(); - - qbuffer.activate(); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, qSrcTex); - glEnable(GL_TEXTURE_2D); - //upsampleShader->enable(); - // Provide uniform paramter via texcoord to avoid recompilation of shaders - glMultiTexCoord4f(GL_TEXTURE3_ARB, pScale, pScale, pScale, pScale); - renderNormalizedQuad(); - upsampleShader->disable(); - glDisable(GL_TEXTURE_2D); - checkGLErrorsHere0(); - } // upsampleDisparities() - -} // end namespace - -//---------------------------------------------------------------------- - -namespace V3D_GPU -{ - - void - TVL1_ColorFlowEstimatorBase::allocate(int W, int H) - { - _width = W; - _height = H; - - char const * texSpec = _warpedBufferHighPrecision ? "rgba=32f tex2D" : "rgba=16f tex2D"; - - for (int ch = 0; ch < 3; ++ch) - { - _warpedBufferPyramidsch.resize(_nLevels); - for (int level = 0; level < _nLevels; ++level) - { - int const w = _width / (1 << level); - int const h = _height / (1 << level); - - _warpedBufferPyramidschlevel = new RTT_Buffer(texSpec, "_warpedBufferPyramid"); - _warpedBufferPyramidschlevel->allocate(w, h); - } - } // end for (ch) - } // end TVL1_ColorFlowEstimatorBase::allocate() - - void - TVL1_ColorFlowEstimatorBase::deallocate() - { - for (int ch = 0; ch < 3; ++ch) - for (int level = 0; level < _nLevels; ++level) - _warpedBufferPyramidschlevel->deallocate(); - } - -//---------------------------------------------------------------------- - - void - TVL1_ColorFlowEstimator_QR::allocate(int W, int H) - { - TVL1_ColorFlowEstimatorBase::allocate(W, H); - - _shader_uv = new GLSL_FragmentProgram("tvl1_color_flow_new_update_uv"); - _shader_p = new GLSL_FragmentProgram("tvl1_flow_relaxed_update_p"); - _shader_uv->setProgram(GLSL_Shaders::tvl1_color_flow_QR_update_uv.c_str()); - _shader_p->setProgram(GLSL_Shaders::tvl1_flow_new_update_p.c_str()); - _shader_uv->compile(); - _shader_p->compile(); - - _uBuffer1Pyramid.resize(_nLevels); - _uBuffer2Pyramid.resize(_nLevels); - _pBuffer1Pyramid.resize(_nLevels); - _pBuffer2Pyramid.resize(_nLevels); - - char const * uvTexSpec = _uvBufferHighPrecision ? "rg=32f tex2D enableTextureRG" : "rg=16f tex2D enableTextureRG"; - char const * pTexSpec = _pBufferHighPrecision ? "rgba=32f tex2D" : "rgba=16f tex2D"; - - for (int level = 0; level < _nLevels; ++level) - { - int const w = _width / (1 << level); - int const h = _height / (1 << level); - - _uBuffer1Pyramidlevel = new RTT_Buffer(uvTexSpec, "ubuffer1"); - _uBuffer1Pyramidlevel->allocate(w, h); - _uBuffer2Pyramidlevel = new RTT_Buffer(uvTexSpec, "ubuffer2"); - _uBuffer2Pyramidlevel->allocate(w, h); - _pBuffer1Pyramidlevel = new RTT_Buffer(pTexSpec, "pbuffer1"); - _pBuffer1Pyramidlevel->allocate(w, h); - _pBuffer2Pyramidlevel = new RTT_Buffer(pTexSpec, "pbuffer2"); - _pBuffer2Pyramidlevel->allocate(w, h); - } // end for (level) - } // end TVL1_ColorFlowEstimator_QR::allocate() - - void - TVL1_ColorFlowEstimator_QR::deallocate() - { - TVL1_ColorFlowEstimatorBase::deallocate(); - - for (int level = 0; level < _nLevels; ++level) - { - _uBuffer1Pyramidlevel->deallocate(); - _uBuffer2Pyramidlevel->deallocate(); - _pBuffer1Pyramidlevel->deallocate(); - _pBuffer2Pyramidlevel->deallocate(); - } - } // end TVL1_ColorFlowEstimator_QR::deallocate() - - void - TVL1_ColorFlowEstimator_QR::run(unsigned int I0_TexIDs3, unsigned int I1_TexIDs3) - { - for (int level = _nLevels-1; level >= _startLevel; --level) - { - RTT_Buffer * ubuffer1 = _uBuffer1Pyramidlevel; - RTT_Buffer * ubuffer2 = _uBuffer2Pyramidlevel; - RTT_Buffer * pbuffer1 = _pBuffer1Pyramidlevel; - RTT_Buffer * pbuffer2 = _pBuffer2Pyramidlevel; - - float const lambda = _lambda; - - if (level == _nLevels-1) - { - glClearColor(0, 0, 0, 0); - ubuffer2->activate(); - glClear(GL_COLOR_BUFFER_BIT); - pbuffer2->activate(); - glClear(GL_COLOR_BUFFER_BIT); - } - else - { - upsampleDisparities(_uBuffer2Pyramidlevel+1->textureID(), - _pBuffer2Pyramidlevel+1->textureID(), - 1.0f, *ubuffer2, *pbuffer2); - } - - int const w = _width / (1 << level); - int const h = _height / (1 << level); - - RTT_Buffer& warpedBuffer_R = *_warpedBufferPyramids0level; - RTT_Buffer& warpedBuffer_G = *_warpedBufferPyramids1level; - RTT_Buffer& warpedBuffer_B = *_warpedBufferPyramids2level; - - float const ds = 1.0f / w; - float const dt = 1.0f / h; - - _shader_uv->parameter("lambda_theta", 3.0f * _cfg._theta * lambda); - _shader_uv->parameter("theta", _cfg._theta); - //_shader_p->parameter("timestep_over_theta", _cfg._tau / _cfg._theta); - _shader_p->parameter("timestep", -_cfg._tau / _cfg._theta); - _shader_p->parameter("rcpLambda_p", 1.0f); - - for (int iter = 0; iter < _nOuterIterations; ++iter) - { - warpImageWithFlowField(ubuffer2->textureID(), I0_TexIDs0, I1_TexIDs0, level, warpedBuffer_R); - warpImageWithFlowField(ubuffer2->textureID(), I0_TexIDs1, I1_TexIDs1, level, warpedBuffer_G); - warpImageWithFlowField(ubuffer2->textureID(), I0_TexIDs2, I1_TexIDs2, level, warpedBuffer_B); - checkGLErrorsHere0(); - - setupNormalizedProjection(); - - for (int k = 0; k < _nInnerIterations /* * sqrtf(resizeFactor) */; ++k) - { - pbuffer1->activate(); - - ubuffer2->enableTexture(GL_TEXTURE0_ARB); - pbuffer2->enableTexture(GL_TEXTURE1_ARB); - - _shader_p->enable(); - _shader_p->bindTexture("uv_src", 0); - _shader_p->bindTexture("p_uv_src", 1); - renderNormalizedQuad(GPU_SAMPLE_REVERSE_NEIGHBORS, ds, dt); - _shader_p->disable(); - - //ubuffer2->disableTexture(GL_TEXTURE0_ARB); - pbuffer2->disableTexture(GL_TEXTURE1_ARB); - - std::swap(pbuffer1, pbuffer2); - - ubuffer1->activate(); - - //ubuffer2->enableTexture(GL_TEXTURE0_ARB); - pbuffer2->enableTexture(GL_TEXTURE1_ARB); - warpedBuffer_R.enableTexture(GL_TEXTURE2_ARB); - warpedBuffer_G.enableTexture(GL_TEXTURE3_ARB); - warpedBuffer_B.enableTexture(GL_TEXTURE4_ARB); - - - _shader_uv->enable(); - _shader_uv->bindTexture("uv_src", 0); - _shader_uv->bindTexture("p_uv_src", 1); - _shader_uv->bindTexture("warped_R_tex", 2); - _shader_uv->bindTexture("warped_G_tex", 3); - _shader_uv->bindTexture("warped_B_tex", 4); - renderNormalizedQuad(GPU_SAMPLE_REVERSE_NEIGHBORS, ds, dt); - _shader_uv->disable(); - - ubuffer2->disableTexture(GL_TEXTURE0_ARB); - pbuffer2->disableTexture(GL_TEXTURE1_ARB); - warpedBuffer_R.disableTexture(GL_TEXTURE2_ARB); - warpedBuffer_G.disableTexture(GL_TEXTURE3_ARB); - warpedBuffer_B.disableTexture(GL_TEXTURE4_ARB); - - std::swap(ubuffer1, ubuffer2); - } // end for (k) - } // end for (iter) - } // end for (level) - } // end TVL1_ColorFlowEstimator_QR::run() - -} // end namespace V3D_GP
View file
slowmoVideo-0.4.tar.gz/src/V3D/GL/v3d_gpucolorflow.h
Deleted
@@ -1,112 +0,0 @@ -// -*- C++ -*- - -#include "config.h" - -#ifndef V3D_GPU_COLOR_FLOW_H -#define V3D_GPU_COLOR_FLOW_H - -#include "GL/v3d_gpubase.h" -#include "GL/v3d_gpuflow.h" - -namespace V3D_GPU -{ - - struct TVL1_ColorFlowEstimatorBase - { - TVL1_ColorFlowEstimatorBase(int nLevels) - : _warpedBufferHighPrecision(true), - _uvBufferHighPrecision(true), - _pBufferHighPrecision(false), // fp16 is usually enough for p - _nOuterIterations(1), _nInnerIterations(50), _startLevel(0), _nLevels(nLevels), - _width(-1), _height(-1) - { } - - void setLambda(float lambda) { _lambda = lambda; } - void setOuterIterations(int nIters) { _nOuterIterations = nIters; } - void setInnerIterations(int nIters) { _nInnerIterations = nIters; } - void setStartLevel(int startLevel) { _startLevel = startLevel; } - - // Must be called before allocate() to have an effect. - void configurePrecision(bool warpedBufferHighPrecision, - bool uvBufferHighPrecision, - bool pBufferHighPrecision) - { - _warpedBufferHighPrecision = warpedBufferHighPrecision; - _uvBufferHighPrecision = uvBufferHighPrecision; - _pBufferHighPrecision = pBufferHighPrecision; - } - - void allocate(int w, int h); - void deallocate(); - - RTT_Buffer * getWarpedBuffer(int channel, int level) - { - return _warpedBufferPyramidschannellevel; - } - - protected: - bool _warpedBufferHighPrecision, _uvBufferHighPrecision, _pBufferHighPrecision; - - std::vector<RTT_Buffer *> _warpedBufferPyramids3; - - int _nOuterIterations, _nInnerIterations; - - float _lambda; - int _startLevel, _nLevels; - int _width, _height; - }; // end struct TVL1_ColorFlowEstimatorBase - -//---------------------------------------------------------------------- - - // Quadratic relaxation approach - struct TVL1_ColorFlowEstimator_QR : public TVL1_ColorFlowEstimatorBase - { - public: - struct Config - { - Config(float tau = 0.249f, float theta = 0.1f) - : _tau(tau), _theta(theta) - { } - - float _tau, _theta; - }; - - TVL1_ColorFlowEstimator_QR(int nLevels) - : TVL1_ColorFlowEstimatorBase(nLevels) - { - _shader_uv = 0; - _shader_p = 0; - } - - ~TVL1_ColorFlowEstimator_QR() { } - - void configure(Config const& cfg) { _cfg = cfg; } - - void allocate(int w, int h); - void deallocate(); - - void run(unsigned int I0_TexIDs3, unsigned int I1_TexIDs3); - - unsigned int getFlowFieldTextureID() - { - return _uBuffer2Pyramid_startLevel->textureID(); - } - - RTT_Buffer *getFlowBuffer() - { - return _uBuffer2Pyramid_startLevel; - } - - protected: - Config _cfg; - - GLSL_FragmentProgram *_shader_uv; - GLSL_FragmentProgram *_shader_p; - - std::vector<RTT_Buffer *> _uBuffer1Pyramid, _uBuffer2Pyramid; - std::vector<RTT_Buffer *> _pBuffer1Pyramid, _pBuffer2Pyramid; - }; // end struct TVL1_ColorFlowEstimator_QR - -} // end namespace V3D_GPU - -#endif // defined(V3D_GPU_FLOW_H)
View file
slowmoVideo-0.4.tar.gz/src/V3D/GL/v3d_gpuflow.cpp
Deleted
@@ -1,252 +0,0 @@ -#include "config.h" - -#include "Base/v3d_utilities.h" -#include "v3d_gpuflow.h" -#include "glsl_shaders.h" - -#include <iostream> -#include <cmath> -#include <GL/glew.h> - -using namespace std; -using namespace V3D_GPU; - -namespace -{ - void - upsampleDisparities(unsigned uvSrcTex, unsigned pSrcTex, float pScale, - RTT_Buffer& ubuffer, RTT_Buffer& pbuffer) - { - static GLSL_FragmentProgram * upsampleShader = 0; - - if (upsampleShader == 0) - { - upsampleShader = new GLSL_FragmentProgram("v3d_gpuflow::upsampleDisparities::upsampleShader"); - - char const * source = - "void main(uniform sampler2D src_tex : TEXTURE0, \n" - " float2 st0 : TEXCOORD0, \n" - " float4 st3 : TEXCOORD3, \n" - " out float4 res_out : COLOR0) \n" - "{ \n" - " res_out = st3 * tex2D(src_tex, st0); \n" - "} \n"; - upsampleShader->setProgram(source); - upsampleShader->compile(); - checkGLErrorsHere0(); - } // end if - - setupNormalizedProjection(); - ubuffer.activate(); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, uvSrcTex); - glEnable(GL_TEXTURE_2D); - upsampleShader->enable(); - // Provide uniform paramter via texcoord to avoid recompilation of shaders - glMultiTexCoord4f(GL_TEXTURE3_ARB, 2, 2, 1, 1); - //glMultiTexCoord4f(GL_TEXTURE3_ARB, 0, 0, 0, 0); - renderNormalizedQuad(); - //upsampleShader->disable(); - glDisable(GL_TEXTURE_2D); - checkGLErrorsHere0(); - - pbuffer.activate(); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, pSrcTex); - glEnable(GL_TEXTURE_2D); - //upsampleShader->enable(); - // Provide uniform paramter via texcoord to avoid recompilation of shaders - glMultiTexCoord4f(GL_TEXTURE3_ARB, pScale, pScale, pScale, pScale); - renderNormalizedQuad(); - upsampleShader->disable(); - glDisable(GL_TEXTURE_2D); - checkGLErrorsHere0(); - } // upsampleDisparities() - - void - upsampleBuffer(unsigned srcTex, float scale, FrameBufferObject& dstFbo) - { - static GLSL_FragmentProgram * upsampleShader = 0; - - if (upsampleShader == 0) - { - upsampleShader = new GLSL_FragmentProgram("v3d_gpuflow::upsampleBuffer::upsampleShader"); - - char const * source = - "void main(uniform sampler2D src_tex : TEXTURE0, \n" - " float2 st0 : TEXCOORD0, \n" - " float4 st3 : TEXCOORD3, \n" - " out float4 res_out : COLOR0) \n" - "{ \n" - " res_out = st3 * tex2D(src_tex, st0); \n" - "} \n"; - upsampleShader->setProgram(source); - upsampleShader->compile(); - checkGLErrorsHere0(); - } // end if - - setupNormalizedProjection(); - dstFbo.activate(); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, srcTex); - glEnable(GL_TEXTURE_2D); - upsampleShader->enable(); - // Provide uniform paramter via texcoord to avoid recompilation of shaders - glMultiTexCoord4f(GL_TEXTURE3_ARB, scale, scale, scale, scale); - renderNormalizedQuad(); - upsampleShader->disable(); - glDisable(GL_TEXTURE_2D); - checkGLErrorsHere0(); - } // upsampleBuffer() - - void - upsampleBuffers(unsigned src1Tex, unsigned src2Tex, float scale1, float scale2, - FrameBufferObject& dstFbo) - { - static GLSL_FragmentProgram * upsampleShader = 0; - - if (upsampleShader == 0) - { - upsampleShader = new GLSL_FragmentProgram("v3d_gpuflow::upsampleBuffer::upsampleShader"); - - char const * source = - "void main(uniform sampler2D src1_tex : TEXTURE0, \n" - " uniform sampler2D src2_tex : TEXTURE1, \n" - " float2 st0 : TEXCOORD0, \n" - " float4 st3 : TEXCOORD3, \n" - " float4 st4 : TEXCOORD4, \n" - " out float4 res1_out : COLOR0, \n" - " out float4 res2_out : COLOR1) \n" - "{ \n" - " res1_out = st3 * tex2D(src1_tex, st0); \n" - " res1_out = st4 * tex2D(src2_tex, st0); \n" - "} \n"; - upsampleShader->setProgram(source); - upsampleShader->compile(); - checkGLErrorsHere0(); - } // end if - - setupNormalizedProjection(); - dstFbo.activate(); - - GLenum const targetBuffers2 = { GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT }; - glDrawBuffersARB(2, targetBuffers); - - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, src1Tex); - glEnable(GL_TEXTURE_2D); - glActiveTexture(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_2D, src2Tex); - glEnable(GL_TEXTURE_2D); - upsampleShader->enable(); - // Provide uniform paramter via texcoord to avoid recompilation of shaders - // Texcoords 0-2 are assigned by renderNormalizedQuad(). - glMultiTexCoord4f(GL_TEXTURE3_ARB, scale1, scale1, scale1, scale1); - glMultiTexCoord4f(GL_TEXTURE4_ARB, scale2, scale2, scale2, scale2); - renderNormalizedQuad(); - upsampleShader->disable(); - glActiveTexture(GL_TEXTURE0); - glDisable(GL_TEXTURE_2D); - glActiveTexture(GL_TEXTURE1); - glDisable(GL_TEXTURE_2D); - - glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); - - checkGLErrorsHere0(); - } // upsampleBuffers() - -} // end namespace - -//---------------------------------------------------------------------- - -namespace V3D_GPU -{ - - void - TVL1_FlowEstimatorBase::allocate(int W, int H) - { - _width = W; - _height = H; - - char const * texSpec = _warpedBufferHighPrecision ? "rgba=32f tex2D" : "rgba=16f tex2D"; - - _warpedBufferPyramid.resize(_nLevels); - for (int level = 0; level < _nLevels; ++level) - { - int const w = _width / (1 << level); - int const h = _height / (1 << level); - - _warpedBufferPyramidlevel = new RTT_Buffer(texSpec, "_warpedBufferPyramid"); - _warpedBufferPyramidlevel->allocate(w, h); - } - } // end TVL1_FlowEstimatorBase::allocate() - - void - TVL1_FlowEstimatorBase::deallocate() - { - for (int level = 0; level < _nLevels; ++level) - _warpedBufferPyramidlevel->deallocate(); - } - -//---------------------------------------------------------------------- - - void - warpImageWithFlowField(unsigned int uv_tex, unsigned int I0_tex, - unsigned int I1_tex, int level, RTT_Buffer& dest) - { - static GLSL_FragmentProgram * shader = 0; - if (shader == 0) - { - shader = new GLSL_FragmentProgram("v3d_gpuflow::warpImageWithFlowField::shader"); - shader->setProgram(GLSL_Shaders::flow_warp_image.c_str()); - shader->compile(); - checkGLErrorsHere0(); - } - - int const w = dest.width(); - int const h = dest.height(); - - dest.activate(); - - setupNormalizedProjection(); - - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, uv_tex); - glEnable(GL_TEXTURE_2D); - - glActiveTexture(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_2D, I0_tex); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, level); - //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); - glEnable(GL_TEXTURE_2D); - glActiveTexture(GL_TEXTURE2); - glBindTexture(GL_TEXTURE_2D, I1_tex); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, level); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); - glEnable(GL_TEXTURE_2D); - - // Provide uniform paramter via texcoord to avoid recompilation of shaders - glMultiTexCoord3f(GL_TEXTURE3_ARB, 1.0f/w, 1.0f/h, 1 << level); - shader->enable(); - shader->bindTexture("uv_src", 0); - shader->bindTexture("I0_tex", 1); - shader->bindTexture("I1_tex", 2); - renderNormalizedQuad(); - shader->disable(); - - glActiveTexture(GL_TEXTURE0); - glDisable(GL_TEXTURE_2D); - glActiveTexture(GL_TEXTURE1); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); - //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glDisable(GL_TEXTURE_2D); - glActiveTexture(GL_TEXTURE2); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glDisable(GL_TEXTURE_2D); - } // end warpImageWithFlowField() - -} // end namespace V3D_GPU
View file
slowmoVideo-0.4.tar.gz/src/V3D/GL/v3d_gpuflow.h
Deleted
@@ -1,63 +0,0 @@ -// -*- C++ -*- - -#include "config.h" - -#ifndef V3D_GPU_FLOW_H -#define V3D_GPU_FLOW_H - -#include "GL/v3d_gpubase.h" -#include "GL/v3d_gpupyramid.h" - -namespace V3D_GPU -{ - - struct TVL1_FlowEstimatorBase - { - TVL1_FlowEstimatorBase(int nLevels) - : _warpedBufferHighPrecision(true), - _uvBufferHighPrecision(true), - _pBufferHighPrecision(false), // fp16 is usually enough for p - _nOuterIterations(1), _nInnerIterations(50), _startLevel(0), _nLevels(nLevels), - _width(-1), _height(-1) - { } - - void setLambda(float lambda) { _lambda = lambda; } - void setOuterIterations(int nIters) { _nOuterIterations = nIters; } - void setInnerIterations(int nIters) { _nInnerIterations = nIters; } - void setStartLevel(int startLevel) { _startLevel = startLevel; } - - // Must be called before allocate() to have an effect. - void configurePrecision(bool warpedBufferHighPrecision, - bool uvBufferHighPrecision, - bool pBufferHighPrecision) - { - _warpedBufferHighPrecision = warpedBufferHighPrecision; - _uvBufferHighPrecision = uvBufferHighPrecision; - _pBufferHighPrecision = pBufferHighPrecision; - } - - void allocate(int w, int h); - void deallocate(); - - RTT_Buffer * getWarpedBuffer(int level) { return _warpedBufferPyramidlevel; } - - protected: - bool _warpedBufferHighPrecision, _uvBufferHighPrecision, _pBufferHighPrecision; - - std::vector<RTT_Buffer *> _warpedBufferPyramid; - - int _nOuterIterations, _nInnerIterations; - - float _lambda; - int _startLevel, _nLevels; - int _width, _height; - }; // end struct TVL1_FlowEstimatorBase - -//---------------------------------------------------------------------- - - void warpImageWithFlowField(unsigned int uv_tex, unsigned int I0_tex, - unsigned int I1_tex, int level, RTT_Buffer& dest); - -} // end namespace V3D_GPU - -#endif // defined(V3D_GPU_FLOW_H)
View file
slowmoVideo-0.4.tar.gz/src/V3D/GL/v3d_gpupyramid.cpp
Deleted
@@ -1,271 +0,0 @@ -#include "config.h" - -#include "v3d_gpupyramid.h" -#include "Base/v3d_timer.h" -#include "glsl_shaders.h" -#include <GL/glew.h> - -#include <iostream> -#include <iomanip> -#include <cstdio> - -using namespace std; -using namespace V3D_GPU; -using namespace V3D; - -namespace -{ - inline void - renderQuad4Tap(float dS, float dT) - { - glBegin(GL_TRIANGLES); - glMultiTexCoord4f(GL_TEXTURE0_ARB, 0-1*dS, 0-1*dT, 0-0*dS, 0-0*dT); - glMultiTexCoord4f(GL_TEXTURE1_ARB, 0+1*dS, 0+1*dT, 0+2*dS, 0+2*dT); - glVertex2f(0, 0); - - glMultiTexCoord4f(GL_TEXTURE0_ARB, 2-1*dS, 0-1*dT, 2-0*dS, 0-0*dT); - glMultiTexCoord4f(GL_TEXTURE1_ARB, 2+1*dS, 0+1*dT, 2+2*dS, 0+2*dT); - glVertex2f(2, 0); - - glMultiTexCoord4f(GL_TEXTURE0_ARB, 0-1*dS, 2-1*dT, 0-0*dS, 2-0*dT); - glMultiTexCoord4f(GL_TEXTURE1_ARB, 0+1*dS, 2+1*dT, 0+2*dS, 2+2*dT); - glVertex2f(0, 2); - glEnd(); - } // end renderQuad() - - inline void - renderQuad8Tap(float dS, float dT) - { - glBegin(GL_TRIANGLES); - glMultiTexCoord4f(GL_TEXTURE0_ARB, 0-3*dS, 0-3*dT, 0-2*dS, 0-2*dT); - glMultiTexCoord4f(GL_TEXTURE1_ARB, 0-1*dS, 0-1*dT, 0-0*dS, 0-0*dT); - glMultiTexCoord4f(GL_TEXTURE2_ARB, 0+1*dS, 0+1*dT, 0+2*dS, 0+2*dT); - glMultiTexCoord4f(GL_TEXTURE3_ARB, 0+3*dS, 0+3*dT, 0+4*dS, 0+4*dT); - glVertex2f(0, 0); - - glMultiTexCoord4f(GL_TEXTURE0_ARB, 2-3*dS, 0-3*dT, 2-2*dS, 0-2*dT); - glMultiTexCoord4f(GL_TEXTURE1_ARB, 2-1*dS, 0-1*dT, 2-0*dS, 0-0*dT); - glMultiTexCoord4f(GL_TEXTURE2_ARB, 2+1*dS, 0+1*dT, 2+2*dS, 0+2*dT); - glMultiTexCoord4f(GL_TEXTURE3_ARB, 2+3*dS, 0+3*dT, 2+4*dS, 0+4*dT); - glVertex2f(2, 0); - - glMultiTexCoord4f(GL_TEXTURE0_ARB, 0-3*dS, 2-3*dT, 0-2*dS, 2-2*dT); - glMultiTexCoord4f(GL_TEXTURE1_ARB, 0-1*dS, 2-1*dT, 0-0*dS, 2-0*dT); - glMultiTexCoord4f(GL_TEXTURE2_ARB, 0+1*dS, 2+1*dT, 0+2*dS, 2+2*dT); - glMultiTexCoord4f(GL_TEXTURE3_ARB, 0+3*dS, 2+3*dT, 0+4*dS, 2+4*dT); - glVertex2f(0, 2); - glEnd(); - } // end renderQuad() - -} // end namespace <> - -//---------------------------------------------------------------------- - -namespace V3D_GPU -{ - - void - PyramidWithDerivativesCreator::allocate(int w, int h, int nLevels, int preSmoothingFilter) - { - ScopedTimer st(__PRETTY_FUNCTION__); - _width = w; - _height = h; - _nLevels = nLevels; - _preSmoothingFilter = preSmoothingFilter; - - GLenum const textureTarget = GL_TEXTURE_2D; - GLenum const floatFormat = _useFP32 ? GL_RGBA32F_ARB : GL_RGBA16F_ARB; - - glGenFramebuffersEXT(1, &_pyrFbIDs); - glGenFramebuffersEXT(1, &_tmpFbIDs); - glGenFramebuffersEXT(1, &_tmp2FbID); - checkGLErrorsHere0(); - - _srcTex.allocateID(); - _srcTex.reserve(w, h, TextureSpecification(_srcTexSpec)); - - glGenTextures(1, &_pyrTexID); - glGenTextures(1, &_tmpTexID); - glGenTextures(1, &_tmpTex2ID); - - //cout << "pyrTexID" << endl; - glBindTexture(textureTarget, _pyrTexID); - glTexParameteri(textureTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(textureTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - //glTexParameteri(textureTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); - glTexParameteri(textureTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(textureTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(textureTarget, GL_TEXTURE_BASE_LEVEL, 0); - glTexParameteri(textureTarget, GL_TEXTURE_MAX_LEVEL, nLevels-1); - // This is the simplest way to create the full mipmap pyramid. - for (int n = 0; n < nLevels; ++n) - glTexImage2D(textureTarget, n, floatFormat, w >> n , h >> n , 0, GL_RGBA, GL_UNSIGNED_BYTE,0); - checkGLErrorsHere0(); - - //cout << "tmpTexID" << endl; - glBindTexture(textureTarget, _tmpTexID); - glTexParameteri(textureTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(textureTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - //glTexParameteri(textureTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); - glTexParameteri(textureTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(textureTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(textureTarget, GL_TEXTURE_BASE_LEVEL, 0); - glTexParameteri(textureTarget, GL_TEXTURE_MAX_LEVEL, nLevels-1); - for (int n = 0; n < nLevels; ++n) - glTexImage2D(textureTarget, n, floatFormat, w >> n, (h/2) >> n, 0, GL_RGBA, GL_UNSIGNED_BYTE,0); - - //cout << "tmpTex2ID" << endl; - glBindTexture(textureTarget, _tmpTex2ID); - glTexParameteri(textureTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(textureTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(textureTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(textureTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexImage2D(textureTarget, 0, floatFormat, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); - - glBindTexture(textureTarget, 0); - checkGLErrorsHere0(); - - initializeShaders(preSmoothingFilter); - } // end PyramidWithDerivativesCreator::allocate() - - void - PyramidWithDerivativesCreator::initializeShaders(int preSmoothingFilter) - { - ScopedTimer st(__PRETTY_FUNCTION__); - if (shaders_initialized) - return; - - shaders_initialized = true; - - if (_pass1HorizShader == 0) - { - _pass1HorizShader - = new GLSL_FragmentProgram("PyramidWithDerivativesCreator::buildPyramidForGrayscaleImage_impl::pass1HorizShader"); - _pass1HorizShader->setProgram(GLSL_Shaders::pyramid_with_derivative_pass1v.c_str()); - _pass1HorizShader->compile(); - checkGLErrorsHere0(); - } // end if (_pass1HorizShader == 0) - - if (_pass1VertShader == 0) - { - _pass1VertShader - = new GLSL_FragmentProgram("PyramidWithDerivativesCreator::buildPyramidForGrayscaleImage_impl::pass1VertShader"); - _pass1VertShader->setProgram(GLSL_Shaders::pyramid_with_derivative_pass1h.c_str()); - _pass1VertShader->compile(); - checkGLErrorsHere0(); - } // end if (_pass1VertShader == 0) - - if (_pass2Shader == 0) - { - _pass2Shader - = new GLSL_FragmentProgram("PyramidWithDerivativesCreator::buildPyramidForGrayscaleImage_impl::pass2Shader"); - _pass2Shader->setProgram(GLSL_Shaders::pyramid_with_derivative_pass2.c_str()); - _pass2Shader->compile(); - checkGLErrorsHere0(); - } // end if (_pass2Shader == 0) - } - - void - PyramidWithDerivativesCreator::deallocate() - { - glDeleteFramebuffersEXT(1, &_pyrFbIDs); - glDeleteFramebuffersEXT(1, &_tmpFbIDs); - glDeleteFramebuffersEXT(1, &_tmp2FbID); - glDeleteTextures(1, &_pyrTexID); - glDeleteTextures(1, &_tmpTexID); - glDeleteTextures(1, &_tmpTex2ID); - _srcTex.deallocateID(); - } - - void - PyramidWithDerivativesCreator::buildPyramidForGrayscaleImage(uchar const * image) - { - _srcTex.overwriteWith(image, 1); - this->buildPyramidForGrayscaleTexture(_srcTex.textureID()); - } - - void - PyramidWithDerivativesCreator::buildPyramidForGrayscaleImage(float const * image) - { - _srcTex.overwriteWith(image, 1); - this->buildPyramidForGrayscaleTexture(_srcTex.textureID()); - } - - void - PyramidWithDerivativesCreator::buildPyramidForGrayscaleTexture(unsigned int srcTexID) - { - setupNormalizedProjection(); - glViewport(0, 0, _width, _height); - - GLenum const textureTarget = GL_TEXTURE_2D; - - glEnable(GL_TEXTURE_2D); - glActiveTexture(GL_TEXTURE0); - glBindTexture(textureTarget, srcTexID); - - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, _tmp2FbID); - glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, textureTarget, _tmpTex2ID, 0); - - _pass1HorizShader->parameter("presmoothing", _preSmoothingFilter); - _pass1HorizShader->enable(); - _pass1HorizShader->bindTexture("src_tex", 0); - renderQuad8Tap(0.0f, 1.0f/_height); - _pass1HorizShader->disable(); - - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, _pyrFbIDs); - glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,GL_TEXTURE_2D,_pyrTexID,0); - glBindTexture(textureTarget, _tmpTex2ID); - - _pass1VertShader->parameter("presmoothing", _preSmoothingFilter); - _pass1VertShader->enable(); - _pass1VertShader->bindTexture("src_tex", 0); - renderQuad8Tap(1.0f/_width, 0.0f); - _pass1VertShader->disable(); - - _pass2Shader->enable(); - - for (int level = 1; level < _nLevels; ++level) - { - // Source texture dimensions. - int const W = (_width >> (level-1)); - int const H = (_height >> (level-1)); - - glBindTexture(textureTarget, _pyrTexID); - glTexParameteri(textureTarget, GL_TEXTURE_BASE_LEVEL, level-1); - - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, _tmpFbIDs); - glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,GL_TEXTURE_2D,_tmpTexID,level-1); - glViewport(0, 0, W, H/2); - renderQuad4Tap(0.0f, 1.0f/H); - //glTexParameteri(textureTarget, GL_TEXTURE_BASE_LEVEL, 0); - - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, _pyrFbIDs); - glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,GL_TEXTURE_2D,_pyrTexID,level); - glViewport(0, 0, W/2, H/2); - glBindTexture(textureTarget, _tmpTexID); - glTexParameteri(textureTarget, GL_TEXTURE_BASE_LEVEL, level-1); - renderQuad4Tap(1.0f/W, 0.0f); - //glTexParameteri(textureTarget, GL_TEXTURE_BASE_LEVEL, 0); - } // end for (level) - - _pass2Shader->disable(); - glDisable(GL_TEXTURE_2D); - - glBindTexture(textureTarget, _pyrTexID); - glTexParameteri(textureTarget, GL_TEXTURE_BASE_LEVEL, 0); - glBindTexture(textureTarget, _tmpTexID); - glTexParameteri(textureTarget, GL_TEXTURE_BASE_LEVEL, 0); - } // end PyramidWithDerivativesCreator::buildPyramidForGrayscaleTexturel() - - void - PyramidWithDerivativesCreator::activateTarget(int level) - { - int const W = (_width >> level); - int const H = (_height >> level); - - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, _pyrFbIDs); - glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,GL_TEXTURE_2D, _pyrTexID, level); - glViewport(0, 0, W, H); - } - -} // end namespace V3D_GPU
View file
slowmoVideo-0.4.tar.gz/src/V3D/GL/v3d_gpupyramid.h
Deleted
@@ -1,56 +0,0 @@ -// -*- C++ -*- - -#include "config.h" - -#ifndef V3D_GPU_PYRAMID_H -#define V3D_GPU_PYRAMID_H - -#include "v3d_gpubase.h" - -namespace V3D_GPU -{ - - struct PyramidWithDerivativesCreator - { - PyramidWithDerivativesCreator(bool useFP32 = false, char const * srcTexSpec = "r=8 noRTT") - : _useFP32(useFP32), _width(0), _height(0), _nLevels(0), _srcTexSpec(srcTexSpec), _preSmoothingFilter(0), - _pass1HorizShader(0), _pass1VertShader(0), _pass2Shader(0), shaders_initialized(false) - { } - - ~PyramidWithDerivativesCreator() { } - - int numberOfLevels() const { return _nLevels; } - - void allocate(int w, int h, int nLevels, int preSmoothingFilter = 0); - void deallocate(); - - void buildPyramidForGrayscaleImage(uchar const * image); - void buildPyramidForGrayscaleImage(float const * image); - - void buildPyramidForGrayscaleTexture(unsigned int srcTexID); - - void activateTarget(int level); - - unsigned int textureID() const { return _pyrTexID; } - unsigned int sourceTextureID() const { return _srcTex.textureID(); } - - void initializeShaders(int presmoohing); - - protected: - bool const _useFP32; - int _width, _height, _nLevels; - unsigned int _pyrFbIDs, _tmpFbIDs, _tmp2FbID; - unsigned int _pyrTexID, _tmpTexID, _tmpTex2ID; - ImageTexture2D _srcTex; - char const * _srcTexSpec; - int _preSmoothingFilter; - - GLSL_FragmentProgram *_pass1HorizShader; - GLSL_FragmentProgram *_pass1VertShader; - GLSL_FragmentProgram *_pass2Shader; - bool shaders_initialized; - }; // end struct PyramidWithDerivativesCreator - -} // end namespace V3D_GPU - -#endif
View file
slowmoVideo-0.4.tar.gz/src/V3D/Math
Deleted
-(directory)
View file
slowmoVideo-0.4.tar.gz/src/V3D/Math/v3d_linear.h
Deleted
@@ -1,622 +0,0 @@ -// -*- C++ -*- - -#ifndef V3D_LINEAR_H -#define V3D_LINEAR_H - -#include "Math/v3d_linearbase.h" - -#include <iostream> - -namespace V3D -{ - - template <typename Elem, int Size> - struct InlineVector : public InlineVectorBase<Elem, Size> - { - InlineVector() { } - - template<typename Elem2> - explicit InlineVector<Elem,Size>(InlineVector<Elem2,Size> const& a) - { - for(int i=0; i<Size; i++) - this->_veci = (Elem2)ai; - } - - template <int size> - InlineVector<Elem,size> slice( int first ) const - { - InlineVector<Elem,size> vec; - copyVectorSlice(*this,first,size,vec,0); - return vec; - } - }; // end struct InlineVector - - template <typename Elem> - struct InlineVector<Elem, 2> : public InlineVectorBase<Elem, 2> - { - InlineVector() { } - - InlineVector(Elem a, Elem b) - { - InlineVectorBase<Elem, 2>::_vec0 = a; - InlineVectorBase<Elem, 2>::_vec1 = b; - } - - template<typename Elem2> - explicit InlineVector(InlineVector<Elem2,2> const& a) - { - for(int i=0; i<2; i++) - this->_veci = (Elem2)ai; - } - - template <int size> - InlineVector<Elem,size> slice( int first ) const - { - InlineVector<Elem,size> vec; - copyVectorSlice(*this,first,size,vec,0); - return vec; - } - }; // end struct InlineVector - - template <typename Elem> - struct InlineVector<Elem, 3> : public InlineVectorBase<Elem, 3> - { - InlineVector() { } - - InlineVector(Elem a, Elem b, Elem c) - { - InlineVectorBase<Elem, 3>::_vec0 = a; - InlineVectorBase<Elem, 3>::_vec1 = b; - InlineVectorBase<Elem, 3>::_vec2 = c; - } - - InlineVector(InlineVector<Elem,2> const &vec, Elem c) - { - InlineVectorBase<Elem, 3>::_vec0 = vec0; - InlineVectorBase<Elem, 3>::_vec1 = vec1; - InlineVectorBase<Elem, 3>::_vec2 = c; - } - - template<typename Elem2> - explicit InlineVector(InlineVector<Elem2,3> const& a) - { - for(int i=0; i<3; i++) - this->_veci = (Elem2)ai; - } - - template <int size> - InlineVector<Elem,size> slice( int first ) const - { - InlineVector<Elem,size> vec; - copyVectorSlice(*this,first,size,vec,0); - return vec; - } - }; // end struct InlineVector - - template <typename Elem> - struct InlineVector<Elem, 4> : public InlineVectorBase<Elem, 4> - { - InlineVector() { } - - InlineVector(Elem a, Elem b, Elem c, Elem d) - { - InlineVectorBase<Elem, 4>::_vec0 = a; - InlineVectorBase<Elem, 4>::_vec1 = b; - InlineVectorBase<Elem, 4>::_vec2 = c; - InlineVectorBase<Elem, 4>::_vec3 = d; - } - - InlineVector( InlineVector<Elem,3> const& v, Elem d ) - { - InlineVectorBase<Elem, 4>::_vec0 = v0; - InlineVectorBase<Elem, 4>::_vec1 = v1; - InlineVectorBase<Elem, 4>::_vec2 = v2; - InlineVectorBase<Elem, 4>::_vec3 = d; - } - - template<typename Elem2> - explicit InlineVector(InlineVector<Elem2,4> const& a) - { - for(int i=0; i<4; i++) - this->_veci = (Elem2)ai; - } - - template <int size> - InlineVector<Elem,size> slice( int first ) const - { - InlineVector<Elem,size> vec; - copyVectorSlice(*this,first,size,vec,0); - return vec; - } - }; // end struct InlineVector - - template <typename Elem> - struct Vector : public VectorBase<Elem> - { - Vector() - : VectorBase<Elem>() - { } - - Vector(unsigned int size) - : VectorBase<Elem>(size) - { } - - Vector(unsigned int size, Elem * values) - : VectorBase<Elem>(size, values) - { } - - Vector(Vector<Elem> const& a) - : VectorBase<Elem>(a) - { } - - Vector<Elem>& operator=(Vector<Elem> const& a) - { - (VectorBase<Elem>::operator=)(a); - return *this; - } - - Vector<Elem>& operator+=(Vector<Elem> const& rhs) - { - addVectorsIP(rhs, *this); - return *this; - } - - Vector<Elem>& operator*=(Elem scale) - { - scaleVectorIP(scale, *this); - return *this; - } - - Vector<Elem> operator+(Vector<Elem> const& rhs) const - { - Vector<Elem> res(this->size()); - addVectors(*this, rhs, res); - return res; - } - - Vector<Elem> operator-(Vector<Elem> const& rhs) const - { - Vector<Elem> res(this->size()); - subtractVectors(*this, rhs, res); - return res; - } - - Elem operator*(Vector<Elem> const& rhs) const - { - return innerProduct(*this, rhs); - } - - }; // end struct Vector - - template <typename Elem, int Rows, int Cols> - struct InlineMatrix : public InlineMatrixBase<Elem, Rows, Cols> - { - template <int numRows, int numCols> - InlineMatrix<Elem,numRows,numCols> slice( int row, int col ) const - { - InlineMatrix<Elem,numRows,numCols> mat; - copyMatrixSlice(*this,row,col,numRows,numCols,mat,0,0); - return mat; - } - - InlineVector<Elem,Cols> row( int row ) const - { - InlineVector<Elem,Cols> vec; - this->getRowSlice(row,0,Cols,vec); - return vec; - } - - InlineVector<Elem,Rows> col( int col ) const - { - InlineVector<Elem,Rows> vec; - this->getColumnSlice(0,Rows,col,vec); - return vec; - } - - InlineMatrix<Elem,Cols,Rows> transposed() const - { - return transposedMatrix(*this); - } - }; // end struct InlineMatrix - - template <typename Elem> - struct Matrix : public MatrixBase<Elem> - { - Matrix() - : MatrixBase<Elem>() - { } - - Matrix(unsigned int rows, unsigned int cols) - : MatrixBase<Elem>(rows, cols) - { } - - Matrix(unsigned int rows, unsigned int cols, Elem value) - : MatrixBase<Elem>(rows, cols) - { - fillMatrix(*this, value); - } - - Matrix(unsigned int rows, unsigned int cols, Elem * values) - : MatrixBase<Elem>(rows, cols, values) - { } - - Matrix(Matrix<Elem> const& a) - : MatrixBase<Elem>(a) - { } - - Matrix<Elem>& operator=(Matrix<Elem> const& a) - { - (MatrixBase<Elem>::operator=)(a); - return *this; - } - - Matrix<Elem>& operator+=(Matrix<Elem> const& rhs) - { - addMatricesIP(rhs, *this); - return *this; - } - - Matrix<Elem>& operator*=(Elem scale) - { - scaleMatrixIP(scale, *this); - return *this; - } - - Matrix<Elem> operator+(Matrix<Elem> const& rhs) const - { - Matrix<Elem> res(this->num_rows(), this->num_cols()); - addMatrices(*this, rhs, res); - return res; - } - - Matrix<Elem> operator-(Matrix<Elem> const& rhs) const - { - Matrix<Elem> res(this->num_rows(), this->num_cols()); - subtractMatrices(*this, rhs, res); - return res; - } - - }; // end struct Matrix - -//---------------------------------------------------------------------- - - typedef InlineVector<float, 2> Vector2f; - typedef InlineVector<double, 2> Vector2d; - typedef InlineVector<float, 3> Vector3f; - typedef InlineVector<double, 3> Vector3d; - typedef InlineVector<float, 4> Vector4f; - typedef InlineVector<double, 4> Vector4d; - - typedef InlineVector<unsigned char, 3> Vector3b; // For color specifications e.g. - - typedef InlineMatrix<float, 2, 2> Matrix2x2f; - typedef InlineMatrix<double, 2, 2> Matrix2x2d; - typedef InlineMatrix<float, 3, 3> Matrix3x3f; - typedef InlineMatrix<double, 3, 3> Matrix3x3d; - typedef InlineMatrix<float, 4, 4> Matrix4x4f; - typedef InlineMatrix<double, 4, 4> Matrix4x4d; - - typedef InlineMatrix<float, 2, 3> Matrix2x3f; - typedef InlineMatrix<double, 2, 3> Matrix2x3d; - typedef InlineMatrix<float, 3, 4> Matrix3x4f; - typedef InlineMatrix<double, 3, 4> Matrix3x4d; - - template <typename Elem> - struct VectorArray - { - VectorArray(unsigned count, unsigned size) - : _count(count), _size(size), _values(0), _vectors(0) - { - unsigned const nTotal = _count * _size; - if (count > 0) _vectors = new Vector<Elem>count; - if (nTotal > 0) _values = new ElemnTotal; - for (unsigned i = 0; i < _count; ++i) new (&_vectorsi) Vector<Elem>(_size, _values + i*_size); - } - - VectorArray(unsigned count, unsigned size, Elem initVal) - : _count(count), _size(size), _values(0), _vectors(0) - { - unsigned const nTotal = _count * _size; - if (count > 0) _vectors = new Vector<Elem>count; - if (nTotal > 0) _values = new ElemnTotal; - for (unsigned i = 0; i < _count; ++i) new (&_vectorsi) Vector<Elem>(_size, _values + i*_size); - std::fill(_values, _values + nTotal, initVal); - } - - ~VectorArray() - { - delete _values; - delete _vectors; - } - - unsigned count() const { return _count; } - unsigned size() const { return _size; } - - //! Get the submatrix at position ix - Vector<Elem> const& operator(unsigned ix) const - { - return _vectorsix; - } - - //! Get the submatrix at position ix - Vector<Elem>& operator(unsigned ix) - { - return _vectorsix; - } - - protected: - unsigned _count, _size; - Elem * _values; - Vector<Elem> * _vectors; - - private: - VectorArray(VectorArray const&); - void operator=(VectorArray const&); - }; - - template <typename Elem> - struct MatrixArray - { - MatrixArray(unsigned count, unsigned nRows, unsigned nCols) - : _count(count), _rows(nRows), _columns(nCols), _values(0), _matrices(0) - { - unsigned const nTotal = _count * _rows * _columns; - if (count > 0) _matrices = new Matrix<Elem>count; - if (nTotal > 0) _values = new doublenTotal; - for (unsigned i = 0; i < _count; ++i) - new (&_matricesi) Matrix<Elem>(_rows, _columns, _values + i*(_rows*_columns)); - } - - ~MatrixArray() - { - delete _matrices; - delete _values; - } - - //! Get the submatrix at position ix - Matrix<Elem> const& operator(unsigned ix) const - { - return _matricesix; - } - - //! Get the submatrix at position ix - Matrix<Elem>& operator(unsigned ix) - { - return _matricesix; - } - - unsigned count() const { return _count; } - unsigned num_rows() const { return _rows; } - unsigned num_cols() const { return _columns; } - - protected: - unsigned _count, _rows, _columns; - double * _values; - Matrix<Elem> * _matrices; - - private: - MatrixArray(MatrixArray const&); - void operator=(MatrixArray const&); - }; - -//---------------------------------------------------------------------- - - template <typename Elem, int Size> - inline InlineVector<Elem, Size+1> - homogenizeVector(InlineVector<Elem, Size> const& v) - { - InlineVector<Elem, Size+1> res; - copyVectorSlice(v, 0, Size, res, 0); - resSize = 1; - return res; - } - - template <typename Elem, int Size> - inline InlineVector<Elem, Size> - operator-(InlineVector<Elem, Size> const& v) - { - InlineVector<Elem, Size> res; - scaleVector(-1, v, res); - return res; - } - - template <typename Elem, int Size> - inline InlineVector<Elem, Size> - operator+(InlineVector<Elem, Size> const& v, InlineVector<Elem, Size> const& w) - { - InlineVector<Elem, Size> res; - addVectors(v, w, res); - return res; - } - - template <typename Elem, int Size> - inline InlineVector<Elem, Size> - operator-(InlineVector<Elem, Size> const& v, InlineVector<Elem, Size> const& w) - { - InlineVector<Elem, Size> res; - subtractVectors(v, w, res); - return res; - } - - template <typename Elem, int Rows, int Cols> - inline InlineMatrix<Elem, Rows, Cols> - operator-(InlineMatrix<Elem, Rows, Cols> const& A, InlineMatrix<Elem, Rows, Cols> const& B) - { - InlineMatrix<Elem, Rows, Cols> res; - subtractMatrices(A, B, res); - return res; - } - - template <typename Elem, int Rows, int Cols> - inline InlineMatrix<Elem, Rows, Cols> - operator+(InlineMatrix<Elem, Rows, Cols> const& A, InlineMatrix<Elem, Rows, Cols> const& B) - { - InlineMatrix<Elem, Rows, Cols> res; - addMatrices(A, B, res); - return res; - } - - template <typename Elem, int Size> - inline InlineVector<Elem, Size> - operator*(Elem scale, InlineVector<Elem, Size> const& v) - { - InlineVector<Elem, Size> res; - scaleVector(scale, v, res); - return res; - } - - template <typename Elem, int Rows, int Cols> - inline InlineMatrix<Elem, Rows, Cols> - operator*(Elem scale, InlineMatrix<Elem, Rows, Cols> const& A) - { - InlineMatrix<Elem, Rows, Cols> res; - scaleMatrix(A, scale, res); - return res; - } - - template <typename Elem, int Rows, int Cols> - inline InlineVector<Elem, Rows> - operator*(InlineMatrix<Elem, Rows, Cols> const& A, InlineVector<Elem, Cols> const& v) - { - InlineVector<Elem, Rows> res; - multiply_A_v(A, v, res); - return res; - } - - template <typename Elem, int Rows, int Cols> - inline InlineVector<Elem, Rows> - operator*(InlineVector<Elem, Rows> const& v, InlineMatrix<Elem, Rows, Cols> const& A) - { - InlineVector<Elem, Cols> res; - multiply_At_v(A, v, res); - return res; - } - - template <typename Elem, int RowsA, int ColsA, int ColsB> - inline InlineMatrix<Elem, RowsA, ColsB> - operator*(InlineMatrix<Elem, RowsA, ColsA> const& A, InlineMatrix<Elem, ColsA, ColsB> const& B) - { - InlineMatrix<Elem, RowsA, ColsB> res; - multiply_A_B(A, B, res); - return res; - } - - template <typename Elem, int Rows, int Cols> - inline InlineMatrix<Elem, Cols, Rows> - transposedMatrix(InlineMatrix<Elem, Rows, Cols> const& A) - { - InlineMatrix<Elem, Cols, Rows> At; - makeTransposedMatrix(A, At); - return At; - } - - template <typename Elem> - inline InlineMatrix<Elem, 3, 3> - invertedMatrix(InlineMatrix<Elem, 3, 3> const& A) - { - Elem a = A00, b = A01, c = A02; - Elem d = A10, e = A11, f = A12; - Elem g = A20, h = A21, i = A22; - - Elem const det = a*e*i + b*f*g + c*d*h - c*e*g - b*d*i - a*f*h; - - InlineMatrix<Elem, 3, 3> res; - res00 = e*i-f*h; res01 = c*h-b*i; res02 = b*f-c*e; - res10 = f*g-d*i; res11 = a*i-c*g; res12 = c*d-a*f; - res20 = d*h-e*g; res21 = b*g-a*h; res22 = a*e-b*d; - - scaleMatrixIP(1.0/det, res); - return res; - } - - template <typename Elem, int Rows, int Cols> - inline InlineMatrix<Elem,Rows,Cols> - outerProductMatrix(InlineVector<Elem,Rows> const& u, InlineVector<Elem,Cols> const& v) - { - InlineMatrix<Elem,Rows,Cols> mat; - makeOuterProductMatrix(u,v,mat); - return mat; - } - - template <typename Elem> - inline InlineMatrix<Elem, 3, 3> - crossProductMatrix(InlineVector<Elem, 3> const& v) - { - InlineMatrix<Elem, 3, 3> res; - makeCrossProductMatrix(v, res); - return res; - } - - template <typename Elem> - inline InlineVector<Elem,3> - crossProduct(InlineVector<Elem,3> const& u, InlineVector<Elem,3> const& v) - { - InlineVector<Elem,3> res; - makeCrossProductVector(u,v,res); - return res; - } - - template <typename Elem> - inline InlineVector<Elem, 2> - makeVector2(Elem a, Elem b) - { - InlineVector<Elem, 2> res; - res0 = a; res1 = b; - return res; - } - - template <typename Elem> - inline InlineVector<Elem, 3> - makeVector3(Elem a, Elem b, Elem c) - { - InlineVector<Elem, 3> res; - res0 = a; res1 = b; res2 = c; - return res; - } - -//====================================================================== - - template <typename Elem> - inline Vector<Elem> - operator*(Matrix<Elem> const& A, Vector<Elem> const& v) - { - Vector<Elem> res(A.num_rows()); - multiply_A_v(A, v, res); - return res; - } - -//====================================================================== - - template <typename Vec> - inline void - displayVector(Vec const& v) - { - using namespace std; - - cout << " "; - for (int r = 0; r < v.size(); ++r) - cout << vr << " "; - cout << "" << endl; - } - - template <typename Mat> - inline void - displayMatrix(Mat const& A) - { - using namespace std; - - cout << " "; - for (int r = 0; r < A.num_rows(); ++r) - { - for (int c = 0; c < A.num_cols(); ++c) - cout << Arc << " "; - if (r < A.num_rows()-1) - cout << endl; - else - cout << "" << endl; - } - } - -} // end namespace V3D - -#endif
View file
slowmoVideo-0.4.tar.gz/src/V3D/Math/v3d_linearbase.h
Deleted
@@ -1,1255 +0,0 @@ -// -*- C++ -*- - -#ifndef V3D_LINEAR_BASE_H -#define V3D_LINEAR_BASE_H - -#include <cassert> -#include <algorithm> -#include <vector> -#include <cmath> - -#include "Base/v3d_serialization.h" - -namespace V3D -{ - using namespace std; - - //! Unboxed vector type - template <typename Elem, int Size> - struct InlineVectorBase - { - typedef Elem value_type; - typedef Elem element_type; - - typedef Elem const * const_iterator; - typedef Elem * iterator; - - static unsigned int size() { return Size; } - - Elem& operator(unsigned int i) { return _veci; } - Elem operator(unsigned int i) const { return _veci; } - - Elem& operator()(unsigned int i) { return _veci-1; } - Elem operator()(unsigned int i) const { return _veci-1; } - - const_iterator begin() const { return _vec; } - iterator begin() { return _vec; } - const_iterator end() const { return _vec + Size; } - iterator end() { return _vec + Size; } - - void newsize(unsigned int sz) const - { - assert(sz == Size); - } - - template <typename Archive> void serialize(Archive& ar) - { - SerializationScope<Archive> scope(ar); - int sz = Size; - ar & sz; - if (ar.isLoading()) this->newsize(sz); - for (int i = 0; i < sz; ++i) ar & _veci; - } - - V3D_DEFINE_LOAD_SAVE(InlineVectorBase); - - protected: - Elem _vecSize; - }; - - //V3D_DEFINE_TEMPLATE_IOSTREAM_OPS(InlineVectorBase); - - //! Boxed (heap allocated) vector. - template <typename Elem> - struct VectorBase - { - typedef Elem value_type; - typedef Elem element_type; - - typedef Elem const * const_iterator; - typedef Elem * iterator; - - VectorBase() - : _size(0), _ownsVec(true), _vec(0) - { } - - VectorBase(unsigned int size) - : _size(size), _ownsVec(true), _vec(0) - { - if (size > 0) _vec = new Elemsize; - } - - VectorBase(unsigned int size, Elem * values) - : _size(size), _ownsVec(false), _vec(values) - { } - - VectorBase(VectorBase<Elem> const& a) - : _size(0), _ownsVec(true), _vec(0) - { - _size = a._size; - if (_size == 0) return; - _vec = new Elem_size; - std::copy(a._vec, a._vec + _size, _vec); - } - - ~VectorBase() { if (_ownsVec && _vec != 0) delete _vec; } - - VectorBase& operator=(VectorBase<Elem> const& a) - { - if (this == &a) return *this; - - this->newsize(a._size); - std::copy(a._vec, a._vec + _size, _vec); - return *this; - } - - unsigned int size() const { return _size; } - - VectorBase<Elem>& newsize(unsigned int sz) - { - if (sz == _size) return *this; - assert(_ownsVec); - - __destroy(); - _size = sz; - if (_size > 0) _vec = new Elem_size; - - return *this; - } - - Elem& operator(unsigned int i) { return _veci; } - Elem operator(unsigned int i) const { return _veci; } - - Elem& operator()(unsigned int i) { return _veci-1; } - Elem operator()(unsigned int i) const { return _veci-1; } - - const_iterator begin() const { return _vec; } - iterator begin() { return _vec; } - const_iterator end() const { return _vec + _size; } - iterator end() { return _vec + _size; } - - template <typename Archive> void serialize(Archive& ar) - { - SerializationScope<Archive> scope(ar); - int sz = _size; - ar & sz; - if (ar.isLoading()) this->newsize(sz); - for (int i = 0; i < sz; ++i) ar & _veci; - } - - V3D_DEFINE_LOAD_SAVE(VectorBase); - - protected: - void __destroy() - { - assert(_ownsVec); - - if (_vec != 0) delete _vec; - _size = 0; - _vec = 0; - } - - unsigned int _size; - bool _ownsVec; - Elem * _vec; - }; - - //V3D_DEFINE_TEMPLATE_IOSTREAM_OPS(VectorBase); - - template <typename Elem, int Rows, int Cols> - struct InlineMatrixBase - { - typedef Elem value_type; - typedef Elem element_type; - - typedef Elem * iterator; - typedef Elem const * const_iterator; - - static unsigned int num_rows() { return Rows; } - static unsigned int num_cols() { return Cols; } - - Elem * operator(unsigned int row) { return _mrow; } - Elem const * operator(unsigned int row) const { return _mrow; } - - Elem& operator()(unsigned int row, unsigned int col) { return _mrow-1col-1; } - Elem operator()(unsigned int row, unsigned int col) const { return _mrow-1col-1; } - - template <typename Vec> - void getRowSlice(unsigned int row, unsigned int first, unsigned int len, Vec& dst) const - { - for (unsigned int c = 0; c < len; ++c) dstc = _mrowc+first; - } - - template <typename Vec> - void getColumnSlice(unsigned int first, unsigned int len, unsigned int col, Vec& dst) const - { - for (unsigned int r = 0; r < len; ++r) dstr = _mr+firstcol; - } - - template <typename Vec> - void setRowSlice(unsigned int row, unsigned int first, unsigned int len, const Vec& src) - { - for (unsigned int c = 0; c < len; ++c) _mrowc+first = srcc; - } - - template <typename Vec> - void setColumnSlice(unsigned int first, unsigned int len, unsigned int col, const Vec& src) - { - for (unsigned int r = 0; r < len; ++r) _mr+firstcol = srcr; - } - - void newsize(unsigned int rows, unsigned int cols) const - { - assert(rows == Rows && cols == Cols); - } - - const_iterator begin() const { return &_m00; } - iterator begin() { return &_m00; } - const_iterator end() const { return &_m00 + Rows*Cols; } - iterator end() { return &_m00 + Rows*Cols; } - - template <typename Archive> void serialize(Archive& ar) - { - SerializationScope<Archive> scope(ar); - int n = Rows, m = Cols; - ar & n & m; - if (ar.isLoading()) this->newsize(n, m); - for (int r = 0; r < n; ++r) - for (int c = 0; c < m; ++c) - ar & _mrc; - } - - V3D_DEFINE_LOAD_SAVE(InlineMatrixBase); - - protected: - Elem _mRowsCols; - }; - - //V3D_DEFINE_TEMPLATE_IOSTREAM_OPS(InlineMatrixBase); - - template <typename Elem> - struct MatrixBase - { - typedef Elem value_type; - typedef Elem element_type; - - typedef Elem const * const_iterator; - typedef Elem * iterator; - - MatrixBase() - : _rows(0), _cols(0), _ownsData(true), _m(0) - { } - - MatrixBase(unsigned int rows, unsigned int cols) - : _rows(rows), _cols(cols), _ownsData(true), _m(0) - { - if (_rows * _cols == 0) return; - _m = new Elemrows*cols; - } - - MatrixBase(unsigned int rows, unsigned int cols, Elem * values) - : _rows(rows), _cols(cols), _ownsData(false), _m(values) - { } - - MatrixBase(MatrixBase<Elem> const& a) - : _ownsData(true), _m(0) - { - _rows = a._rows; _cols = a._cols; - if (_rows * _cols == 0) return; - _m = new Elem_rows*_cols; - std::copy(a._m, a._m+_rows*_cols, _m); - } - - ~MatrixBase() - { - if (_ownsData && _m != 0) delete _m; - } - - MatrixBase& operator=(MatrixBase<Elem> const& a) - { - if (this == &a) return *this; - - this->newsize(a.num_rows(), a.num_cols()); - - std::copy(a._m, a._m+_rows*_cols, _m); - return *this; - } - - void newsize(unsigned int rows, unsigned int cols) - { - if (rows == _rows && cols == _cols) return; - - assert(_ownsData); - - __destroy(); - - _rows = rows; - _cols = cols; - if (_rows * _cols == 0) return; - _m = new Elemrows*cols; - } - - unsigned int num_rows() const { return _rows; } - unsigned int num_cols() const { return _cols; } - - Elem * operator(unsigned int row) { return _m + row*_cols; } - Elem const * operator(unsigned int row) const { return _m + row*_cols; } - - Elem& operator()(unsigned int row, unsigned int col) { return _m(row-1)*_cols + col-1; } - Elem operator()(unsigned int row, unsigned int col) const { return _m(row-1)*_cols + col-1; } - - const_iterator begin() const { return _m; } - iterator begin() { return _m; } - const_iterator end() const { return _m + _rows*_cols; } - iterator end() { return _m + _rows*_cols; } - - template <typename Vec> - void getRowSlice(unsigned int row, unsigned int first, unsigned int last, Vec& dst) const - { - Elem const * v = (*this)row; - for (unsigned int c = first; c < last; ++c) dstc-first = vc; - } - - template <typename Vec> - void getColumnSlice(unsigned int first, unsigned int len, unsigned int col, Vec& dst) const - { - for (unsigned int r = 0; r < len; ++r) dstr = (*this)r+firstcol; - } - - template <typename Vec> - void setRowSlice(unsigned int row, unsigned int first, unsigned int len, const Vec& src) - { - Elem * v = (*this)row; - for (unsigned int c = 0; c < len; ++c) vc+first = srcc; - } - - template <typename Vec> - void setColumnSlice(unsigned int first, unsigned int len, unsigned int col, const Vec& src) - { - for (unsigned int r = 0; r < len; ++r) (*this)r+firstcol = srcr; - } - - template <typename Archive> void serialize(Archive& ar) - { - SerializationScope<Archive> scope(ar); - int n = _rows, m = _cols; - ar & n & m; - if (ar.isLoading()) this->newsize(n, m); - - for (int i = 0; i < n*m; ++i) ar & _mi; - } - - V3D_DEFINE_LOAD_SAVE(MatrixBase); - - protected: - void __destroy() - { - assert(_ownsData); - if (_m != 0) delete _m; - _m = 0; - _rows = _cols = 0; - } - - unsigned int _rows, _cols; - bool _ownsData; - Elem * _m; - }; - - //V3D_DEFINE_TEMPLATE_IOSTREAM_OPS(MatrixBase); - -//---------------------------------------------------------------------- - - template <typename T> - struct CCS_Matrix - { - typedef T value_type; - typedef T element_type; - - CCS_Matrix() - : _rows(0), _cols(0) - { } - - CCS_Matrix(int const rows, int const cols, vector<pair<int, int> > const& nonZeros) - : _rows(rows), _cols(cols) - { - this->initialize(nonZeros); - } - - CCS_Matrix(int const rows, int const cols, vector<pair<int, int> > const& nonZeros, vector<T> const& values) - : _rows(rows), _cols(cols) - { - assert(nonZeros.size() == values.size()); - - this->initialize(nonZeros); - for (size_t i = 0; i < values.size(); ++i) _values_destIdxsi = valuesi; - } - - CCS_Matrix(CCS_Matrix const& b) - : _rows(b._rows), _cols(b._cols), - _colStarts(b._colStarts), _rowIdxs(b._rowIdxs), _destIdxs(b._destIdxs), _values(b._values) - { } - - CCS_Matrix& operator=(CCS_Matrix const& b) - { - if (this == &b) return *this; - _rows = b._rows; - _cols = b._cols; - _colStarts = b._colStarts; - _rowIdxs = b._rowIdxs; - _destIdxs = b._destIdxs; - _values = b._values; - return *this; - } - - void create(int const rows, int const cols, vector<pair<int, int> > const& nonZeros) - { - _rows = rows; - _cols = cols; - this->initialize(nonZeros); - } - - unsigned int num_rows() const { return _rows; } - unsigned int num_cols() const { return _cols; } - - int getNonzeroCount() const { return _values.size(); } - - T const * getValues() const { return &_values0; } - T * getValues() { return &_values0; } - - int const * getDestIndices() const { return &_destIdxs0; } - int const * getColumnStarts() const { return &_colStarts0; } - int const * getRowIndices() const { return &_rowIdxs0; } - - void getRowRange(unsigned int col, unsigned int& firstRow, unsigned int& lastRow) const - { - firstRow = _rowIdxs_colStartscol; - lastRow = _rowIdxs_colStartscol+1-1+1; - } - - template <typename Vec> - void getColumnSlice(unsigned int first, unsigned int len, unsigned int col, Vec& dst) const - { - unsigned int const last = first + len; - - for (int r = 0; r < len; ++r) dstr = 0; // Fill vector with zeros - - int const colStart = _colStartscol; - int const colEnd = _colStartscol+1; - - int i = colStart; - int r; - // Skip rows less than the given start row - while (i < colEnd && (r = _rowIdxsi) < first) ++i; - - // Copy elements until the final row - while (i < colEnd && (r = _rowIdxsi) < last) - { - dstr-first = _valuesi; - ++i; - } - } // end getColumnSlice() - - int getColumnNonzeroCount(unsigned int col) const - { - int const colStart = _colStartscol; - int const colEnd = _colStartscol+1; - return colEnd - colStart; - } - - template <typename VecA, typename VecB> - void getSparseColumn(unsigned int col, VecA& rows, VecB& values) const - { - int const colStart = _colStartscol; - int const colEnd = _colStartscol+1; - int const nnz = colEnd - colStart; - - for (int i = 0; i < nnz; ++i) - { - rowsi = _rowIdxscolStart + i; - valuesi = _valuescolStart + i; - } - } - - protected: - struct NonzeroInfo - { - int row, col, serial; - - // Sort wrt the column first - bool operator<(NonzeroInfo const& rhs) const - { - if (col < rhs.col) return true; - if (col > rhs.col) return false; - return row < rhs.row; - } - }; - - void initialize(std::vector<std::pair<int, int> > const& nonZeros) - { - using namespace std; - - int const nnz = nonZeros.size(); - - _colStarts.resize(_cols + 1); - _rowIdxs.resize(nnz); - - vector<NonzeroInfo> nz(nnz); - for (int k = 0; k < nnz; ++k) - { - nzk.row = nonZerosk.first; - nzk.col = nonZerosk.second; - nzk.serial = k; - } - - // Sort in column major order - std::sort(nz.begin(), nz.end()); - - for (size_t k = 0; k < nnz; ++k) _rowIdxsk = nzk.row; - - int curCol = -1; - for (int k = 0; k < nnz; ++k) - { - NonzeroInfo const& el = nzk; - if (el.col != curCol) - { - // Update empty cols between - for (int c = curCol+1; c < el.col; ++c) _colStartsc = k; - - curCol = el.col; - _colStartscurCol = k; - } // end if - } // end for (k) - - // Update remaining columns - for (int c = curCol+1; c <= _cols; ++c) _colStartsc = nnz; - - _destIdxs.resize(nnz); - for (int k = 0; k < nnz; ++k) _destIdxsnzk.serial = k; - - _values.resize(nnz); - } // end initialize() - - int _rows, _cols; - std::vector<int> _colStarts; - std::vector<int> _rowIdxs; - std::vector<int> _destIdxs; - std::vector<T> _values; - }; // end struct CCS_Matrix - -//---------------------------------------------------------------------- - - template <typename Vec, typename Elem> - inline void - fillVector(Elem val, Vec& v) - { - // We do not use std::fill since we rely only on size() and operator member functions. - for (unsigned int i = 0; i < v.size(); ++i) vi = val; - } - - template <typename Vec> - inline void - makeZeroVector(Vec& v) - { - fillVector(0, v); - } - - template <typename VecA, typename VecB> - inline void - copyVector(VecA const& src, VecB& dst) - { - assert(src.size() == dst.size()); - // We do not use std::fill since we rely only on size() and operator member functions. - for (unsigned int i = 0; i < src.size(); ++i) dsti = srci; - } - - template <typename VecA, typename VecB> - inline void - copyVectorSlice(VecA const& src, unsigned int srcStart, unsigned int srcLen, - VecB& dst, unsigned int dstStart) - { - unsigned int const end = std::min(srcStart + srcLen, src.size()); - unsigned int const sz = dst.size(); - unsigned int i0, i1; - for (i0 = srcStart, i1 = dstStart; i0 < end && i1 < sz; ++i0, ++i1) dsti1 = srci0; - } - - template <typename Vec> - inline typename Vec::value_type - norm_L1(Vec const& v) - { - typename Vec::value_type res(0); - for (unsigned int i = 0; i < v.size(); ++i) res += std::abs(vi); - return res; - } - - template <typename Vec> - inline typename Vec::value_type - norm_Linf(Vec const& v) - { - typename Vec::value_type res(0); - for (unsigned int i = 0; i < v.size(); ++i) res = std::max(res, std::abs(vi)); - return res; - } - - template <typename Vec> - inline typename Vec::value_type - norm_L2(Vec const& v) - { - typename Vec::value_type res(0); - for (unsigned int i = 0; i < v.size(); ++i) res += vi*vi; - return sqrt((double)res); - } - - template <typename Vec> - inline typename Vec::value_type - sqrNorm_L2(Vec const& v) - { - typename Vec::value_type res(0); - for (unsigned int i = 0; i < v.size(); ++i) res += vi*vi; - return res; - } - - template <typename VecA, typename VecB> - inline typename VecA::value_type - distance_L2(VecA const& a, VecB const& b) - { - assert(a.size() == b.size()); - typename VecA::value_type res(0); - for (unsigned int i = 0; i < a.size(); ++i) res += (ai-bi)*(ai-bi); - return sqrt(res); - } - - template <typename VecA, typename VecB> - inline typename VecA::value_type - sqrDistance_L2(VecA const& a, VecB const& b) - { - assert(a.size() == b.size()); - typename VecA::value_type res(0); - for (unsigned int i = 0; i < a.size(); ++i) res += (ai-bi)*(ai-bi); - return res; - } - - template <typename VecA, typename VecB> - inline typename VecA::value_type - distance_Linf(VecA const& a, VecB const& b) - { - typedef typename VecA::value_type T; - assert(a.size() == b.size()); - T res(0); - for (unsigned int i = 0; i < a.size(); ++i) res = std::max(res, T(fabs(ai - bi))); - return res; - } - - template <typename Vec> - inline void - normalizeVector(Vec& v) - { - typename Vec::value_type norm(norm_L2(v)); - for (unsigned int i = 0; i < v.size(); ++i) vi /= norm; - } - - template<typename VecA, typename VecB> - inline typename VecA::value_type - innerProduct(VecA const& a, VecB const& b) - { - assert(a.size() == b.size()); - typename VecA::value_type res(0); - for (unsigned int i = 0; i < a.size(); ++i) res += ai * bi; - return res; - } - - template <typename Elem, typename VecA, typename VecB> - inline void - scaleVector(Elem s, VecA const& v, VecB& dst) - { - for (unsigned int i = 0; i < v.size(); ++i) dsti = s * vi; - } - - template <typename Elem, typename Vec> - inline void - scaleVectorIP(Elem s, Vec& v) - { - typedef typename Vec::value_type Elem2; - for (unsigned int i = 0; i < v.size(); ++i) - vi = (Elem2)(vi * s); - } - - template <typename VecA, typename VecB, typename VecC> - inline void - makeCrossProductVector(VecA const& v, VecB const& w, VecC& dst) - { - assert(v.size() == 3); - assert(w.size() == 3); - assert(dst.size() == 3); - dst0 = v1*w2 - v2*w1; - dst1 = v2*w0 - v0*w2; - dst2 = v0*w1 - v1*w0; - } - - template <typename VecA, typename VecB, typename VecC> - inline void - addVectors(VecA const& v, VecB const& w, VecC& dst) - { - assert(v.size() == w.size()); - assert(v.size() == dst.size()); - for (unsigned int i = 0; i < v.size(); ++i) dsti = vi + wi; - } - - template <typename VecA, typename VecB> - inline void - addVectorsIP(VecA const& v, VecB& dst) - { - assert(v.size() == dst.size()); - for (unsigned int i = 0; i < v.size(); ++i) dsti += vi; - } - - template <typename VecA, typename VecB, typename VecC> - inline void - subtractVectors(VecA const& v, VecB const& w, VecC& dst) - { - assert(v.size() == w.size()); - assert(v.size() == dst.size()); - for (unsigned int i = 0; i < v.size(); ++i) dsti = vi - wi; - } - - template <typename Elem, typename VecA, typename VecB, typename VecC> - inline void - makeInterpolatedVector(Elem a, VecA const& v, Elem b, VecB const& w, VecC& dst) - { - assert(v.size() == w.size()); - assert(v.size() == dst.size()); - for (unsigned int i = 0; i < v.size(); ++i) dsti = a * vi + b * wi; - } - - template <typename VecA, typename VecB> - inline typename VecA::value_type - unsignedAngleBetweenVectors(VecA const& v, VecB const& w) - { - assert(v.size() == w.size()); - typename VecA::value_type dot = innerProduct(v, w) / norm_L2(v) / norm_L2(w); - if (dot > 1.0) return 0; - if (dot < -1.0) return M_PI; - return acos(dot); - } - - template <typename MatA, typename MatB> - inline void - copyMatrix(MatA const& src, MatB& dst) - { - unsigned int const rows = src.num_rows(); - unsigned int const cols = src.num_cols(); - assert(dst.num_rows() == rows); - assert(dst.num_cols() == cols); - for (unsigned int c = 0; c < cols; ++c) - for (unsigned int r = 0; r < rows; ++r) dstrc = srcrc; - } - - template <typename MatA, typename MatB> - inline void - copyMatrixSlice(MatA const& src, unsigned int rowStart, unsigned int colStart, unsigned int rowLen, unsigned int colLen, - MatB& dst, unsigned int dstRow, unsigned int dstCol) - { - unsigned int const rows = dst.num_rows(); - unsigned int const cols = dst.num_cols(); - - unsigned int const rowEnd = std::min(rowStart + rowLen, src.num_rows()); - unsigned int const colEnd = std::min(colStart + colLen, src.num_cols()); - - unsigned int c0, c1, r0, r1; - - for (c0 = colStart, c1 = dstCol; c0 < colEnd && c1 < cols; ++c0, ++c1) - for (r0 = rowStart, r1 = dstRow; r0 < rowEnd && r1 < rows; ++r0, ++r1) - dstr1c1 = srcr0c0; - } - - template <typename MatA, typename MatB> - inline void - makeTransposedMatrix(MatA const& src, MatB& dst) - { - unsigned int const rows = src.num_rows(); - unsigned int const cols = src.num_cols(); - assert(dst.num_cols() == rows); - assert(dst.num_rows() == cols); - for (unsigned int c = 0; c < cols; ++c) - for (unsigned int r = 0; r < rows; ++r) dstcr = srcrc; - } - - template <typename Mat> - inline void - fillMatrix(Mat& m, typename Mat::value_type val) - { - unsigned int const rows = m.num_rows(); - unsigned int const cols = m.num_cols(); - for (unsigned int c = 0; c < cols; ++c) - for (unsigned int r = 0; r < rows; ++r) mrc = val; - } - - template <typename Mat> - inline void - makeZeroMatrix(Mat& m) - { - fillMatrix(m, 0); - } - - template <typename Mat> - inline void - makeIdentityMatrix(Mat& m) - { - makeZeroMatrix(m); - unsigned int const rows = m.num_rows(); - unsigned int const cols = m.num_cols(); - unsigned int n = std::min(rows, cols); - for (unsigned int i = 0; i < n; ++i) - mii = 1; - } - - template <typename Mat, typename Vec> - inline void - makeCrossProductMatrix(Vec const& v, Mat& m) - { - assert(v.size() == 3); - assert(m.num_rows() == 3); - assert(m.num_cols() == 3); - m00 = 0; m01 = -v2; m02 = v1; - m10 = v2; m11 = 0; m12 = -v0; - m20 = -v1; m21 = v0; m22 = 0; - } - - template <typename Mat, typename Vec> - inline void - makeOuterProductMatrix(Vec const& v, Mat& m) - { - assert(m.num_cols() == m.num_rows()); - assert(v.size() == m.num_cols()); - unsigned const sz = v.size(); - for (unsigned r = 0; r < sz; ++r) - for (unsigned c = 0; c < sz; ++c) mrc = vr*vc; - } - - template <typename Mat, typename VecA, typename VecB> - inline void - makeOuterProductMatrix(VecA const& u, VecB const& v, Mat& m) - { - assert(m.num_cols() == m.num_rows()); - assert(u.size() == m.num_cols()); - assert(v.size() == m.num_cols()); - unsigned const sz = u.size(); - for (unsigned r = 0; r < sz; ++r) - for (unsigned c = 0; c < sz; ++c) mrc = ur*vc; - } - - template <typename MatA, typename MatB, typename MatC> - void addMatrices(MatA const& a, MatB const& b, MatC& dst) - { - assert(a.num_cols() == b.num_cols()); - assert(a.num_rows() == b.num_rows()); - assert(dst.num_cols() == a.num_cols()); - assert(dst.num_rows() == a.num_rows()); - - unsigned int const rows = a.num_rows(); - unsigned int const cols = a.num_cols(); - - for (unsigned r = 0; r < rows; ++r) - for (unsigned c = 0; c < cols; ++c) dstrc = arc + brc; - } - - template <typename MatA, typename MatB> - void addMatricesIP(MatA const& a, MatB& dst) - { - assert(dst.num_cols() == a.num_cols()); - assert(dst.num_rows() == a.num_rows()); - - unsigned int const rows = a.num_rows(); - unsigned int const cols = a.num_cols(); - - for (unsigned r = 0; r < rows; ++r) - for (unsigned c = 0; c < cols; ++c) dstrc += arc; - } - - template <typename MatA, typename MatB, typename MatC> - void subtractMatrices(MatA const& a, MatB const& b, MatC& dst) - { - assert(a.num_cols() == b.num_cols()); - assert(a.num_rows() == b.num_rows()); - assert(dst.num_cols() == a.num_cols()); - assert(dst.num_rows() == a.num_rows()); - - unsigned int const rows = a.num_rows(); - unsigned int const cols = a.num_cols(); - - for (unsigned r = 0; r < rows; ++r) - for (unsigned c = 0; c < cols; ++c) dstrc = arc - brc; - } - - template <typename MatA, typename Elem, typename MatB> - inline void - scaleMatrix(MatA const& m, Elem scale, MatB& dst) - { - unsigned int const rows = m.num_rows(); - unsigned int const cols = m.num_cols(); - for (unsigned int c = 0; c < cols; ++c) - for (unsigned int r = 0; r < rows; ++r) dstrc = mrc * scale; - } - - template <typename Mat, typename Elem> - inline void - scaleMatrixIP(Elem scale, Mat& m) - { - unsigned int const rows = m.num_rows(); - unsigned int const cols = m.num_cols(); - for (unsigned int c = 0; c < cols; ++c) - for (unsigned int r = 0; r < rows; ++r) mrc *= scale; - } - - template <typename Mat, typename VecA, typename VecB> - inline void - multiply_A_v(Mat const& m, VecA const& in, VecB& dst) - { - unsigned int const rows = m.num_rows(); - unsigned int const cols = m.num_cols(); - assert(in.size() == cols); - assert(dst.size() == rows); - - makeZeroVector(dst); - - for (unsigned int r = 0; r < rows; ++r) - for (unsigned int c = 0; c < cols; ++c) dstr += mrc * inc; - } - - template <typename Mat, typename VecA, typename VecB> - inline void - multiply_A_v_projective(Mat const& m, VecA const& in, VecB& dst) - { - unsigned int const rows = m.num_rows(); - unsigned int const cols = m.num_cols(); - assert(in.size() == cols-1); - assert(dst.size() == rows-1); - - typename VecB::value_type w = mrows-1cols-1; - unsigned int r, i; - for (i = 0; i < cols-1; ++i) w += mrows-1i * ini; - for (r = 0; r < rows-1; ++r) dstr = mrcols-1; - for (r = 0; r < rows-1; ++r) - for (unsigned int c = 0; c < cols-1; ++c) dstr += mrc * inc; - for (i = 0; i < rows-1; ++i) dsti /= w; - } - - template <typename Mat, typename VecA, typename VecB> - inline void - multiply_A_v_affine(Mat const& m, VecA const& in, VecB& dst) - { - unsigned int const rows = m.num_rows(); - unsigned int const cols = m.num_cols(); - assert(in.size() == cols-1); - assert(dst.size() == rows); - - unsigned int r; - - for (r = 0; r < rows; ++r) dstr = mrcols-1; - for (r = 0; r < rows; ++r) - for (unsigned int c = 0; c < cols-1; ++c) dstr += mrc * inc; - } - - template <typename Mat, typename VecA, typename VecB> - inline void - multiply_At_v(Mat const& m, VecA const& in, VecB& dst) - { - unsigned int const rows = m.num_rows(); - unsigned int const cols = m.num_cols(); - assert(in.size() == rows); - assert(dst.size() == cols); - - makeZeroVector(dst); - for (unsigned int c = 0; c < cols; ++c) - for (unsigned int r = 0; r < rows; ++r) dstc += mrc * inr; - } - - template <typename SparseMat, typename VecA, typename VecB> - inline void - multiply_At_v_Sparse(SparseMat const& a, VecA const& in, VecB& dst) - { - assert(in.size() == a.num_rows()); - assert(dst.size() == a.num_cols()); - - typedef typename VecB::value_type Elem; - - std::vector<int> rows(a.num_rows()); - std::vector<Elem> vals(a.num_rows()); - - makeZeroVector(dst); - for (unsigned int c = 0; c < a.num_cols(); ++c) - { - int const nnz = a.getColumnNonzeroCount(c); - a.getSparseColumn(c, rows, vals); - - Elem accum = 0; - - for (int i = 0; i < nnz; ++i) - { - int const r = rowsi; - accum += valsi * inr; - } - dstc = accum; - } - } // end multiply_At_v_Sparse() - - template <typename MatA, typename MatB> - inline void - multiply_At_A(MatA const& a, MatB& dst) - { - assert(dst.num_rows() == a.num_cols()); - assert(dst.num_cols() == a.num_cols()); - - typedef typename MatB::value_type Elem; - - int const M = a.num_rows(); - int const N = a.num_cols(); - - Elem accum; - for (int r = 0; r < N; ++r) - for (int c = 0; c < N; ++c) - { - accum = 0; - for (int k = 0; k < M; ++k) accum += akr * akc; - dstrc = accum; - } - } - - template <typename SparseMatA, typename MatB> - inline void - multiply_At_A_Sparse(SparseMatA const& a, MatB& dst) - { - assert(dst.num_rows() == a.num_cols()); - assert(dst.num_cols() == a.num_cols()); - - typedef typename MatB::value_type Elem; - - makeZeroMatrix(dst); - - std::vector<int> rows1(a.num_rows()), rows2(a.num_rows()); - std::vector<Elem> vals1(a.num_rows()), vals2(a.num_rows()); - - for (unsigned int r = 0; r < dst.num_rows(); ++r) - { - int const nnz1 = a.getColumnNonzeroCount(r); - a.getSparseColumn(r, rows1, vals1); - - for (unsigned int c = 0; c <= r; ++c) - { - int const nnz2 = a.getColumnNonzeroCount(c); - a.getSparseColumn(c, rows2, vals2); - - Elem accum = 0; - - int i1 = 0, i2 = 0; - while (i1 < nnz1 && i2 < nnz2) - { - if (rows1i1 > rows2i2) - ++i2; - else if (rows1i1 < rows2i2) - ++i1; - else - { - accum += vals1i1 * vals2i2; - ++i1; - ++i2; - } - } // end while - - dstrc = accum; - dstcr = accum; - } // end for (c) - } // end for (r) - } // multiply_At_A_Sparse() - - template <typename MatA, typename MatB, typename MatC> - inline void - multiply_A_B(MatA const& a, MatB const& b, MatC& dst) - { - assert(a.num_cols() == b.num_rows()); - assert(dst.num_rows() == a.num_rows()); - assert(dst.num_cols() == b.num_cols()); - - typedef typename MatC::value_type Elem; - - Elem accum; - for (unsigned int r = 0; r < a.num_rows(); ++r) - for (unsigned int c = 0; c < b.num_cols(); ++c) - { - accum = 0; - for (unsigned int k = 0; k < a.num_cols(); ++k) accum += ark * bkc; - dstrc = accum; - } - } - - template <typename MatA, typename MatB, typename MatC> - inline void - multiply_At_B(MatA const& a, MatB const& b, MatC& dst) - { - assert(a.num_rows() == b.num_rows()); - assert(dst.num_rows() == a.num_cols()); - assert(dst.num_cols() == b.num_cols()); - - typedef typename MatC::value_type Elem; - - Elem accum; - for (unsigned int r = 0; r < a.num_cols(); ++r) - for (unsigned int c = 0; c < b.num_cols(); ++c) - { - accum = 0; - for (unsigned int k = 0; k < a.num_rows(); ++k) accum += akr * bkc; - dstrc = accum; - } - } - - template <typename MatA, typename MatB, typename MatC> - inline void - multiply_A_Bt(MatA const& a, MatB const& b, MatC& dst) - { - assert(a.num_cols() == b.num_cols()); - assert(dst.num_rows() == a.num_rows()); - assert(dst.num_cols() == b.num_rows()); - - typedef typename MatC::value_type Elem; - - Elem accum; - for (unsigned int r = 0; r < a.num_rows(); ++r) - for (unsigned int c = 0; c < b.num_rows(); ++c) - { - accum = 0; - for (unsigned int k = 0; k < a.num_cols(); ++k) accum += ark * bck; - dstrc = accum; - } - } - - template <typename Mat> - inline void - transposeMatrixIP(Mat& a) - { - assert(a.num_rows() == a.num_cols()); - - for (unsigned int r = 0; r < a.num_rows(); ++r) - for (unsigned int c = 0; c < r; ++c) - std::swap(arc, acr); - } - - template <typename Mat> - inline typename Mat::value_type - matrixDeterminant3x3(Mat const& A) - { - assert(A.num_rows() == 3); - assert(A.num_cols() == 3); - return (A00*A11*A22 + A01*A12*A20 + A02*A10*A21 - -A02*A11*A20 - A01*A10*A22 - A00*A12*A21); - } - - template <typename Mat> - inline double - matrixNormFrobenius(Mat const& a) - { - double accum(0.0); - for (unsigned int r = 0; r < a.num_rows(); ++r) - for (unsigned int c = 0; c < a.num_cols(); ++c) - accum += arc*arc; - - return sqrt(accum); - } - -//********************************************************************** - - //! Convert a matrix to upper triangular form, aka Gauss elimination. - template <typename Mat> - inline void - convertToRowEchelonMatrix(Mat& A) - { - typedef typename Mat::value_type Field; - - int const n = A.num_rows(); - int const m = A.num_cols(); - - int i, j, k; - - int lead = 0; // Pivot column - - // Pass 1: Generate a upper right triangular matrix - for (i = 0; i < n && lead < m; ++i, ++lead) - { - int pivot_row = i; - Field pivot_elem(0); - - while (lead < m) - { - // Search for the largest pivot element in column lead - for (k = i; k < n; ++k) - { - Field a = std::abs(Aklead); - if (a > pivot_elem) - { - pivot_elem = a; - pivot_row = k; - } - } // end for (k) - if (pivot_elem == Field(0)) - ++lead; - else - break; - } - if (lead >= m) break; - - if (i != pivot_row) - { - // Exchange row i and pivot_row - for (j = 0; j < m; ++j) - { - Field tmp = Aij; - Aij = Apivot_rowj; - Apivot_rowj = tmp; - } - } - - Field pivot = Ailead; - Field rcpPivot = Field(1)/pivot; - - Ailead = Field(1); - for (j = lead+1; j < m; ++j) Aij = Aij * rcpPivot; - - for (k = i+1; k < n; ++k) - { - Field q = Aklead; - Aklead = Field(0); - for (j = lead+1; j < m; ++j) Akj = Akj - q*Aij; - } - } // end for (i) - } // end convertToRowEchelonMatrix() - - // Convert a row echelon matrix to a reduced one, i.e. Gauss-Jordan elimination. - template <typename Mat> - inline void - convertToReducedRowEchelonMatrix(Mat& A) - { - typedef typename Mat::value_type Field; - - // Pass 2: Remove additional elements above the diagonal - int const n = A.num_rows(); - int const m = A.num_cols(); - - for (int i = n-1; i >= 0; --i) - { - int lead = i; - while (lead < m && Ailead == Field(0)) ++lead; - - if (lead >= m) continue; - - for (int k = 0; k < i; ++k) - { - Field q = Aklead; - for (int j = lead; j < m; ++j) - Akj = Akj - q*Aij; - } // end for (k) - } // end for (i) - } // end convertToReducedRowEchelonMatrix() - - -} // end namespace V3D - -#endif
View file
slowmoVideo-0.4.tar.gz/src/V3D/README.TXT
Deleted
@@ -1,65 +0,0 @@ -Description - -This is a GPU implementation of feature point tracking with and without -simultaneous gain estimation (i.e. changes in the overall image brightness are -detected and handled). For a technical description see C. Zach, D. Gallup, and -J.-M. Frahm, "Fast Gain-Adaptive KLT Tracking on the GPU,". CVPR Workshop on -Computer Vision on GPU's (CVGPU), 2008, available at -http://cs.unc.edu/~cmzach/publications.html. - -Additionally, this package now includes the TV-L1 optical flow implementation -as described in C.Zach, T. Pock, and H. Bischof, "A Duality Based Approach for -Realtime TV-L1 Optical Flow", Pattern Recognition (Proc. DAGM), vol. 4792 of -Lecture Notes in Computer Science, 2007 (also available at -http://cs.unc.edu/~cmzach/publications.html). - -Using the simple API for tracking is demonstrated in -Apps/GL/klt_for_video.cpp, which successively reads frames from videos (using -the OpenCV library) and displays the obtained feature tracks. Note that you -have to set the V3D_SHADER_DIR environment variable to point to the Shader -directory, e.g. export -V3D_SHADER_DIR=/home/user/src/GPU-KLT+FLOW-1.0/GL/Shaders with a sh/bash -environment. A simple application for TV-L1 optical flow is provided in -Apps/GL/tvl1_flow.cpp. - -Requirements - -NVidias Cg toolkit (version 2 or later, -http://developer.nvidia.com/object/cg_toolkit.html) and the OpenGL extension -wrangler library (glew.sourceforge.net) are required to build the -library. Currenlty, the GPU tracker is limited to NVidia hardware (Geforce6 -series or newer, the hardware must support the fp40 Cg profile). If you want -to run the simple demo applications, the OpenCV computer vision library -(http://sourceforge.net/projects/opencvlibrary/) with sufficient support for -video codecs (e.g. through ffmpeg or xinelib) is required. The build system -uses cmake (www.cmake.org). - -The optical flow code can use libpng or libjpeg for loading images. If none of -these is available (modify the main CMakeLists.txt), then binary PNM images -(magic code either P5 or P6) are still supported. GLUT or freeglut is used for -GL window handling. - -The library was developed under Linux, but should compile equally well on -other operating systems. - --Christopher Zach (chzach@inf.ethz.ch) - - -/* -Copyright (c) 2008-2010 UNC-Chapel Hill & ETH Zurich - -This file is part of GPU-KLT+FLOW. - -GPU-KLT+FLOW is free software: you can redistribute it and/or modify it under -the terms of the GNU Lesser General Public License as published by the Free -Software Foundation, either version 3 of the License, or (at your option) any -later version. - -GPU-KLT+FLOW is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more -details. - -You should have received a copy of the GNU Lesser General Public License along -with GPU-KLT+FLOW. If not, see <http://www.gnu.org/licenses/>. -*/
View file
slowmoVideo-0.4.tar.gz/src/cmake
Deleted
-(directory)
View file
slowmoVideo-0.4.tar.gz/src/cmake/FindFFMPEG.cmake
Deleted
@@ -1,137 +0,0 @@ -# From: http://www.openlibraries.org/browser/trunk/FindFFMPEG.cmake - -# - Try to find FFMPEG -# Once done this will define -# -# FFMPEG_FOUND - system has FFMPEG -# FFMPEG_INCLUDE_DIR - the include directories -# FFMPEG_LIBRARY_DIR - the directory containing the libraries -# FFMPEG_LIBRARIES - link these to use FFMPEG -# FFMPEG_SWSCALE_FOUND - FFMPEG also has SWSCALE -# - -#SET( FFMPEG_HEADERS avformat.h avcodec.h avutil.h avdevice.h ) -#SET( FFMPEG_PATH_SUFFIXES libavformat libavcodec libavutil libavdevice ) -SET( FFMPEG_HEADERS avformat.h avcodec.h avutil.h ) -SET( FFMPEG_PATH_SUFFIXES libavformat libavcodec libavutil ) -SET( FFMPEG_SWS_HEADERS swscale.h ) -SET( FFMPEG_SWS_PATH_SUFFIXES libswscale ) - -if( WIN32 ) - #SET( FFMPEG_LIBRARIES avformat.lib avcodec.lib avutil.lib avdevice.lib ) - SET( FFMPEG_LIBRARIES avformat.lib avcodec.lib avutil.lib ) - SET( FFMPEG_SWS_LIBRARIES swscale.lib ) - SET( FFMPEG_LIBRARY_DIR $ENV{FFMPEGDIR}\\lib ) - SET( FFMPEG_INCLUDE_PATHS $ENV{FFMPEGDIR}\\include ) - - # check to see if we can find swscale - SET( TMP_ TMP-NOTFOUND ) - FIND_PATH( TMP_ ${FFMPEG_SWS_LIBRARIES} - PATHS ${FFMPEG_LIBRARY_DIR} ) - IF ( TMP_ ) - SET( SWSCALE_FOUND TRUE ) - ENDIF( TMP_ ) -else( WIN32 ) - #SET( FFMPEG_LIBRARIES avformat avcodec avutil avdevice ) - SET( FFMPEG_LIBRARIES avformat avcodec avutil ) - SET( FFMPEG_SWS_LIBRARIES swscale ) - INCLUDE(FindPkgConfig) - if ( PKG_CONFIG_FOUND ) - pkg_check_modules( AVFORMAT libavformat ) - pkg_check_modules( AVCODEC libavcodec ) - pkg_check_modules( AVUTIL libavutil ) - #pkg_check_modules( AVDEVICE libavdevice ) - pkg_check_modules( SWSCALE libswscale ) - endif ( PKG_CONFIG_FOUND ) - - SET( FFMPEG_LIBRARY_DIR ${AVFORMAT_LIBRARY_DIRS} - ${AVCODEC_LIBRARY_DIRS} - ${AVUTIL_LIBRARY_DIRS} - #${AVDEVICE_LIBRARY_DIRS} - ) - SET( FFMPEG_INCLUDE_PATHS ${AVFORMAT_INCLUDE_DIRS} - ${AVCODEC_INCLUDE_DIRS} - ${AVUTIL_INCLUDE_DIRS} - #${AVDEVICE_INCLUDE_DIRS} - ) - # check to see if we can find swscale - FIND_LIBRARY(LIB_SWSCALE_ swscale ${FFMPEG_LIBRARY_DIR} ) - IF ( LIB_SWSCALE_ ) - SET( SWSCALE_FOUND TRUE ) - ENDIF( LIB_SWSCALE_ ) - -endif( WIN32 ) - -# add in swscale if found -IF ( SWSCALE_FOUND ) - SET( FFMPEG_LIBRARY_DIR ${FFMPEG_LIBRARY_DIR} - ${SWSCALE_LIBRARY_DIRS} ) - SET( FFMPEG_INCLUDE_PATHS ${FFMPEG_INCLUDE_PATHS} - ${SWSCALE_INCLUDE_DIRS} ) - SET( FFMPEG_HEADERS ${FFMPEG_HEADERS} - ${FFMPEG_SWS_HEADERS} ) - SET( FFMPEG_PATH_SUFFIXES ${FFMPEG_PATH_SUFFIXES} - ${FFMPEG_SWS_PATH_SUFFIXES} ) - SET( FFMPEG_LIBRARIES ${FFMPEG_LIBRARIES} - ${FFMPEG_SWS_LIBRARIES} ) -ENDIF ( SWSCALE_FOUND ) - -# find includes -SET( INC_SUCCESS 0 ) -SET( TMP_ TMP-NOTFOUND ) -SET( FFMPEG_INCLUDE_DIR ${FFMPEG_INCLUDE_PATHS} ) -FOREACH( INC_ ${FFMPEG_HEADERS} ) - message(STATUS "checking: ${INC_}" ) - - FIND_PATH( TMP_ ${INC_} - PATHS ${FFMPEG_INCLUDE_PATHS} - PATH_SUFFIXES ${FFMPEG_PATH_SUFFIXES} ) - IF ( TMP_ ) - message(STATUS " ${TMP_}" ) - MATH( EXPR INC_SUCCESS ${INC_SUCCESS}+1 ) - SET( FFMPEG_INCLUDE_DIR ${FFMPEG_INCLUDE_DIR} ${TMP_} ) - ENDIF ( TMP_ ) - SET( TMP_ TMP-NOTFOUND ) -ENDFOREACH( INC_ ) - -list(LENGTH FFMPEG_INCLUDE_DIR LENGTH_INCLUDES) -list(LENGTH FFMPEG_LIBRARY_DIR LENGTH_LIBRARIES) - -# clear out duplicates -if(LENGTH_INCLUDES GREATER 0) -LIST( REMOVE_DUPLICATES FFMPEG_INCLUDE_DIR ) -endif(LENGTH_INCLUDES GREATER 0) -if(LENGTH_LIBRARIES GREATER 0) -LIST( REMOVE_DUPLICATES FFMPEG_LIBRARY_DIR ) -endif(LENGTH_LIBRARIES GREATER 0) - -# find the full paths of the libraries -SET( TMP_ TMP-NOTFOUND ) -IF ( NOT WIN32 ) - FOREACH( LIB_ ${FFMPEG_LIBRARIES} ) - FIND_LIBRARY( TMP_ NAMES ${LIB_} PATHS ${FFMPEG_LIBRARY_DIR} ) - IF ( TMP_ ) - SET( FFMPEG_LIBRARIES_FULL ${FFMPEG_LIBRARIES_FULL} ${TMP_} ) - ENDIF ( TMP_ ) - SET( TMP_ TMP-NOTFOUND ) - ENDFOREACH( LIB_ ) - SET ( FFMPEG_LIBRARIES ${FFMPEG_LIBRARIES_FULL} ) -ENDIF( NOT WIN32 ) - -LIST( LENGTH FFMPEG_HEADERS LIST_SIZE_ ) - -SET( FFMPEG_FOUND FALSE ) -SET( FFMPEG_SWSCALE_FOUND FALSE ) -IF ( ${INC_SUCCESS} EQUAL ${LIST_SIZE_} ) - SET( FFMPEG_FOUND TRUE ) - SET( FFMPEG_SWSCALE_FOUND ${SWSCALE_FOUND} ) -ENDIF ( ${INC_SUCCESS} EQUAL ${LIST_SIZE_} ) - -string(REPLACE "/usr/include/" "" FFMPEG_INCLUDE_DIR "${FFMPEG_INCLUDE_DIR}") - -# On OS X we ffmpeg libraries depend on VideoDecodeAcceleration and CoreVideo frameworks -IF (APPLE) - SET(FFMPEG_LIBRARIES ${FFMPEG_LIBRARIES} "-framework CoreFoundation -framework QuartzCore -framework VideoDecodeAcceleration -liconv -lbz2 -lz") -ENDIF() - -
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo
Deleted
-(directory)
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/Doxyfile
Deleted
@@ -1,1716 +0,0 @@ -# Doxyfile 1.7.4 - -# This file describes the settings to be used by the documentation system -# doxygen (www.doxygen.org) for a project. -# -# All text after a hash (#) is considered a comment and will be ignored. -# The format is: -# TAG = value value, ... -# For lists items can also be appended using: -# TAG += value value, ... -# Values that contain spaces should be placed between quotes (" "). - -#--------------------------------------------------------------------------- -# Project related configuration options -#--------------------------------------------------------------------------- - -# This tag specifies the encoding used for all characters in the config file -# that follow. The default is UTF-8 which is also the encoding used for all -# text before the first occurrence of this tag. Doxygen uses libiconv (or the -# iconv built into libc) for the transcoding. See -# http://www.gnu.org/software/libiconv for the list of possible encodings. - -DOXYFILE_ENCODING = UTF-8 - -# The PROJECT_NAME tag is a single word (or a sequence of words surrounded -# by quotes) that should identify the project. - -PROJECT_NAME = slowmoVideo - -# The PROJECT_NUMBER tag can be used to enter a project or revision number. -# This could be handy for archiving the generated documentation or -# if some version control system is used. - -PROJECT_NUMBER = - -# Using the PROJECT_BRIEF tag one can provide an optional one line description -# for a project that appears at the top of each page and should give viewer -# a quick idea about the purpose of the project. Keep the description short. - -PROJECT_BRIEF = - -# With the PROJECT_LOGO tag one can specify an logo or icon that is -# included in the documentation. The maximum height of the logo should not -# exceed 55 pixels and the maximum width should not exceed 200 pixels. -# Doxygen will copy the logo to the output directory. - -PROJECT_LOGO = - -# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) -# base path where the generated documentation will be put. -# If a relative path is entered, it will be relative to the location -# where doxygen was started. If left blank the current directory will be used. - -OUTPUT_DIRECTORY = docs - -# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create -# 4096 sub-directories (in 2 levels) under the output directory of each output -# format and will distribute the generated files over these directories. -# Enabling this option can be useful when feeding doxygen a huge amount of -# source files, where putting all generated files in the same directory would -# otherwise cause performance problems for the file system. - -CREATE_SUBDIRS = NO - -# The OUTPUT_LANGUAGE tag is used to specify the language in which all -# documentation generated by doxygen is written. Doxygen will use this -# information to generate all constant output in the proper language. -# The default language is English, other supported languages are: -# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, -# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, -# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English -# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, -# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, -# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. - -OUTPUT_LANGUAGE = English - -# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will -# include brief member descriptions after the members that are listed in -# the file and class documentation (similar to JavaDoc). -# Set to NO to disable this. - -BRIEF_MEMBER_DESC = YES - -# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend -# the brief description of a member or function before the detailed description. -# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the -# brief descriptions will be completely suppressed. - -REPEAT_BRIEF = YES - -# This tag implements a quasi-intelligent brief description abbreviator -# that is used to form the text in various listings. Each string -# in this list, if found as the leading text of the brief description, will be -# stripped from the text and the result after processing the whole list, is -# used as the annotated text. Otherwise, the brief description is used as-is. -# If left blank, the following values are used ("$name" is automatically -# replaced with the name of the entity): "The $name class" "The $name widget" -# "The $name file" "is" "provides" "specifies" "contains" -# "represents" "a" "an" "the" - -ABBREVIATE_BRIEF = - -# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then -# Doxygen will generate a detailed section even if there is only a brief -# description. - -ALWAYS_DETAILED_SEC = NO - -# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all -# inherited members of a class in the documentation of that class as if those -# members were ordinary class members. Constructors, destructors and assignment -# operators of the base classes will not be shown. - -INLINE_INHERITED_MEMB = NO - -# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full -# path before files name in the file list and in the header files. If set -# to NO the shortest path that makes the file name unique will be used. - -FULL_PATH_NAMES = YES - -# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag -# can be used to strip a user-defined part of the path. Stripping is -# only done if one of the specified strings matches the left-hand part of -# the path. The tag can be used to show relative paths in the file list. -# If left blank the directory from which doxygen is run is used as the -# path to strip. - -STRIP_FROM_PATH = - -# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of -# the path mentioned in the documentation of a class, which tells -# the reader which header file to include in order to use a class. -# If left blank only the name of the header file containing the class -# definition is used. Otherwise one should specify the include paths that -# are normally passed to the compiler using the -I flag. - -STRIP_FROM_INC_PATH = - -# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter -# (but less readable) file names. This can be useful if your file system -# doesn't support long names like on DOS, Mac, or CD-ROM. - -SHORT_NAMES = NO - -# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen -# will interpret the first line (until the first dot) of a JavaDoc-style -# comment as the brief description. If set to NO, the JavaDoc -# comments will behave just like regular Qt-style comments -# (thus requiring an explicit @brief command for a brief description.) - -JAVADOC_AUTOBRIEF = NO - -# If the QT_AUTOBRIEF tag is set to YES then Doxygen will -# interpret the first line (until the first dot) of a Qt-style -# comment as the brief description. If set to NO, the comments -# will behave just like regular Qt-style comments (thus requiring -# an explicit \brief command for a brief description.) - -QT_AUTOBRIEF = NO - -# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen -# treat a multi-line C++ special comment block (i.e. a block of //! or /// -# comments) as a brief description. This used to be the default behaviour. -# The new default is to treat a multi-line C++ comment block as a detailed -# description. Set this tag to YES if you prefer the old behaviour instead. - -MULTILINE_CPP_IS_BRIEF = NO - -# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented -# member inherits the documentation from any documented member that it -# re-implements. - -INHERIT_DOCS = YES - -# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce -# a new page for each member. If set to NO, the documentation of a member will -# be part of the file/class/namespace that contains it. - -SEPARATE_MEMBER_PAGES = NO - -# The TAB_SIZE tag can be used to set the number of spaces in a tab. -# Doxygen uses this value to replace tabs by spaces in code fragments. - -TAB_SIZE = 8 - -# This tag can be used to specify a number of aliases that acts -# as commands in the documentation. An alias has the form "name=value". -# For example adding "sideeffect=\par Side Effects:\n" will allow you to -# put the command \sideeffect (or @sideeffect) in the documentation, which -# will result in a user-defined paragraph with heading "Side Effects:". -# You can put \n's in the value part of an alias to insert newlines. - -ALIASES = - -# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C -# sources only. Doxygen will then generate output that is more tailored for C. -# For instance, some of the names that are used will be different. The list -# of all members will be omitted, etc. - -OPTIMIZE_OUTPUT_FOR_C = NO - -# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java -# sources only. Doxygen will then generate output that is more tailored for -# Java. For instance, namespaces will be presented as packages, qualified -# scopes will look different, etc. - -OPTIMIZE_OUTPUT_JAVA = NO - -# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran -# sources only. Doxygen will then generate output that is more tailored for -# Fortran. - -OPTIMIZE_FOR_FORTRAN = NO - -# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL -# sources. Doxygen will then generate output that is tailored for -# VHDL. - -OPTIMIZE_OUTPUT_VHDL = NO - -# Doxygen selects the parser to use depending on the extension of the files it -# parses. With this tag you can assign which parser to use for a given extension. -# Doxygen has a built-in mapping, but you can override or extend it using this -# tag. The format is ext=language, where ext is a file extension, and language -# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C, -# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make -# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C -# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions -# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. - -EXTENSION_MAPPING = - -# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want -# to include (a tag file for) the STL sources as input, then you should -# set this tag to YES in order to let doxygen match functions declarations and -# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. -# func(std::string) {}). This also makes the inheritance and collaboration -# diagrams that involve STL classes more complete and accurate. - -BUILTIN_STL_SUPPORT = NO - -# If you use Microsoft's C++/CLI language, you should set this option to YES to -# enable parsing support. - -CPP_CLI_SUPPORT = NO - -# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. -# Doxygen will parse them like normal C++ but will assume all classes use public -# instead of private inheritance when no explicit protection keyword is present. - -SIP_SUPPORT = NO - -# For Microsoft's IDL there are propget and propput attributes to indicate getter -# and setter methods for a property. Setting this option to YES (the default) -# will make doxygen replace the get and set methods by a property in the -# documentation. This will only work if the methods are indeed getting or -# setting a simple type. If this is not the case, or you want to show the -# methods anyway, you should set this option to NO. - -IDL_PROPERTY_SUPPORT = YES - -# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC -# tag is set to YES, then doxygen will reuse the documentation of the first -# member in the group (if any) for the other members of the group. By default -# all members of a group must be documented explicitly. - -DISTRIBUTE_GROUP_DOC = NO - -# Set the SUBGROUPING tag to YES (the default) to allow class member groups of -# the same type (for instance a group of public functions) to be put as a -# subgroup of that type (e.g. under the Public Functions section). Set it to -# NO to prevent subgrouping. Alternatively, this can be done per class using -# the \nosubgrouping command. - -SUBGROUPING = YES - -# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and -# unions are shown inside the group in which they are included (e.g. using -# @ingroup) instead of on a separate page (for HTML and Man pages) or -# section (for LaTeX and RTF). - -INLINE_GROUPED_CLASSES = NO - -# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum -# is documented as struct, union, or enum with the name of the typedef. So -# typedef struct TypeS {} TypeT, will appear in the documentation as a struct -# with name TypeT. When disabled the typedef will appear as a member of a file, -# namespace, or class. And the struct will be named TypeS. This can typically -# be useful for C code in case the coding convention dictates that all compound -# types are typedef'ed and only the typedef is referenced, never the tag name. - -TYPEDEF_HIDES_STRUCT = NO - -# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to -# determine which symbols to keep in memory and which to flush to disk. -# When the cache is full, less often used symbols will be written to disk. -# For small to medium size projects (<1000 input files) the default value is -# probably good enough. For larger projects a too small cache size can cause -# doxygen to be busy swapping symbols to and from disk most of the time -# causing a significant performance penalty. -# If the system has enough physical memory increasing the cache will improve the -# performance by keeping more symbols in memory. Note that the value works on -# a logarithmic scale so increasing the size by one will roughly double the -# memory usage. The cache size is given by this formula: -# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, -# corresponding to a cache size of 2^16 = 65536 symbols - -SYMBOL_CACHE_SIZE = 0 - -#--------------------------------------------------------------------------- -# Build related configuration options -#--------------------------------------------------------------------------- - -# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in -# documentation are documented, even if no documentation was available. -# Private class members and static file members will be hidden unless -# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES - -EXTRACT_ALL = NO - -# If the EXTRACT_PRIVATE tag is set to YES all private members of a class -# will be included in the documentation. - -EXTRACT_PRIVATE = NO - -# If the EXTRACT_STATIC tag is set to YES all static members of a file -# will be included in the documentation. - -EXTRACT_STATIC = YES - -# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) -# defined locally in source files will be included in the documentation. -# If set to NO only classes defined in header files are included. - -EXTRACT_LOCAL_CLASSES = YES - -# This flag is only useful for Objective-C code. When set to YES local -# methods, which are defined in the implementation section but not in -# the interface are included in the documentation. -# If set to NO (the default) only methods in the interface are included. - -EXTRACT_LOCAL_METHODS = NO - -# If this flag is set to YES, the members of anonymous namespaces will be -# extracted and appear in the documentation as a namespace called -# 'anonymous_namespace{file}', where file will be replaced with the base -# name of the file that contains the anonymous namespace. By default -# anonymous namespaces are hidden. - -EXTRACT_ANON_NSPACES = NO - -# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all -# undocumented members of documented classes, files or namespaces. -# If set to NO (the default) these members will be included in the -# various overviews, but no documentation section is generated. -# This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_MEMBERS = NO - -# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all -# undocumented classes that are normally visible in the class hierarchy. -# If set to NO (the default) these classes will be included in the various -# overviews. This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_CLASSES = NO - -# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all -# friend (class|struct|union) declarations. -# If set to NO (the default) these declarations will be included in the -# documentation. - -HIDE_FRIEND_COMPOUNDS = NO - -# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any -# documentation blocks found inside the body of a function. -# If set to NO (the default) these blocks will be appended to the -# function's detailed documentation block. - -HIDE_IN_BODY_DOCS = NO - -# The INTERNAL_DOCS tag determines if documentation -# that is typed after a \internal command is included. If the tag is set -# to NO (the default) then the documentation will be excluded. -# Set it to YES to include the internal documentation. - -INTERNAL_DOCS = NO - -# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate -# file names in lower-case letters. If set to YES upper-case letters are also -# allowed. This is useful if you have classes or files whose names only differ -# in case and if your file system supports case sensitive file names. Windows -# and Mac users are advised to set this option to NO. - -CASE_SENSE_NAMES = YES - -# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen -# will show members with their full class and namespace scopes in the -# documentation. If set to YES the scope will be hidden. - -HIDE_SCOPE_NAMES = NO - -# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen -# will put a list of the files that are included by a file in the documentation -# of that file. - -SHOW_INCLUDE_FILES = YES - -# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen -# will list include files with double quotes in the documentation -# rather than with sharp brackets. - -FORCE_LOCAL_INCLUDES = NO - -# If the INLINE_INFO tag is set to YES (the default) then a tag inline -# is inserted in the documentation for inline members. - -INLINE_INFO = YES - -# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen -# will sort the (detailed) documentation of file and class members -# alphabetically by member name. If set to NO the members will appear in -# declaration order. - -SORT_MEMBER_DOCS = YES - -# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the -# brief documentation of file, namespace and class members alphabetically -# by member name. If set to NO (the default) the members will appear in -# declaration order. - -SORT_BRIEF_DOCS = NO - -# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen -# will sort the (brief and detailed) documentation of class members so that -# constructors and destructors are listed first. If set to NO (the default) -# the constructors will appear in the respective orders defined by -# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. -# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO -# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. - -SORT_MEMBERS_CTORS_1ST = NO - -# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the -# hierarchy of group names into alphabetical order. If set to NO (the default) -# the group names will appear in their defined order. - -SORT_GROUP_NAMES = NO - -# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be -# sorted by fully-qualified names, including namespaces. If set to -# NO (the default), the class list will be sorted only by class name, -# not including the namespace part. -# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. -# Note: This option applies only to the class list, not to the -# alphabetical list. - -SORT_BY_SCOPE_NAME = NO - -# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to -# do proper type resolution of all parameters of a function it will reject a -# match between the prototype and the implementation of a member function even -# if there is only one candidate or it is obvious which candidate to choose -# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen -# will still accept a match between prototype and implementation in such cases. - -STRICT_PROTO_MATCHING = NO - -# The GENERATE_TODOLIST tag can be used to enable (YES) or -# disable (NO) the todo list. This list is created by putting \todo -# commands in the documentation. - -GENERATE_TODOLIST = YES - -# The GENERATE_TESTLIST tag can be used to enable (YES) or -# disable (NO) the test list. This list is created by putting \test -# commands in the documentation. - -GENERATE_TESTLIST = YES - -# The GENERATE_BUGLIST tag can be used to enable (YES) or -# disable (NO) the bug list. This list is created by putting \bug -# commands in the documentation. - -GENERATE_BUGLIST = YES - -# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or -# disable (NO) the deprecated list. This list is created by putting -# \deprecated commands in the documentation. - -GENERATE_DEPRECATEDLIST= YES - -# The ENABLED_SECTIONS tag can be used to enable conditional -# documentation sections, marked by \if sectionname ... \endif. - -ENABLED_SECTIONS = - -# The MAX_INITIALIZER_LINES tag determines the maximum number of lines -# the initial value of a variable or macro consists of for it to appear in -# the documentation. If the initializer consists of more lines than specified -# here it will be hidden. Use a value of 0 to hide initializers completely. -# The appearance of the initializer of individual variables and macros in the -# documentation can be controlled using \showinitializer or \hideinitializer -# command in the documentation regardless of this setting. - -MAX_INITIALIZER_LINES = 30 - -# Set the SHOW_USED_FILES tag to NO to disable the list of files generated -# at the bottom of the documentation of classes and structs. If set to YES the -# list will mention the files that were used to generate the documentation. - -SHOW_USED_FILES = YES - -# If the sources in your project are distributed over multiple directories -# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy -# in the documentation. The default is NO. - -SHOW_DIRECTORIES = YES - -# Set the SHOW_FILES tag to NO to disable the generation of the Files page. -# This will remove the Files entry from the Quick Index and from the -# Folder Tree View (if specified). The default is YES. - -SHOW_FILES = YES - -# Set the SHOW_NAMESPACES tag to NO to disable the generation of the -# Namespaces page. -# This will remove the Namespaces entry from the Quick Index -# and from the Folder Tree View (if specified). The default is YES. - -SHOW_NAMESPACES = YES - -# The FILE_VERSION_FILTER tag can be used to specify a program or script that -# doxygen should invoke to get the current version for each file (typically from -# the version control system). Doxygen will invoke the program by executing (via -# popen()) the command <command> <input-file>, where <command> is the value of -# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file -# provided by doxygen. Whatever the program writes to standard output -# is used as the file version. See the manual for examples. - -FILE_VERSION_FILTER = - -# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed -# by doxygen. The layout file controls the global structure of the generated -# output files in an output format independent way. The create the layout file -# that represents doxygen's defaults, run doxygen with the -l option. -# You can optionally specify a file name after the option, if omitted -# DoxygenLayout.xml will be used as the name of the layout file. - -LAYOUT_FILE = - -#--------------------------------------------------------------------------- -# configuration options related to warning and progress messages -#--------------------------------------------------------------------------- - -# The QUIET tag can be used to turn on/off the messages that are generated -# by doxygen. Possible values are YES and NO. If left blank NO is used. - -QUIET = NO - -# The WARNINGS tag can be used to turn on/off the warning messages that are -# generated by doxygen. Possible values are YES and NO. If left blank -# NO is used. - -WARNINGS = YES - -# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings -# for undocumented members. If EXTRACT_ALL is set to YES then this flag will -# automatically be disabled. - -WARN_IF_UNDOCUMENTED = YES - -# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for -# potential errors in the documentation, such as not documenting some -# parameters in a documented function, or documenting parameters that -# don't exist or using markup commands wrongly. - -WARN_IF_DOC_ERROR = YES - -# The WARN_NO_PARAMDOC option can be enabled to get warnings for -# functions that are documented, but have no documentation for their parameters -# or return value. If set to NO (the default) doxygen will only warn about -# wrong or incomplete parameter documentation, but not about the absence of -# documentation. - -WARN_NO_PARAMDOC = NO - -# The WARN_FORMAT tag determines the format of the warning messages that -# doxygen can produce. The string should contain the $file, $line, and $text -# tags, which will be replaced by the file and line number from which the -# warning originated and the warning text. Optionally the format may contain -# $version, which will be replaced by the version of the file (if it could -# be obtained via FILE_VERSION_FILTER) - -WARN_FORMAT = "$file:$line: $text" - -# The WARN_LOGFILE tag can be used to specify a file to which warning -# and error messages should be written. If left blank the output is written -# to stderr. - -WARN_LOGFILE = - -#--------------------------------------------------------------------------- -# configuration options related to the input files -#--------------------------------------------------------------------------- - -# The INPUT tag can be used to specify the files and/or directories that contain -# documented source files. You may enter file names like "myfile.cpp" or -# directories like "/usr/src/myproject". Separate the files or directories -# with spaces. - -INPUT = slowmoCLI slowmoUI lib project visualizeFlow docs/src - -# This tag can be used to specify the character encoding of the source files -# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is -# also the default input encoding. Doxygen uses libiconv (or the iconv built -# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for -# the list of possible encodings. - -INPUT_ENCODING = UTF-8 - -# If the value of the INPUT tag contains directories, you can use the -# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank the following patterns are tested: -# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh -# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py -# *.f90 *.f *.for *.vhd *.vhdl - -FILE_PATTERNS = - -# The RECURSIVE tag can be used to turn specify whether or not subdirectories -# should be searched for input files as well. Possible values are YES and NO. -# If left blank NO is used. - -RECURSIVE = YES - -# The EXCLUDE tag can be used to specify files and/or directories that should -# excluded from the INPUT source files. This way you can easily exclude a -# subdirectory from a directory tree whose root is specified with the INPUT tag. - -EXCLUDE = - -# The EXCLUDE_SYMLINKS tag can be used select whether or not files or -# directories that are symbolic links (a Unix file system feature) are excluded -# from the input. - -EXCLUDE_SYMLINKS = NO - -# If the value of the INPUT tag contains directories, you can use the -# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude -# certain files from those directories. Note that the wildcards are matched -# against the file with absolute path, so to exclude all test directories -# for example use the pattern */test/* - -EXCLUDE_PATTERNS = - -# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names -# (namespaces, classes, functions, etc.) that should be excluded from the -# output. The symbol name can be a fully qualified name, a word, or if the -# wildcard * is used, a substring. Examples: ANamespace, AClass, -# AClass::ANamespace, ANamespace::*Test - -EXCLUDE_SYMBOLS = - -# The EXAMPLE_PATH tag can be used to specify one or more files or -# directories that contain example code fragments that are included (see -# the \include command). - -EXAMPLE_PATH = - -# If the value of the EXAMPLE_PATH tag contains directories, you can use the -# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank all files are included. - -EXAMPLE_PATTERNS = - -# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be -# searched for input files to be used with the \include or \dontinclude -# commands irrespective of the value of the RECURSIVE tag. -# Possible values are YES and NO. If left blank NO is used. - -EXAMPLE_RECURSIVE = NO - -# The IMAGE_PATH tag can be used to specify one or more files or -# directories that contain image that are included in the documentation (see -# the \image command). - -IMAGE_PATH = - -# The INPUT_FILTER tag can be used to specify a program that doxygen should -# invoke to filter for each input file. Doxygen will invoke the filter program -# by executing (via popen()) the command <filter> <input-file>, where <filter> -# is the value of the INPUT_FILTER tag, and <input-file> is the name of an -# input file. Doxygen will then use the output that the filter program writes -# to standard output. -# If FILTER_PATTERNS is specified, this tag will be -# ignored. - -INPUT_FILTER = - -# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern -# basis. -# Doxygen will compare the file name with each pattern and apply the -# filter if there is a match. -# The filters are a list of the form: -# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further -# info on how filters are used. If FILTER_PATTERNS is empty or if -# non of the patterns match the file name, INPUT_FILTER is applied. - -FILTER_PATTERNS = - -# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using -# INPUT_FILTER) will be used to filter the input files when producing source -# files to browse (i.e. when SOURCE_BROWSER is set to YES). - -FILTER_SOURCE_FILES = NO - -# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file -# pattern. A pattern will override the setting for FILTER_PATTERN (if any) -# and it is also possible to disable source filtering for a specific pattern -# using *.ext= (so without naming a filter). This option only has effect when -# FILTER_SOURCE_FILES is enabled. - -FILTER_SOURCE_PATTERNS = - -#--------------------------------------------------------------------------- -# configuration options related to source browsing -#--------------------------------------------------------------------------- - -# If the SOURCE_BROWSER tag is set to YES then a list of source files will -# be generated. Documented entities will be cross-referenced with these sources. -# Note: To get rid of all source code in the generated output, make sure also -# VERBATIM_HEADERS is set to NO. - -SOURCE_BROWSER = YES - -# Setting the INLINE_SOURCES tag to YES will include the body -# of functions and classes directly in the documentation. - -INLINE_SOURCES = NO - -# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct -# doxygen to hide any special comment blocks from generated source code -# fragments. Normal C and C++ comments will always remain visible. - -STRIP_CODE_COMMENTS = YES - -# If the REFERENCED_BY_RELATION tag is set to YES -# then for each documented function all documented -# functions referencing it will be listed. - -REFERENCED_BY_RELATION = NO - -# If the REFERENCES_RELATION tag is set to YES -# then for each documented function all documented entities -# called/used by that function will be listed. - -REFERENCES_RELATION = NO - -# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) -# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from -# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will -# link to the source code. -# Otherwise they will link to the documentation. - -REFERENCES_LINK_SOURCE = YES - -# If the USE_HTAGS tag is set to YES then the references to source code -# will point to the HTML generated by the htags(1) tool instead of doxygen -# built-in source browser. The htags tool is part of GNU's global source -# tagging system (see http://www.gnu.org/software/global/global.html). You -# will need version 4.8.6 or higher. - -USE_HTAGS = NO - -# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen -# will generate a verbatim copy of the header file for each class for -# which an include is specified. Set to NO to disable this. - -VERBATIM_HEADERS = YES - -#--------------------------------------------------------------------------- -# configuration options related to the alphabetical class index -#--------------------------------------------------------------------------- - -# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index -# of all compounds will be generated. Enable this if the project -# contains a lot of classes, structs, unions or interfaces. - -ALPHABETICAL_INDEX = YES - -# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then -# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns -# in which this list will be split (can be a number in the range 1..20) - -COLS_IN_ALPHA_INDEX = 5 - -# In case all classes in a project start with a common prefix, all -# classes will be put under the same header in the alphabetical index. -# The IGNORE_PREFIX tag can be used to specify one or more prefixes that -# should be ignored while generating the index headers. - -IGNORE_PREFIX = - -#--------------------------------------------------------------------------- -# configuration options related to the HTML output -#--------------------------------------------------------------------------- - -# If the GENERATE_HTML tag is set to YES (the default) Doxygen will -# generate HTML output. - -GENERATE_HTML = YES - -# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `html' will be used as the default path. - -HTML_OUTPUT = html - -# The HTML_FILE_EXTENSION tag can be used to specify the file extension for -# each generated HTML page (for example: .htm,.php,.asp). If it is left blank -# doxygen will generate files with .html extension. - -HTML_FILE_EXTENSION = .html - -# The HTML_HEADER tag can be used to specify a personal HTML header for -# each generated HTML page. If it is left blank doxygen will generate a -# standard header. Note that when using a custom header you are responsible -# for the proper inclusion of any scripts and style sheets that doxygen -# needs, which is dependent on the configuration options used. -# It is adviced to generate a default header using "doxygen -w html -# header.html footer.html stylesheet.css YourConfigFile" and then modify -# that header. Note that the header is subject to change so you typically -# have to redo this when upgrading to a newer version of doxygen or when changing the value of configuration settings such as GENERATE_TREEVIEW! - -HTML_HEADER = - -# The HTML_FOOTER tag can be used to specify a personal HTML footer for -# each generated HTML page. If it is left blank doxygen will generate a -# standard footer. - -HTML_FOOTER = - -# The HTML_STYLESHEET tag can be used to specify a user-defined cascading -# style sheet that is used by each HTML page. It can be used to -# fine-tune the look of the HTML output. If the tag is left blank doxygen -# will generate a default style sheet. Note that doxygen will try to copy -# the style sheet file to the HTML output directory, so don't put your own -# stylesheet in the HTML output directory as well, or it will be erased! - -HTML_STYLESHEET = docs/src/doxygen.css - -# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or -# other source files which should be copied to the HTML output directory. Note -# that these files will be copied to the base HTML output directory. Use the -# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these -# files. In the HTML_STYLESHEET file, use the file name only. Also note that -# the files will be copied as-is; there are no commands or markers available. - -HTML_EXTRA_FILES = - -# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. -# Doxygen will adjust the colors in the stylesheet and background images -# according to this color. Hue is specified as an angle on a colorwheel, -# see http://en.wikipedia.org/wiki/Hue for more information. -# For instance the value 0 represents red, 60 is yellow, 120 is green, -# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. -# The allowed range is 0 to 359. - -HTML_COLORSTYLE_HUE = 220 - -# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of -# the colors in the HTML output. For a value of 0 the output will use -# grayscales only. A value of 255 will produce the most vivid colors. - -HTML_COLORSTYLE_SAT = 100 - -# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to -# the luminance component of the colors in the HTML output. Values below -# 100 gradually make the output lighter, whereas values above 100 make -# the output darker. The value divided by 100 is the actual gamma applied, -# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, -# and 100 does not change the gamma. - -HTML_COLORSTYLE_GAMMA = 80 - -# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML -# page will contain the date and time when the page was generated. Setting -# this to NO can help when comparing the output of multiple runs. - -HTML_TIMESTAMP = YES - -# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, -# files or namespaces will be aligned in HTML using tables. If set to -# NO a bullet list will be used. - -HTML_ALIGN_MEMBERS = YES - -# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML -# documentation will contain sections that can be hidden and shown after the -# page has loaded. For this to work a browser that supports -# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox -# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). - -HTML_DYNAMIC_SECTIONS = NO - -# If the GENERATE_DOCSET tag is set to YES, additional index files -# will be generated that can be used as input for Apple's Xcode 3 -# integrated development environment, introduced with OSX 10.5 (Leopard). -# To create a documentation set, doxygen will generate a Makefile in the -# HTML output directory. Running make will produce the docset in that -# directory and running "make install" will install the docset in -# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find -# it at startup. -# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html -# for more information. - -GENERATE_DOCSET = NO - -# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the -# feed. A documentation feed provides an umbrella under which multiple -# documentation sets from a single provider (such as a company or product suite) -# can be grouped. - -DOCSET_FEEDNAME = "Doxygen generated docs" - -# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that -# should uniquely identify the documentation set bundle. This should be a -# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen -# will append .docset to the name. - -DOCSET_BUNDLE_ID = org.doxygen.Project - -# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify -# the documentation publisher. This should be a reverse domain-name style -# string, e.g. com.mycompany.MyDocSet.documentation. - -DOCSET_PUBLISHER_ID = org.doxygen.Publisher - -# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. - -DOCSET_PUBLISHER_NAME = Publisher - -# If the GENERATE_HTMLHELP tag is set to YES, additional index files -# will be generated that can be used as input for tools like the -# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) -# of the generated HTML documentation. - -GENERATE_HTMLHELP = NO - -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can -# be used to specify the file name of the resulting .chm file. You -# can add a path in front of the file if the result should not be -# written to the html output directory. - -CHM_FILE = - -# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can -# be used to specify the location (absolute path including file name) of -# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run -# the HTML help compiler on the generated index.hhp. - -HHC_LOCATION = - -# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag -# controls if a separate .chi index file is generated (YES) or that -# it should be included in the master .chm file (NO). - -GENERATE_CHI = NO - -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING -# is used to encode HtmlHelp index (hhk), content (hhc) and project file -# content. - -CHM_INDEX_ENCODING = - -# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag -# controls whether a binary table of contents is generated (YES) or a -# normal table of contents (NO) in the .chm file. - -BINARY_TOC = NO - -# The TOC_EXPAND flag can be set to YES to add extra items for group members -# to the contents of the HTML help documentation and to the tree view. - -TOC_EXPAND = NO - -# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and -# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated -# that can be used as input for Qt's qhelpgenerator to generate a -# Qt Compressed Help (.qch) of the generated HTML documentation. - -GENERATE_QHP = NO - -# If the QHG_LOCATION tag is specified, the QCH_FILE tag can -# be used to specify the file name of the resulting .qch file. -# The path specified is relative to the HTML output folder. - -QCH_FILE = - -# The QHP_NAMESPACE tag specifies the namespace to use when generating -# Qt Help Project output. For more information please see -# http://doc.trolltech.com/qthelpproject.html#namespace - -QHP_NAMESPACE = org.doxygen.Project - -# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating -# Qt Help Project output. For more information please see -# http://doc.trolltech.com/qthelpproject.html#virtual-folders - -QHP_VIRTUAL_FOLDER = doc - -# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to -# add. For more information please see -# http://doc.trolltech.com/qthelpproject.html#custom-filters - -QHP_CUST_FILTER_NAME = - -# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the -# custom filter to add. For more information please see -# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters"> -# Qt Help Project / Custom Filters</a>. - -QHP_CUST_FILTER_ATTRS = - -# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this -# project's -# filter section matches. -# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes"> -# Qt Help Project / Filter Attributes</a>. - -QHP_SECT_FILTER_ATTRS = - -# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can -# be used to specify the location of Qt's qhelpgenerator. -# If non-empty doxygen will try to run qhelpgenerator on the generated -# .qhp file. - -QHG_LOCATION = - -# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files -# will be generated, which together with the HTML files, form an Eclipse help -# plugin. To install this plugin and make it available under the help contents -# menu in Eclipse, the contents of the directory containing the HTML and XML -# files needs to be copied into the plugins directory of eclipse. The name of -# the directory within the plugins directory should be the same as -# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before -# the help appears. - -GENERATE_ECLIPSEHELP = NO - -# A unique identifier for the eclipse help plugin. When installing the plugin -# the directory name containing the HTML and XML files should also have -# this name. - -ECLIPSE_DOC_ID = org.doxygen.Project - -# The DISABLE_INDEX tag can be used to turn on/off the condensed index at -# top of each HTML page. The value NO (the default) enables the index and -# the value YES disables it. - -DISABLE_INDEX = NO - -# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values -# (range 0,1..20) that doxygen will group on one line in the generated HTML -# documentation. Note that a value of 0 will completely suppress the enum -# values from appearing in the overview section. - -ENUM_VALUES_PER_LINE = 4 - -# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index -# structure should be generated to display hierarchical information. -# If the tag value is set to YES, a side panel will be generated -# containing a tree-like index structure (just like the one that -# is generated for HTML Help). For this to work a browser that supports -# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). -# Windows users are probably better off using the HTML help feature. - -GENERATE_TREEVIEW = NO - -# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, -# and Class Hierarchy pages using a tree view instead of an ordered list. - -USE_INLINE_TREES = NO - -# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be -# used to set the initial width (in pixels) of the frame in which the tree -# is shown. - -TREEVIEW_WIDTH = 250 - -# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open -# links to external symbols imported via tag files in a separate window. - -EXT_LINKS_IN_WINDOW = NO - -# Use this tag to change the font size of Latex formulas included -# as images in the HTML documentation. The default is 10. Note that -# when you change the font size after a successful doxygen run you need -# to manually remove any form_*.png images from the HTML output directory -# to force them to be regenerated. - -FORMULA_FONTSIZE = 10 - -# Use the FORMULA_TRANPARENT tag to determine whether or not the images -# generated for formulas are transparent PNGs. Transparent PNGs are -# not supported properly for IE 6.0, but are supported on all modern browsers. -# Note that when changing this option you need to delete any form_*.png files -# in the HTML output before the changes have effect. - -FORMULA_TRANSPARENT = YES - -# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax -# (see http://www.mathjax.org) which uses client side Javascript for the -# rendering instead of using prerendered bitmaps. Use this if you do not -# have LaTeX installed or if you want to formulas look prettier in the HTML -# output. When enabled you also need to install MathJax separately and -# configure the path to it using the MATHJAX_RELPATH option. - -USE_MATHJAX = NO - -# When MathJax is enabled you need to specify the location relative to the -# HTML output directory using the MATHJAX_RELPATH option. The destination -# directory should contain the MathJax.js script. For instance, if the mathjax -# directory is located at the same level as the HTML output directory, then -# MATHJAX_RELPATH should be ../mathjax. The default value points to the -# mathjax.org site, so you can quickly see the result without installing -# MathJax, but it is strongly recommended to install a local copy of MathJax -# before deployment. - -MATHJAX_RELPATH = http://www.mathjax.org/mathjax - -# When the SEARCHENGINE tag is enabled doxygen will generate a search box -# for the HTML output. The underlying search engine uses javascript -# and DHTML and should work on any modern browser. Note that when using -# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets -# (GENERATE_DOCSET) there is already a search function so this one should -# typically be disabled. For large projects the javascript based search engine -# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. - -SEARCHENGINE = YES - -# When the SERVER_BASED_SEARCH tag is enabled the search engine will be -# implemented using a PHP enabled web server instead of at the web client -# using Javascript. Doxygen will generate the search PHP script and index -# file to put on the web server. The advantage of the server -# based approach is that it scales better to large projects and allows -# full text search. The disadvantages are that it is more difficult to setup -# and does not have live searching capabilities. - -SERVER_BASED_SEARCH = NO - -#--------------------------------------------------------------------------- -# configuration options related to the LaTeX output -#--------------------------------------------------------------------------- - -# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will -# generate Latex output. - -GENERATE_LATEX = YES - -# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `latex' will be used as the default path. - -LATEX_OUTPUT = latex - -# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be -# invoked. If left blank `latex' will be used as the default command name. -# Note that when enabling USE_PDFLATEX this option is only used for -# generating bitmaps for formulas in the HTML output, but not in the -# Makefile that is written to the output directory. - -LATEX_CMD_NAME = latex - -# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to -# generate index for LaTeX. If left blank `makeindex' will be used as the -# default command name. - -MAKEINDEX_CMD_NAME = makeindex - -# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact -# LaTeX documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_LATEX = NO - -# The PAPER_TYPE tag can be used to set the paper type that is used -# by the printer. Possible values are: a4, letter, legal and -# executive. If left blank a4wide will be used. - -PAPER_TYPE = a4 - -# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX -# packages that should be included in the LaTeX output. - -EXTRA_PACKAGES = - -# The LATEX_HEADER tag can be used to specify a personal LaTeX header for -# the generated latex document. The header should contain everything until -# the first chapter. If it is left blank doxygen will generate a -# standard header. Notice: only use this tag if you know what you are doing! - -LATEX_HEADER = - -# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for -# the generated latex document. The footer should contain everything after -# the last chapter. If it is left blank doxygen will generate a -# standard footer. Notice: only use this tag if you know what you are doing! - -LATEX_FOOTER = - -# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated -# is prepared for conversion to pdf (using ps2pdf). The pdf file will -# contain links (just like the HTML output) instead of page references -# This makes the output suitable for online browsing using a pdf viewer. - -PDF_HYPERLINKS = YES - -# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of -# plain latex in the generated Makefile. Set this option to YES to get a -# higher quality PDF documentation. - -USE_PDFLATEX = YES - -# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. -# command to the generated LaTeX files. This will instruct LaTeX to keep -# running if errors occur, instead of asking the user for help. -# This option is also used when generating formulas in HTML. - -LATEX_BATCHMODE = NO - -# If LATEX_HIDE_INDICES is set to YES then doxygen will not -# include the index chapters (such as File Index, Compound Index, etc.) -# in the output. - -LATEX_HIDE_INDICES = NO - -# If LATEX_SOURCE_CODE is set to YES then doxygen will include -# source code with syntax highlighting in the LaTeX output. -# Note that which sources are shown also depends on other settings -# such as SOURCE_BROWSER. - -LATEX_SOURCE_CODE = NO - -#--------------------------------------------------------------------------- -# configuration options related to the RTF output -#--------------------------------------------------------------------------- - -# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output -# The RTF output is optimized for Word 97 and may not look very pretty with -# other RTF readers or editors. - -GENERATE_RTF = NO - -# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `rtf' will be used as the default path. - -RTF_OUTPUT = rtf - -# If the COMPACT_RTF tag is set to YES Doxygen generates more compact -# RTF documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_RTF = NO - -# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated -# will contain hyperlink fields. The RTF file will -# contain links (just like the HTML output) instead of page references. -# This makes the output suitable for online browsing using WORD or other -# programs which support those fields. -# Note: wordpad (write) and others do not support links. - -RTF_HYPERLINKS = NO - -# Load stylesheet definitions from file. Syntax is similar to doxygen's -# config file, i.e. a series of assignments. You only have to provide -# replacements, missing definitions are set to their default value. - -RTF_STYLESHEET_FILE = - -# Set optional variables used in the generation of an rtf document. -# Syntax is similar to doxygen's config file. - -RTF_EXTENSIONS_FILE = - -#--------------------------------------------------------------------------- -# configuration options related to the man page output -#--------------------------------------------------------------------------- - -# If the GENERATE_MAN tag is set to YES (the default) Doxygen will -# generate man pages - -GENERATE_MAN = NO - -# The MAN_OUTPUT tag is used to specify where the man pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `man' will be used as the default path. - -MAN_OUTPUT = man - -# The MAN_EXTENSION tag determines the extension that is added to -# the generated man pages (default is the subroutine's section .3) - -MAN_EXTENSION = .3 - -# If the MAN_LINKS tag is set to YES and Doxygen generates man output, -# then it will generate one additional man file for each entity -# documented in the real man page(s). These additional files -# only source the real man page, but without them the man command -# would be unable to find the correct page. The default is NO. - -MAN_LINKS = NO - -#--------------------------------------------------------------------------- -# configuration options related to the XML output -#--------------------------------------------------------------------------- - -# If the GENERATE_XML tag is set to YES Doxygen will -# generate an XML file that captures the structure of -# the code including all documentation. - -GENERATE_XML = NO - -# The XML_OUTPUT tag is used to specify where the XML pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `xml' will be used as the default path. - -XML_OUTPUT = xml - -# The XML_SCHEMA tag can be used to specify an XML schema, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_SCHEMA = - -# The XML_DTD tag can be used to specify an XML DTD, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_DTD = - -# If the XML_PROGRAMLISTING tag is set to YES Doxygen will -# dump the program listings (including syntax highlighting -# and cross-referencing information) to the XML output. Note that -# enabling this will significantly increase the size of the XML output. - -XML_PROGRAMLISTING = YES - -#--------------------------------------------------------------------------- -# configuration options for the AutoGen Definitions output -#--------------------------------------------------------------------------- - -# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will -# generate an AutoGen Definitions (see autogen.sf.net) file -# that captures the structure of the code including all -# documentation. Note that this feature is still experimental -# and incomplete at the moment. - -GENERATE_AUTOGEN_DEF = NO - -#--------------------------------------------------------------------------- -# configuration options related to the Perl module output -#--------------------------------------------------------------------------- - -# If the GENERATE_PERLMOD tag is set to YES Doxygen will -# generate a Perl module file that captures the structure of -# the code including all documentation. Note that this -# feature is still experimental and incomplete at the -# moment. - -GENERATE_PERLMOD = NO - -# If the PERLMOD_LATEX tag is set to YES Doxygen will generate -# the necessary Makefile rules, Perl scripts and LaTeX code to be able -# to generate PDF and DVI output from the Perl module output. - -PERLMOD_LATEX = NO - -# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be -# nicely formatted so it can be parsed by a human reader. -# This is useful -# if you want to understand what is going on. -# On the other hand, if this -# tag is set to NO the size of the Perl module output will be much smaller -# and Perl will parse it just the same. - -PERLMOD_PRETTY = YES - -# The names of the make variables in the generated doxyrules.make file -# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. -# This is useful so different doxyrules.make files included by the same -# Makefile don't overwrite each other's variables. - -PERLMOD_MAKEVAR_PREFIX = - -#--------------------------------------------------------------------------- -# Configuration options related to the preprocessor -#--------------------------------------------------------------------------- - -# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will -# evaluate all C-preprocessor directives found in the sources and include -# files. - -ENABLE_PREPROCESSING = YES - -# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro -# names in the source code. If set to NO (the default) only conditional -# compilation will be performed. Macro expansion can be done in a controlled -# way by setting EXPAND_ONLY_PREDEF to YES. - -MACRO_EXPANSION = NO - -# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES -# then the macro expansion is limited to the macros specified with the -# PREDEFINED and EXPAND_AS_DEFINED tags. - -EXPAND_ONLY_PREDEF = NO - -# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files -# pointed to by INCLUDE_PATH will be searched when a #include is found. - -SEARCH_INCLUDES = YES - -# The INCLUDE_PATH tag can be used to specify one or more directories that -# contain include files that are not input files but should be processed by -# the preprocessor. - -INCLUDE_PATH = - -# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard -# patterns (like *.h and *.hpp) to filter out the header-files in the -# directories. If left blank, the patterns specified with FILE_PATTERNS will -# be used. - -INCLUDE_FILE_PATTERNS = - -# The PREDEFINED tag can be used to specify one or more macro names that -# are defined before the preprocessor is started (similar to the -D option of -# gcc). The argument of the tag is a list of macros of the form: name -# or name=definition (no spaces). If the definition and the = are -# omitted =1 is assumed. To prevent a macro definition from being -# undefined via #undef or recursively expanded use the := operator -# instead of the = operator. - -PREDEFINED = - -# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then -# this tag can be used to specify a list of macro names that should be expanded. -# The macro definition that is found in the sources will be used. -# Use the PREDEFINED tag if you want to use a different macro definition that -# overrules the definition found in the source code. - -EXPAND_AS_DEFINED = - -# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then -# doxygen's preprocessor will remove all references to function-like macros -# that are alone on a line, have an all uppercase name, and do not end with a -# semicolon, because these will confuse the parser if not removed. - -SKIP_FUNCTION_MACROS = YES - -#--------------------------------------------------------------------------- -# Configuration::additions related to external references -#--------------------------------------------------------------------------- - -# The TAGFILES option can be used to specify one or more tagfiles. -# Optionally an initial location of the external documentation -# can be added for each tagfile. The format of a tag file without -# this location is as follows: -# -# TAGFILES = file1 file2 ... -# Adding location for the tag files is done as follows: -# -# TAGFILES = file1=loc1 "file2 = loc2" ... -# where "loc1" and "loc2" can be relative or absolute paths or -# URLs. If a location is present for each tag, the installdox tool -# does not have to be run to correct the links. -# Note that each tag file must have a unique name -# (where the name does NOT include the path) -# If a tag file is not located in the directory in which doxygen -# is run, you must also specify the path to the tagfile here. - -TAGFILES = - -# When a file name is specified after GENERATE_TAGFILE, doxygen will create -# a tag file that is based on the input files it reads. - -GENERATE_TAGFILE = - -# If the ALLEXTERNALS tag is set to YES all external classes will be listed -# in the class index. If set to NO only the inherited external classes -# will be listed. - -ALLEXTERNALS = NO - -# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed -# in the modules index. If set to NO, only the current project's groups will -# be listed. - -EXTERNAL_GROUPS = YES - -# The PERL_PATH should be the absolute path and name of the perl script -# interpreter (i.e. the result of `which perl'). - -PERL_PATH = /usr/bin/perl - -#--------------------------------------------------------------------------- -# Configuration options related to the dot tool -#--------------------------------------------------------------------------- - -# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will -# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base -# or super classes. Setting the tag to NO turns the diagrams off. Note that -# this option also works with HAVE_DOT disabled, but it is recommended to -# install and use dot, since it yields more powerful graphs. - -CLASS_DIAGRAMS = YES - -# You can define message sequence charts within doxygen comments using the \msc -# command. Doxygen will then run the mscgen tool (see -# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the -# documentation. The MSCGEN_PATH tag allows you to specify the directory where -# the mscgen tool resides. If left empty the tool is assumed to be found in the -# default search path. - -MSCGEN_PATH = - -# If set to YES, the inheritance and collaboration graphs will hide -# inheritance and usage relations if the target is undocumented -# or is not a class. - -HIDE_UNDOC_RELATIONS = YES - -# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is -# available from the path. This tool is part of Graphviz, a graph visualization -# toolkit from AT&T and Lucent Bell Labs. The other options in this section -# have no effect if this option is set to NO (the default) - -HAVE_DOT = NO - -# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is -# allowed to run in parallel. When set to 0 (the default) doxygen will -# base this on the number of processors available in the system. You can set it -# explicitly to a value larger than 0 to get control over the balance -# between CPU load and processing speed. - -DOT_NUM_THREADS = 0 - -# By default doxygen will write a font called Helvetica to the output -# directory and reference it in all dot files that doxygen generates. -# When you want a differently looking font you can specify the font name -# using DOT_FONTNAME. You need to make sure dot is able to find the font, -# which can be done by putting it in a standard location or by setting the -# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory -# containing the font. - -DOT_FONTNAME = Helvetica - -# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. -# The default size is 10pt. - -DOT_FONTSIZE = 10 - -# By default doxygen will tell dot to use the output directory to look for the -# FreeSans.ttf font (which doxygen will put there itself). If you specify a -# different font using DOT_FONTNAME you can set the path where dot -# can find it using this tag. - -DOT_FONTPATH = - -# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect inheritance relations. Setting this tag to YES will force the -# the CLASS_DIAGRAMS tag to NO. - -CLASS_GRAPH = YES - -# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect implementation dependencies (inheritance, containment, and -# class references variables) of the class with other documented classes. - -COLLABORATION_GRAPH = YES - -# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for groups, showing the direct groups dependencies - -GROUP_GRAPHS = YES - -# If the UML_LOOK tag is set to YES doxygen will generate inheritance and -# collaboration diagrams in a style similar to the OMG's Unified Modeling -# Language. - -UML_LOOK = NO - -# If set to YES, the inheritance and collaboration graphs will show the -# relations between templates and their instances. - -TEMPLATE_RELATIONS = NO - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT -# tags are set to YES then doxygen will generate a graph for each documented -# file showing the direct and indirect include dependencies of the file with -# other documented files. - -INCLUDE_GRAPH = YES - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and -# HAVE_DOT tags are set to YES then doxygen will generate a graph for each -# documented header file showing the documented files that directly or -# indirectly include this file. - -INCLUDED_BY_GRAPH = YES - -# If the CALL_GRAPH and HAVE_DOT options are set to YES then -# doxygen will generate a call dependency graph for every global function -# or class method. Note that enabling this option will significantly increase -# the time of a run. So in most cases it will be better to enable call graphs -# for selected functions only using the \callgraph command. - -CALL_GRAPH = NO - -# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then -# doxygen will generate a caller dependency graph for every global function -# or class method. Note that enabling this option will significantly increase -# the time of a run. So in most cases it will be better to enable caller -# graphs for selected functions only using the \callergraph command. - -CALLER_GRAPH = NO - -# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen -# will generate a graphical hierarchy of all classes instead of a textual one. - -GRAPHICAL_HIERARCHY = YES - -# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES -# then doxygen will show the dependencies a directory has on other directories -# in a graphical way. The dependency relations are determined by the #include -# relations between the files in the directories. - -DIRECTORY_GRAPH = YES - -# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images -# generated by dot. Possible values are svg, png, jpg, or gif. -# If left blank png will be used. - -DOT_IMAGE_FORMAT = png - -# The tag DOT_PATH can be used to specify the path where the dot tool can be -# found. If left blank, it is assumed the dot tool can be found in the path. - -DOT_PATH = - -# The DOTFILE_DIRS tag can be used to specify one or more directories that -# contain dot files that are included in the documentation (see the -# \dotfile command). - -DOTFILE_DIRS = - -# The MSCFILE_DIRS tag can be used to specify one or more directories that -# contain msc files that are included in the documentation (see the -# \mscfile command). - -MSCFILE_DIRS = - -# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of -# nodes that will be shown in the graph. If the number of nodes in a graph -# becomes larger than this value, doxygen will truncate the graph, which is -# visualized by representing a node as a red box. Note that doxygen if the -# number of direct children of the root node in a graph is already larger than -# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note -# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. - -DOT_GRAPH_MAX_NODES = 50 - -# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the -# graphs generated by dot. A depth value of 3 means that only nodes reachable -# from the root by following a path via at most 3 edges will be shown. Nodes -# that lay further from the root node will be omitted. Note that setting this -# option to 1 or 2 may greatly reduce the computation time needed for large -# code bases. Also note that the size of a graph can be further restricted by -# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. - -MAX_DOT_GRAPH_DEPTH = 0 - -# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent -# background. This is disabled by default, because dot on Windows does not -# seem to support this out of the box. Warning: Depending on the platform used, -# enabling this option may lead to badly anti-aliased labels on the edges of -# a graph (i.e. they become hard to read). - -DOT_TRANSPARENT = NO - -# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output -# files in one run (i.e. multiple -o and -T options on the command line). This -# makes dot run faster, but since only newer versions of dot (>1.8.10) -# support this, this feature is disabled by default. - -DOT_MULTI_TARGETS = YES - -# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will -# generate a legend page explaining the meaning of the various boxes and -# arrows in the dot generated graphs. - -GENERATE_LEGEND = YES - -# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will -# remove the intermediate dot files that are used to generate -# the various graphs. - -DOT_CLEANUP = YES
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/Makefile
Deleted
@@ -1,416 +0,0 @@ -# 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 - -# The top-level source directory on which CMake was run. -CMAKE_SOURCE_DIR = /home/mso/src/slowmoVideo/slowmoVideo - -# The top-level build directory on which CMake was run. -CMAKE_BINARY_DIR = /home/mso/src/slowmoVideo/slowmoVideo - -#============================================================================= -# 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\"" -.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/mso/src/slowmoVideo/slowmoVideo/CMakeFiles /home/mso/src/slowmoVideo/slowmoVideo/CMakeFiles/progress.marks - $(MAKE) -f CMakeFiles/Makefile2 all - $(CMAKE_COMMAND) -E cmake_progress_start /home/mso/src/slowmoVideo/slowmoVideo/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 sV - -# Build rule for target. -sV: cmake_check_build_system - $(MAKE) -f CMakeFiles/Makefile2 sV -.PHONY : sV - -# fast build rule for target. -sV/fast: - $(MAKE) -f lib/CMakeFiles/sV.dir/build.make lib/CMakeFiles/sV.dir/build -.PHONY : sV/fast - -#============================================================================= -# Target rules for targets named sVencode - -# Build rule for target. -sVencode: cmake_check_build_system - $(MAKE) -f CMakeFiles/Makefile2 sVencode -.PHONY : sVencode - -# fast build rule for target. -sVencode/fast: - $(MAKE) -f lib/CMakeFiles/sVencode.dir/build.make lib/CMakeFiles/sVencode.dir/build -.PHONY : sVencode/fast - -#============================================================================= -# Target rules for targets named sVflow - -# Build rule for target. -sVflow: cmake_check_build_system - $(MAKE) -f CMakeFiles/Makefile2 sVflow -.PHONY : sVflow - -# fast build rule for target. -sVflow/fast: - $(MAKE) -f lib/CMakeFiles/sVflow.dir/build.make lib/CMakeFiles/sVflow.dir/build -.PHONY : sVflow/fast - -#============================================================================= -# Target rules for targets named sVinfo - -# Build rule for target. -sVinfo: cmake_check_build_system - $(MAKE) -f CMakeFiles/Makefile2 sVinfo -.PHONY : sVinfo - -# fast build rule for target. -sVinfo/fast: - $(MAKE) -f lib/CMakeFiles/sVinfo.dir/build.make lib/CMakeFiles/sVinfo.dir/build -.PHONY : sVinfo/fast - -#============================================================================= -# Target rules for targets named sVvis - -# Build rule for target. -sVvis: cmake_check_build_system - $(MAKE) -f CMakeFiles/Makefile2 sVvis -.PHONY : sVvis - -# fast build rule for target. -sVvis/fast: - $(MAKE) -f lib/CMakeFiles/sVvis.dir/build.make lib/CMakeFiles/sVvis.dir/build -.PHONY : sVvis/fast - -#============================================================================= -# Target rules for targets named sVgui - -# Build rule for target. -sVgui: cmake_check_build_system - $(MAKE) -f CMakeFiles/Makefile2 sVgui -.PHONY : sVgui - -# fast build rule for target. -sVgui/fast: - $(MAKE) -f libgui/CMakeFiles/sVgui.dir/build.make libgui/CMakeFiles/sVgui.dir/build -.PHONY : sVgui/fast - -#============================================================================= -# Target rules for targets named sVproj - -# Build rule for target. -sVproj: cmake_check_build_system - $(MAKE) -f CMakeFiles/Makefile2 sVproj -.PHONY : sVproj - -# fast build rule for target. -sVproj/fast: - $(MAKE) -f project/CMakeFiles/sVproj.dir/build.make project/CMakeFiles/sVproj.dir/build -.PHONY : sVproj/fast - -#============================================================================= -# Target rules for targets named slowmoInterpolate - -# Build rule for target. -slowmoInterpolate: cmake_check_build_system - $(MAKE) -f CMakeFiles/Makefile2 slowmoInterpolate -.PHONY : slowmoInterpolate - -# fast build rule for target. -slowmoInterpolate/fast: - $(MAKE) -f slowmoCLI/CMakeFiles/slowmoInterpolate.dir/build.make slowmoCLI/CMakeFiles/slowmoInterpolate.dir/build -.PHONY : slowmoInterpolate/fast - -#============================================================================= -# Target rules for targets named videoInfo - -# Build rule for target. -videoInfo: cmake_check_build_system - $(MAKE) -f CMakeFiles/Makefile2 videoInfo -.PHONY : videoInfo - -# fast build rule for target. -videoInfo/fast: - $(MAKE) -f slowmoCLI/CMakeFiles/videoInfo.dir/build.make slowmoCLI/CMakeFiles/videoInfo.dir/build -.PHONY : videoInfo/fast - -#============================================================================= -# Target rules for targets named slowmoUI - -# Build rule for target. -slowmoUI: cmake_check_build_system - $(MAKE) -f CMakeFiles/Makefile2 slowmoUI -.PHONY : slowmoUI - -# fast build rule for target. -slowmoUI/fast: - $(MAKE) -f slowmoUI/CMakeFiles/slowmoUI.dir/build.make slowmoUI/CMakeFiles/slowmoUI.dir/build -.PHONY : slowmoUI/fast - -#============================================================================= -# Target rules for targets named slowmoFlowEdit - -# Build rule for target. -slowmoFlowEdit: cmake_check_build_system - $(MAKE) -f CMakeFiles/Makefile2 slowmoFlowEdit -.PHONY : slowmoFlowEdit - -# fast build rule for target. -slowmoFlowEdit/fast: - $(MAKE) -f slowmoFlowEdit/CMakeFiles/slowmoFlowEdit.dir/build.make slowmoFlowEdit/CMakeFiles/slowmoFlowEdit.dir/build -.PHONY : slowmoFlowEdit/fast - -#============================================================================= -# Target rules for targets named slowmoInfo - -# Build rule for target. -slowmoInfo: cmake_check_build_system - $(MAKE) -f CMakeFiles/Makefile2 slowmoInfo -.PHONY : slowmoInfo - -# fast build rule for target. -slowmoInfo/fast: - $(MAKE) -f slowmoInfo/CMakeFiles/slowmoInfo.dir/build.make slowmoInfo/CMakeFiles/slowmoInfo.dir/build -.PHONY : slowmoInfo/fast - -#============================================================================= -# Target rules for targets named slowmoRenderer - -# Build rule for target. -slowmoRenderer: cmake_check_build_system - $(MAKE) -f CMakeFiles/Makefile2 slowmoRenderer -.PHONY : slowmoRenderer - -# fast build rule for target. -slowmoRenderer/fast: - $(MAKE) -f slowmoRenderer/CMakeFiles/slowmoRenderer.dir/build.make slowmoRenderer/CMakeFiles/slowmoRenderer.dir/build -.PHONY : slowmoRenderer/fast - -#============================================================================= -# Target rules for targets named visualizeFlow - -# Build rule for target. -visualizeFlow: cmake_check_build_system - $(MAKE) -f CMakeFiles/Makefile2 visualizeFlow -.PHONY : visualizeFlow - -# fast build rule for target. -visualizeFlow/fast: - $(MAKE) -f visualizeFlow/CMakeFiles/visualizeFlow.dir/build.make visualizeFlow/CMakeFiles/visualizeFlow.dir/build -.PHONY : visualizeFlow/fast - -#============================================================================= -# Target rules for targets named Test - -# Build rule for target. -Test: cmake_check_build_system - $(MAKE) -f CMakeFiles/Makefile2 Test -.PHONY : Test - -# fast build rule for target. -Test/fast: - $(MAKE) -f test/CMakeFiles/Test.dir/build.make test/CMakeFiles/Test.dir/build -.PHONY : Test/fast - -#============================================================================= -# Target rules for targets named encodeFramesTest - -# Build rule for target. -encodeFramesTest: cmake_check_build_system - $(MAKE) -f CMakeFiles/Makefile2 encodeFramesTest -.PHONY : encodeFramesTest - -# fast build rule for target. -encodeFramesTest/fast: - $(MAKE) -f test/CMakeFiles/encodeFramesTest.dir/build.make test/CMakeFiles/encodeFramesTest.dir/build -.PHONY : encodeFramesTest/fast - -#============================================================================= -# Target rules for targets named encodeTest - -# Build rule for target. -encodeTest: cmake_check_build_system - $(MAKE) -f CMakeFiles/Makefile2 encodeTest -.PHONY : encodeTest - -# fast build rule for target. -encodeTest/fast: - $(MAKE) -f test/CMakeFiles/encodeTest.dir/build.make test/CMakeFiles/encodeTest.dir/build -.PHONY : encodeTest/fast - -#============================================================================= -# Target rules for targets named UnitTests - -# Build rule for target. -UnitTests: cmake_check_build_system - $(MAKE) -f CMakeFiles/Makefile2 UnitTests -.PHONY : UnitTests - -# fast build rule for target. -UnitTests/fast: - $(MAKE) -f unittests/CMakeFiles/UnitTests.dir/build.make unittests/CMakeFiles/UnitTests.dir/build -.PHONY : UnitTests/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 "... sV" - @echo "... sVencode" - @echo "... sVflow" - @echo "... sVinfo" - @echo "... sVvis" - @echo "... sVgui" - @echo "... sVproj" - @echo "... slowmoInterpolate" - @echo "... videoInfo" - @echo "... slowmoUI" - @echo "... slowmoFlowEdit" - @echo "... slowmoInfo" - @echo "... slowmoRenderer" - @echo "... visualizeFlow" - @echo "... Test" - @echo "... encodeFramesTest" - @echo "... encodeTest" - @echo "... UnitTests" -.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 -
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/docs
Deleted
-(directory)
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/docs/src
Deleted
-(directory)
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/lib
Deleted
-(directory)
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/lib/CMakeLists.txt
Deleted
@@ -1,62 +0,0 @@ -# Static libraries -# http://www.itk.org/pipermail/insight-users/2007-November/024141.html -# http://www.linux-magazin.de/Heft-Abo/Ausgaben/2007/02/Mal-ausspannen - -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99") - -set(LIB_SRC_BASE - defs_sV.cpp - defs_sV.hpp - vector_sV.cpp - shutter_sV.cpp - intMatrix_sV.cpp - interpolate_sV.cpp - bezierTools_sV.cpp - sourceField_sV.cpp -) - -set(LIB_SRC_VIDEO - defs_sV.h - videoInfo_sV.c - avconvInfo_sV.cpp -) - -set(LIB_SRC_ARGS - trivialArgsReader_sV.cpp -) - -set(LIB_SRC_FLOW - flowRW_sV.cpp - flowField_sV.cpp - flowTools_sV.cpp - kernel_sV.cpp -) - -set(LIB_SRC_FLOWVIS - flowVisualization_sV.cpp -) - -set(HEADERS - flowRW_sV.h - flowField_sV.h - flowTools_sV.h -) - - -message(STATUS "FFMPEG libraries are at ${FFMPEG_LIBRARIES}") - -include_directories(${FFMPEG_INCLUDE_PATHS}) -add_library(sV STATIC ${LIB_SRC_BASE}) -target_link_libraries(sV ${QT_LIBRARIES}) - -add_library(sVinfo STATIC ${LIB_SRC_VIDEO}) -target_link_libraries(sVinfo ${FFMPEG_LIBRARIES}) - -add_library(sVencode STATIC ffmpegEncode_sV.c macros_sV.h) -target_link_libraries(sVencode ${FFMPEG_LIBRARIES}) - -add_library(sVflow STATIC ${LIB_SRC_FLOW}) - -add_library(sVvis STATIC ${LIB_SRC_FLOWVIS}) -target_link_libraries(sVvis sVflow ${QT_LIBRARIES}) -
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/lib/defs_sV.cpp
Deleted
@@ -1,170 +0,0 @@ -#include "defs_sV.hpp" - -Error_sV::Error_sV(QString msg) : - m_message(msg) -{ - qDebug() << msg; -} - -QString Error_sV::message() const { - return m_message; -} - -FlowBuildingError::FlowBuildingError(QString msg) : - Error_sV(msg) -{ - qDebug() << "Flow building error: " << msg; -} -FrameSourceError::FrameSourceError(QString msg) : - Error_sV(msg) -{ - qDebug() << "Frame source error: " << msg; -} -InterpolationError::InterpolationError(QString msg) : - Error_sV(msg) -{ - qDebug() << "Interpolation error : " << msg; -} - -QString toString(const QSize &size) -{ - return QString::fromUtf8("%1×%2").arg(size.width()).arg(size.height()); -} - -QString toString(const FrameSize &size) -{ - switch (size) { - case FrameSize_Orig: - return QObject::tr("Orig"); - case FrameSize_Small: - return QObject::tr("Small"); - default: - Q_ASSERT(false); - return QObject::tr("Unknown size"); - } -} - -QString toString(const FlowDirection &dir) -{ - switch (dir) { - case FlowDirection_Forward: - return QObject::tr("Forward"); - case FlowDirection_Backward: - return QObject::tr("Backward"); - default: - Q_ASSERT(false); - return QObject::tr("Unknown direction"); - } -} - -QString toString(const CurveType &curveType) -{ - switch (curveType) { - case CurveType_Linear: - return QObject::tr("Linear"); - case CurveType_Bezier: - return QObject::trUtf8("Bézier"); - default: - Q_ASSERT(false); - return QObject::tr("Unknown curve type"); - } -} - -QString toString(const QPointF &p) -{ - return QString("(%1|%2)").arg(p.x()).arg(p.y()); -} - -QString toString(const TagAxis axis) -{ - switch (axis) { - case TagAxis_Source: - return QObject::tr("Source axis"); - case TagAxis_Output: - return QObject::tr("Output axis"); - default: - Q_ASSERT(false); - return QObject::tr("Unknown axis"); - } -} - -QString toString(const InterpolationType &interpolation) -{ - switch (interpolation) { - case InterpolationType_Forward: - return QObject::tr("Forward interpolation (fast)"); - case InterpolationType_ForwardNew: - return QObject::tr("Forward interpolation (accurate)"); - case InterpolationType_Twoway: - return QObject::tr("Two-way interpolation (fast)"); - case InterpolationType_TwowayNew: - return QObject::tr("Two-way interpolation (accurate)"); - case InterpolationType_Bezier: - return QObject::trUtf8("Bézier interpolation"); - default: - Q_ASSERT(false); - return QObject::tr("Unknown interpolation"); - } -} - -QString toString(const MotionblurType &type) -{ - switch (type) { - case MotionblurType_Stacking: - return QObject::tr("Stacking"); - case MotionblurType_Convolving: - return QObject::tr("Convolution"); - case MotionblurType_Nearest: - return QObject::tr("Nearest (no blurring)"); - default: - Q_ASSERT(false); - return QString("Unknown motion blur type"); - } -} - -Fps_sV::Fps_sV(int num, int den) throw(Error_sV) : - num(num), den(den) -{ - if (den <= 0) { - throw Error_sV("FPS denominator must be >= 0."); - } -} -Fps_sV::Fps_sV(QString fpsString) throw(Error_sV) -{ - QRegExp e("(\\d+)\\/(\\d+)"); - if (e.exactMatch(fpsString)) { - num = e.cap(1).toInt(); - den = e.cap(2).toInt(); - if (den <= 0) { - throw Error_sV("FPS denominator must be >= 0."); - } - } else { - throw Error_sV("Cannot create fps value from " + fpsString); - } -} -Fps_sV::Fps_sV(float fps) throw(Error_sV) -{ - if (fps <= 0) { - throw Error_sV(QString("FPS value must be larger than zero (is: %1)").arg(fps)); - } - // Check for 23.976 and similar numbers (24*1000/1001) - if (fabs(1000*ceil(fps)-1001*fps) < 7) { - num = 1000*ceil(fps); - den = 1001; - } else { - num = 100000*fps; - den = 100000; - // Prettify - for (int i = 10; i > 1; i--) { - while (num % i == 0 && den % i == 0) { - num /= i; - den /= i; - } - } - } -} - -QString Fps_sV::toString() const -{ - return QString("%1/%2").arg(num).arg(den); -}
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/lib/defs_sV.hpp
Deleted
@@ -1,172 +0,0 @@ -/* -slowmoVideo creates slow-motion videos from normal-speed videos. -Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. -*/ - -#ifndef DEFS_SV_HPP -#define DEFS_SV_HPP - -#include "macros_sV.h" - -#if defined(WINDOWS) && !defined(MXE) -typedef __int64 int64_t; -#else -#include <inttypes.h> -#endif - -#include <QtCore/QDebug> -#include <QtCore/QString> -#include <QtCore/QSize> -#include <QtCore/QPoint> -#include <QtGui/QColor> -#include <cmath> - -#define SLOWMOVIDEO_VERSION_MAJOR 0 -#define SLOWMOVIDEO_VERSION_MINOR 3 -#define SLOWMOVIDEO_VERSION_MICRO 1 - - -/// Contains information about this slowmoVideo version -namespace Version_sV { - /// Major version number - static int major = SLOWMOVIDEO_VERSION_MAJOR; - /// Minor version number - static int minor = SLOWMOVIDEO_VERSION_MINOR; - /// Micro version number - static int micro = SLOWMOVIDEO_VERSION_MICRO; - /// Version number as string - static QString version(QString("%1.%2.%3").arg(major).arg(minor).arg(micro)); - /// Architecture - static QString bits( -#ifdef BITS_64 - "64-bit" -#else - "32-bit" -#endif - ); - /// Platform - static QString platform( -#if defined LINUX - "Linux" -#elif defined OSX - "OSX" -#elif defined WINDOWS - "Windows" -#endif - ); -} - -enum FlowDirection { FlowDirection_Forward, FlowDirection_Backward }; -enum FrameSize { FrameSize_Orig = 1, FrameSize_Small = 2 }; -enum CurveType { CurveType_Linear = 1, CurveType_Bezier = 2 }; -enum TagAxis { TagAxis_Source = 1, TagAxis_Output = 2 }; -enum InterpolationType { InterpolationType_Forward = 0, InterpolationType_ForwardNew = 1, - InterpolationType_Twoway = 10, InterpolationType_TwowayNew = 11, - InterpolationType_Bezier = 20 }; -enum MotionblurType { MotionblurType_Stacking = 0, MotionblurType_Convolving = 10, - MotionblurType_Nearest = 20 }; - -/// Default colours used in slowmoVideo (e.g. in the user interface) -namespace Colours_sV { - static QColor colOk(158, 245, 94); ///< For checked text fields that are OK - static QColor colBad(247, 122, 48); ///< For checked text fields that are invalid -} - - -/// For general errors. -class Error_sV { -public: - /// Creates a new error object with the given information message. - Error_sV(QString msg); - /// Returns the information message. - QString message() const; -private: - QString m_message; -}; - -/// FPS representation, can guess numerator/denominator from a float value. -struct Fps_sV { - /// numerator - int num; - /// denominator - int den; - - Fps_sV(int num, int den) throw(Error_sV); ///< den must be > 0. - - Fps_sV(float fps) throw(Error_sV); ///< Converts a float fps number to a fractional. 23.97 and 29.97 are detected. - - Fps_sV(QString fpsString) throw(Error_sV); ///< Accepts fps strings like 24000/1001 for 23.97 fps. - - QString toString() const; - - /// Frames per second as float. - double fps() const { - return double(num)/den; - } -}; -/// For errors related to building optical flow. -class FlowBuildingError : public Error_sV { -public: - /// Default constructor. - FlowBuildingError(QString msg); -}; -/// For errors related to the frame source. -class FrameSourceError : public Error_sV { -public: - /// Default constructor. - FrameSourceError(QString msg); -}; -class InterpolationError : public Error_sV { -public: - /// Default constructor - InterpolationError(QString msg); -}; - -QString toString(const QSize& size); -QString toString(const FrameSize &size); -QString toString(const FlowDirection &dir); -QString toString(const CurveType &curveType); -QString toString(const QPointF &p); -QString toString(const TagAxis &axis); -QString toString(const InterpolationType &interpolation); -QString toString(const MotionblurType &interpolation); - -inline QDebug operator<<(QDebug qd, const FlowDirection &direction) { - switch (direction) { - case FlowDirection_Forward: - qd << "Forward"; - break; - case FlowDirection_Backward: - qd << "Backward"; - break; - default: - qd << "Unknown direction"; - Q_ASSERT(false); - break; - } - return qd; -} - -inline QDebug operator<<(QDebug qd, const FrameSize &frameSize) -{ - switch(frameSize) { - case FrameSize_Orig: - qd << "Original frame size"; - break; - case FrameSize_Small: - qd << "Small frame size"; - break; - default: - qd << "Unknown frame size"; - Q_ASSERT(false); - break; - } - return qd; -} - -#endif // DEFS_SV_HPP
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/lib/ffmpegEncode_sV.c
Deleted
@@ -1,484 +0,0 @@ -/* - This code is based on http://ffmpeg.org/doxygen/trunk/encoding_8c-source.html - and http://ffmpeg.org/doxygen/trunk/muxing_8c-source.html - and has been adjusted with a lot of help from Tjoppen at irc.freenode.org#ffmpeg. (Thanks!) - Copyright (c) 2001 Fabrice Bellard - 2011 Simon A. Eugster - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - */ - -#include "ffmpegEncode_sV.h" -#include <libswscale/swscale.h> - -void setErrorMessage(VideoOut_sV *video, const char *msg) -{ - if (video->errorMessage != NULL) { - free(video->errorMessage); - } - video->errorMessage = malloc(strlen(msg)+1); - strcpy(video->errorMessage, msg); -} - -void prepareDefault(VideoOut_sV *video) -{ - prepare(video, "/tmp/ffmpegTest.avi", NULL, 352, 288, 400000, - 1, 24); -} - -int open_video(VideoOut_sV *video) -{ - AVCodec *codec; - AVCodecContext *cc; - - cc = video->streamV->codec; - - /* find the video encoder */ - codec = avcodec_find_encoder(cc->codec_id); - if (!codec) { - char s200; - sprintf(s, "Codec for ID %d could not be found.\n", cc->codec_id); - fputs(s, stderr); - setErrorMessage(video, s); - return 3; - } else { - printf("Codec used: %s\n", codec->name); - } - - /* open the codec */ -#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(53,8,0) - if (avcodec_open(cc, codec) < 0) { -#else - if (avcodec_open2(cc, codec, NULL) < 0) { -#endif - char s200; - sprintf(s, "Could not open codec %s.\n", codec->long_name); - fputs(s, stderr); - return 3; - } - - video->outbufV = NULL; - if (!(video->fc->oformat->flags & AVFMT_RAWPICTURE)) { - /* allocate output buffer */ - /* XXX: API change will be done */ - /* buffers passed into lav* can be allocated any way you prefer, - as long as they're aligned enough for the architecture, and - they're freed appropriately (such as using av_free for buffers - allocated with av_malloc) */ - // \todo av_get_picture_size? - video->outbufSizeV = 200000; - video->outbufV = av_malloc(video->outbufSizeV); - } - return 0; -} - -int prepare(VideoOut_sV *video, const char *filename, const char *vcodec, const int width, const int height, const int bitrate, - const unsigned int numerator, const unsigned int denominator) -{ -#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(53,7,1) - // Must be called before using the avcodec library. (Done automatically in more recent versions.) - avcodec_init(); -#endif - - video->frameNr = 0; - video->errorMessage = NULL; - video->filename = malloc(strlen(filename)+1); - strcpy(video->filename, filename); - - /* initialize libavcodec, and register all codecs and formats */ - av_register_all(); -#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(53,19,0) - avformat_network_init(); -#endif - - /* allocate the output media context */ -#if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(52,45,0) - video->fc = avformat_alloc_context(); - video->fc->oformat = guess_format(NULL, filename, NULL); - strncpy(video->fc->filename, filename, sizeof(video->fc->filename)); -#elif LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(53,4,0) || defined(MOST_LIKELY_LIBAV) - video->fc = avformat_alloc_context(); - video->fc->oformat = av_guess_format(NULL, filename, NULL); - strncpy(video->fc->filename, filename, sizeof(video->fc->filename)); -#else - // Actually introduced in 53.2.0 but not working in 53.3.0 packages - avformat_alloc_output_context2(&video->fc, NULL, NULL, filename); - if (!video->fc) { - printf("Could not deduce output format from file extension: using MPEG.\n"); - avformat_alloc_output_context2(&video->fc, NULL, "mpeg", filename); - } -#endif - if (!video->fc) { - const char *s = "Could allocate the output context, even MPEG is not available.\n"; - fputs(s, stderr); - setErrorMessage(video, s); - return 2; - } - video->format = video->fc->oformat; - printf("Using format %s.\n", video->format->name); - - /* Use the given vcodec if it is not NULL */ - if (vcodec != NULL) { - AVCodec *codec = avcodec_find_encoder_by_name(vcodec); - if (codec == NULL) { - char sstrlen(vcodec)+150; - sprintf(s, "No codec available for %s. Check the output of \nffmpeg -codecs\nto see a list of available codecs.\n", vcodec); - fputs(s, stderr); - setErrorMessage(video, s); - return 2; - } - printf("Found codec: %s\n", codec->long_name); - video->format->video_codec = codec->id; - } - - /* add the audio and video streams using the default format codecs - and initialize the codecs */ - video->streamV = NULL; - if (video->format->video_codec != CODEC_ID_NONE) { - -#if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(53,10,0) - video->streamV = av_new_stream(video->fc, 0); -#else - video->streamV = avformat_new_stream(video->fc, 0); -#endif - if (!video->streamV) { - const char *s = "Could not allocate the video stream.\n"; - fputs(s, stderr); - setErrorMessage(video, s); - return 2; - } - - AVCodecContext *cc = video->streamV->codec; - - cc->codec_id = video->format->video_codec; -#if LIBAVCODEC_VERSION_INT < (52<<16 | 64<<8 | 0) - cc->codec_type = CODEC_TYPE_VIDEO; -#else - cc->codec_type = AVMEDIA_TYPE_VIDEO; -#endif - - cc->bit_rate = bitrate; - - /* resolution must be a multiple of two */ - cc->width = width; - cc->height = height; - - - /* time base: this is the fundamental unit of time (in seconds) in terms - of which frame timestamps are represented. for fixed-fps content, - timebase should be 1/framerate and timestamp increments should be - identically 1. */ - cc->time_base = (AVRational){numerator, denominator}; - - cc->gop_size = 12; /* emit one intra frame every ten frames */ - - - cc->pix_fmt = PIX_FMT_YUV420P; - if (cc->codec_id == CODEC_ID_MPEG2VIDEO || cc->codec_id == CODEC_ID_MPEG4) { - /* just for testing, we also add B frames */ - cc->max_b_frames = 2; - } - if (cc->codec_id == CODEC_ID_MPEG1VIDEO){ - /* Needed to avoid using macroblocks in which some coeffs overflow. - This does not happen with normal video, it just happens here as - the motion of the chroma plane does not match the luma plane. */ - cc->mb_decision=2; - } - // some formats want stream headers to be separate - if(video->fc->oformat->flags & AVFMT_GLOBALHEADER) { - cc->flags |= CODEC_FLAG_GLOBAL_HEADER; - } - - video->rgbConversionContext = sws_getContext( - cc->width, cc->height, - PIX_FMT_BGRA, - cc->width, cc->height, - cc->pix_fmt, - SWS_BICUBIC, NULL, NULL, NULL); - - // One line size for each plane. RGB consists of one plane only. - // (YUV420p consists of 3, Y, Cb, and Cr - video->rgbLinesize0 = cc->width*4; - video->rgbLinesize1 = 0; - video->rgbLinesize2 = 0; - video->rgbLinesize3 = 0; - - if (video->rgbConversionContext == NULL) { - char s200; - sprintf(s, "Cannot initialize the RGB conversion context. Incorrect size (%dx%d)?\n", cc->width, cc->height); - fputs(s, stderr); - setErrorMessage(video, s); - return 2; - } - - - printf("Settings: %dx%d, %d bits/s (tolerance: %d), %d/%d fps\n", cc->width, cc->height, - cc->bit_rate, cc->bit_rate_tolerance, cc->time_base.den, cc->time_base.num); -// printf("Stream settings: %d/%d fps\n", video->streamV->time_base.den, video->streamV->time_base.num); - fflush(stdout); - } else { - const char *s = "No codec ID given.\n"; - fputs(s, stderr); - setErrorMessage(video, s); - return 2; - } - -#if LIBAVFORMAT_VERSION_INT <= AV_VERSION_INT(52,100,1) - dump_format(video->fc, 0, filename, 1); -#else - av_dump_format(video->fc, 0, filename, 1); -#endif - - /* now that all the parameters are set, we can open the audio and - video codecs and allocate the necessary encode buffers */ - if (video->streamV) { - int ret = open_video(video); - if (ret != 0) { - return ret; - } - } else { - const char *s = "Could not open video stream.\n"; - fputs(s, stderr); - setErrorMessage(video, s); - return 2; - } - - - - /* open the output file, if needed */ - if (!(video->format->flags & AVFMT_NOFILE)) { -#if LIBAVFORMAT_VERSION_INT <= AV_VERSION_INT(52,102,0) - if (url_fopen(&video->fc->pb, filename, URL_WRONLY) < 0) { -#else -#if LIBAVFORMAT_VERSION_INT <= AV_VERSION_INT(53,0,0) - if (avio_open(&video->fc->pb, filename, AVIO_WRONLY) < 0) { -#else - if (avio_open(&video->fc->pb, filename, AVIO_FLAG_WRITE) < 0) { -#endif -#endif - - // Check if non-ASCII characters are present in the file path - char nonAscii = 0; - for (int i = 0; i < strlen(video->filename); i++) { - if ((unsigned short)video->filenamei > 0x7f) { - fprintf(stderr, "Contains non-ASCII character: %c (%d)\n", video->filenamei, (unsigned char)video->filenamei); - nonAscii = 1; - } - } - - // Build the error message - char *msg; - if (nonAscii == 1) { - msg = "Could not open file (probably due to non-ASCII characters): "; - } else { - msg = "Could not open file: "; - } - char *msgAll = malloc(sizeof(char) * (strlen(filename) + strlen(msg))); - strcpy(msgAll, msg); - strcat(msgAll, filename); - fputs(msgAll, stderr); - setErrorMessage(video, msgAll); - free(msgAll); - return 5; - } - } - - /* write the stream header, if any */ -#if LIBAVFORMAT_VERSION_INT <= AV_VERSION_INT(53,1,3) - av_write_header(video->fc); -#else - avformat_write_header(video->fc, NULL); -#endif - - - /* alloc image and output buffer */ - video->outbufSizeV = avpicture_get_size(video->streamV->codec->pix_fmt, width, height); - video->outbufV = av_malloc(video->outbufSizeV); - - video->picture = avcodec_alloc_frame(); - avpicture_alloc((AVPicture*)video->picture, video->streamV->codec->pix_fmt, - video->streamV->codec->width, video->streamV->codec->height); - if (!video->picture) { - const char *s = "Could not allocate AVPicture.\n"; - fputs(s, stderr); - setErrorMessage(video, s); - return 2; - } - - return 0; -} - -int eatARGB(VideoOut_sV *video, const unsigned char *data) -{ - fflush(stdout); - - int ret = 0; - AVCodecContext *cc = video->streamV->codec; - -#if LIBSWSCALE_VERSION_INT < AV_VERSION_INT(0,8,0) - sws_scale(video->rgbConversionContext, - (uint8_t**)&data, video->rgbLinesize, - 0, cc->height, - video->picture->data, video->picture->linesize - ); -#else - sws_scale(video->rgbConversionContext, - &data, video->rgbLinesize, - 0, cc->height, - video->picture->data, video->picture->linesize - ); -#endif - - - if (video->fc->oformat->flags & AVFMT_RAWPICTURE) { - /* raw video case. The API will change slightly in the near - future for that */ - AVPacket pkt; - av_init_packet(&pkt); - -#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(52,30,2) - pkt.flags |= PKT_FLAG_KEY; -#else - pkt.flags |= AV_PKT_FLAG_KEY; -#endif - pkt.stream_index = video->streamV->index; - pkt.data = (uint8_t *)video->picture; - pkt.size = sizeof(AVPicture); - - ret = av_interleaved_write_frame(video->fc, &pkt); - } else { - /* encode the image */ - video->outSize = avcodec_encode_video(cc, video->outbufV, video->outbufSizeV, video->picture); - /* if zero size, it means the image was buffered */ - if (video->outSize > 0) { - AVPacket pkt; - av_init_packet(&pkt); - - if (cc->coded_frame->pts != AV_NOPTS_VALUE) { - pkt.pts = av_rescale_q(cc->coded_frame->pts, cc->time_base, video->streamV->time_base); -// printf("pkt.pts is %d.\n", pkt.pts); - } - if(cc->coded_frame->key_frame) { -#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(52,30,2) - pkt.flags |= PKT_FLAG_KEY; -#else - pkt.flags |= AV_PKT_FLAG_KEY; -#endif - } - pkt.stream_index = video->streamV->index; - pkt.data = video->outbufV; - pkt.size = video->outSize; - - /* write the compressed frame in the media file */ - ret = av_interleaved_write_frame(video->fc, &pkt); - } else { - ret = 0; - } - } - if (ret != 0) { - const char *s = "Error while writing video frame (interleaved_write).\n"; - fputs(s, stderr); - setErrorMessage(video, s); - return ret; - } - printf("Added frame %d to %s.\n", video->frameNr, video->filename); - video->frameNr++; - - return ret; -} - -void eatSample(VideoOut_sV *video) -{ - fflush(stdout); - /* prepare a dummy image */ - /* Y */ - int x, y; - for(y = 0; y < video->streamV->codec->height; y++) { - for(x = 0; x < video->streamV->codec->width; x++) { - video->picture->data0y * video->picture->linesize0 + x = x + y + video->frameNr * 3; - } - } - - /* Cb and Cr */ - for(y = 0; y < video->streamV->codec->height/2; y++) { - for(x = 0; x < video->streamV->codec->width/2; x++) { - video->picture->data1y * video->picture->linesize1 + x = 128 + y + video->frameNr * 2; - video->picture->data2y * video->picture->linesize2 + x = 64 + x + video->frameNr * 5; - } - } - - /* encode the image */ - AVCodecContext *cc = video->streamV->codec; - video->outSize = avcodec_encode_video(cc, video->outbufV, video->outbufSizeV, video->picture); - /* if zero size, it means the image was buffered */ - if (video->outSize > 0) { - AVPacket pkt; - av_init_packet(&pkt); - - if (cc->coded_frame->pts != AV_NOPTS_VALUE) { - pkt.pts = av_rescale_q(cc->coded_frame->pts, cc->time_base, video->streamV->time_base); - printf("pkt.pts is %ld.\n", pkt.pts); - } - if(cc->coded_frame->key_frame) { -#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(52,30,2) - pkt.flags |= PKT_FLAG_KEY; -#else - pkt.flags |= AV_PKT_FLAG_KEY; -#endif - } - pkt.stream_index = video->streamV->index; - pkt.data = video->outbufV; - pkt.size = video->outSize; - - /* write the compressed frame in the media file */ - av_interleaved_write_frame(video->fc, &pkt); - } - - video->frameNr++; -} - -void finish(VideoOut_sV *video) -{ - - /* write the trailer, if any. the trailer must be written - * before you close the CodecContexts open when you wrote the - * header; otherwise write_trailer may try to use memory that - * was freed on av_codec_close() */ - av_write_trailer(video->fc); - - /* close each codec */ - if (video->streamV) { - avcodec_close(video->streamV->codec); - av_free(video->picture->data0); - av_free(video->picture); - av_free(video->outbufV); - } - - /* free the streams */ - for(int i = 0; i < video->fc->nb_streams; i++) { - av_freep(&video->fc->streamsi->codec); - av_freep(&video->fc->streamsi); - } - - if (!(video->format->flags & AVFMT_NOFILE)) { - /* close the output file */ -#if LIBAVFORMAT_VERSION_INT <= AV_VERSION_INT(52,106,0) - url_fclose(video->fc->pb); -#else - avio_close(video->fc->pb); -#endif - } - - /* free the stream */ - av_free(video->fc); - - sws_freeContext(video->rgbConversionContext); - printf("\nWrote to %s.\n", video->filename); - - -#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(53,13,0) - avformat_network_deinit(); -#endif -}
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/lib/ffmpegEncode_sV.h
Deleted
@@ -1,85 +0,0 @@ -#ifndef FFMPEGENCODE_SV_H -#define FFMPEGENCODE_SV_H -/* - Copyright (c) 2011 Simon A. Eugster - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - */ - -#include "defs_sV.h" - -// Against the «UINT64_C not declared» message. -// See: http://code.google.com/p/ffmpegsource/issues/detail?id=11 -#ifdef __cplusplus - #define __STDC_CONSTANT_MACROS - #ifdef _STDINT_H - #undef _STDINT_H - #endif - # include <stdint.h> -#endif - -#include <libavcodec/avcodec.h> -#include <libavformat/avformat.h> - -#if ((LIBAVFORMAT_VERSION_MAJOR == 53) && (LIBAVFORMAT_VERSION_MINOR >= 21) && (LIBAVFORMAT_VERSION_MICRO < 100)) -#define MOST_LIKELY_LIBAV -#endif - -/// This struct can eat frames and produces videos! -/// Variables should not be changed from the outside. -typedef struct VideoOut_sV { - - AVFrame *picture; ///< Temporary picture for the incoming frame - AVFormatContext *fc; ///< Video's format context - AVOutputFormat *format; ///< Just a shortcut to fc->format - AVStream *streamV; ///< Video output stream - - /// Current frame number that is encoded - int frameNr; - - /// Context for converting RGB frames to YUV420p - struct SwsContext* rgbConversionContext; - /// Required for converting RGB images - int rgbLinesize4; - - /// Video filename - char *filename; - - int outSize; - int outbufSizeV; - uint8_t *outbufV; - - /// Set if an error occurs (file does not exist, for example), for more accurate information. - char *errorMessage; - -} VideoOut_sV; - -/// Prepares a default VideoOut_sV struct, mainly for testing purposes with eatSample(). -void prepareDefault(VideoOut_sV *video); -/** - Prepares a VideoOut_sV struct. After preparation it is ready to eat RGB images. - \param video VideoOut_sV struct to prepare. - \param filename Target filename - \param vcodec Video codec to use (see <tt>ffmpeg -codecs</tt>). May be \c NULL, - in this case a default codec for the format will be chosen. - \param width Video width - \param height Video height - \param bitrate Bit rate. <tt>width*height*fps</tt> seems to be a good choice for high quality. - \param numerator A frame is shown for <tt>numerator/denominator s</tt>; i.e. the fps number is <tt>denominator/numerator</tt>. - \param denominator See numerator. - */ -int prepare(VideoOut_sV *video, const char *filename, const char *vcodec, const int width, const int height, const int bitrate, - const unsigned int numerator, const unsigned int denominator); - -/// Eats an RGB image and deposits it in the output frame. -int eatARGB(VideoOut_sV *video, const unsigned char *data); -/// Eats a sample image. For testing. -void eatSample(VideoOut_sV *video); - -/// Finishes the produced video file. -void finish(VideoOut_sV *video); - -#endif // FFMPEGENCODE_SV_H
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/lib/flowField_sV.cpp
Deleted
@@ -1,111 +0,0 @@ -/* -slowmoVideo creates slow-motion videos from normal-speed videos. -Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. -*/ - -#include "flowField_sV.h" -#include "string.h" -#include <iostream> - -float FlowField_sV::nullValue = 65535; - -FlowField_sV::FlowField_sV(int width, int height) : - m_width(width), - m_height(height) -{ - m_data = new float2*m_width*m_height; -} - -FlowField_sV::FlowField_sV(int width, int height, float *data, FlowField_sV::GLFormat format) : - m_width(width), - m_height(height) -{ - m_data = new float2*m_width*m_height; - - switch (format) { - case GLFormat_RG: - memcpy(m_data, data, width*height*2*sizeof(float)); - break; - case GLFormat_RGB: - default: - float *fieldData = m_data; - int pos = 0; - for (int i = 0; i < width*height; i++) { - *(fieldData++) = datapos++; - *(fieldData++) = datapos++; - pos++; - } - } -} - -FlowField_sV::~FlowField_sV() -{ - delete m_data; -} - -float FlowField_sV::x(int x, int y) const -{ - return m_data2*(y*m_width+x)+0; -} -float FlowField_sV::y(int x, int y) const -{ - return m_data2*(y*m_width+x)+1; -} - -float& FlowField_sV::rx(int x, int y) -{ - return m_data2*(y*m_width+x)+0; -} -float& FlowField_sV::ry(int x, int y) -{ - return m_data2*(y*m_width+x)+1; -} - -void FlowField_sV::setX(int x, int y, float value) -{ - m_data2*(y*m_width+x)+0 = value; -} -void FlowField_sV::setY(int x, int y, float value) -{ - m_data2*(y*m_width+x)+1 = value; -} - -float* FlowField_sV::data() -{ - return m_data; -} - -bool FlowField_sV::operator ==(const FlowField_sV& other) const -{ - - if (m_width != other.m_width) { - std::cout << "Width differs: " << m_width << " vs. " << other.m_width << "." << std::endl; - return false; - } - if (m_height != other.m_height) { - std::cout << "Height differs. " << m_height << " vs. " << other.m_height << "" << std::endl; - return false; - } - - for (int y = 0; y < m_height; y++) { - for (int x = 0; x < m_width; x++) { - if (this->x(x,y) != other.x(x,y)) { - std::cout << "x Value differs at " << x << "," << y << ": " - << this->x(x,y) << "/" << other.x(x,y) << std::endl; - return false; - } - if (this->y(x,y) != other.y(x,y)) { - std::cout << "y Value differs at " << x << "," << y << ": " - << this->y(x,y) << "/" << other.y(x,y) << std::endl; - return false; - } - } - } - - return true; -}
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/lib/flowRW_sV.cpp
Deleted
@@ -1,104 +0,0 @@ -/* -slowmoVideo creates slow-motion videos from normal-speed videos. -Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. -*/ - -#include "flowRW_sV.h" -#include "flowField_sV.h" - -#include <iostream> -#include <fstream> - -const std::string FlowRW_sV::m_magicNumber = "flow_sV"; -const char FlowRW_sV::m_version = 1; - -void FlowRW_sV::save(std::string filename, FlowField_sV *flowField) -{ - int width = flowField->width(); - int height = flowField->height(); - std::cout << "Writing flow file " << filename << ": " << width << "x" << height - << ", version " << (int)m_version << ", magic number " << m_magicNumber << std::endl; - - float *data = flowField->data(); - std::ofstream file(filename.c_str(), std::ios_base::out | std::ios_base::binary); - file.write((char*) m_magicNumber.c_str(), m_magicNumber.length()*sizeof(char)); - file.write((char*) &m_version, sizeof(char)); - file.write((char*) &width, sizeof(int)); - file.write((char*) &height, sizeof(int)); - - file.write((char*) data, sizeof(float)*flowField->dataSize()); - file.close(); -} - -FlowRW_sV::FlowInfo_sV FlowRW_sV::readInfo(std::string filename) -{ - FlowInfo_sV info; - - std::ifstream file(filename.c_str(), std::ios_base::in | std::ios_base::binary); - - char *magic = new charm_magicNumber.size()+1; - magicm_magicNumber.size() = 0; - file.read(magic, sizeof(char)*m_magicNumber.size()); - file.read(&info.version, sizeof(char)); - info.magic = std::string(magic); - delete magic; - - - file.read((char*) &info.width, sizeof(int)); - file.read((char*) &info.height, sizeof(int)); - if (file.rdstate() == std::ios::goodbit) { - if (info.magic.compare(m_magicNumber) == 0) { - info.valid = true; - } - std::cout << "Magic number: " << info.magic << ", version: " << (int)info.version - << ", size: " << info.width << "x" << info.height << std::endl; - } else { - std::cerr << "Failed to read width/height from " << filename << "." << std::endl; - } - file.close(); - - return info; -} - -FlowField_sV* FlowRW_sV::load(std::string filename) throw(FlowRWError) -{ - std::ifstream file(filename.c_str(), std::ios_base::in | std::ios_base::binary); - - char *magic = new charm_magicNumber.size()+1; - magicm_magicNumber.size() = 0; - char version; - - file.read(magic, sizeof(char)*m_magicNumber.size()); - file.read((char*) &version, sizeof(char)); - - int width, height; - file.read((char*) &width, sizeof(int)); - file.read((char*) &height, sizeof(int)); - if (file.rdstate() != std::ios::goodbit) { - file.close(); - throw FlowRWError("Failed to read width/height from file " + filename); - } - - FlowField_sV *field = new FlowField_sV(width, height); - - file.read((char*) field->data(), sizeof(float)*field->dataSize()); - if (file.rdstate() != std::ios::goodbit) { - delete field; - file.close(); - throw FlowRWError("Failed to read data from file " + filename); - } - file.close(); - - std::cout << "Read flow file of size " << field->width() - << "×" << field->height() - << ". Magic number: " << magic - << ", version: " << (int)version << std::endl; - - delete magic; - return field; -}
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/lib/flowRW_sV.h
Deleted
@@ -1,80 +0,0 @@ -/* -slowmoVideo creates slow-motion videos from normal-speed videos. -Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. -*/ - -#ifndef FLOWRW_SV_H -#define FLOWRW_SV_H - -//#include "defs_sV.hpp" -#include <string> - -class FlowField_sV; - -/** - \brief Reads and writes Optical Flow fields. - - Binary format description: - \code - "flow_sV" 0x1(char) width(int) height(int) - x0(float) y0(float) x1 y1 x2 y2 ... xwidth*height-1 ywidth*height-1 - \endcode - The number after \c flow_sV describes the file version, this allows to e.g. add compression - in future. Width and height should match the image resolution. The following flow data - describes the movement of each pixel in x and y direction. - \see FlowField_sV - */ -class FlowRW_sV -{ -public: - - /// Holds information about a flow file - struct FlowInfo_sV { - /// Flow field width - int width; - /// Flow field height - int height; - /// Flow field version for future changes in the file format - char version; - /// Magic number (first few bytes) - std::string magic; - /// Should be set to true if the flow is valid (valid magic number, valid version etc.) - bool valid; - /// Initially set to invalid. - FlowInfo_sV() { - magic = "flow_sV"; - version = '1'; - valid = false; - } - }; - - struct FlowRWError { - std::string message; - FlowRWError(std::string msg) : message(msg) {} - }; - - /** \fn load(std::string) - \return \c NULL, if the file could not be loaded, and the flow field otherwise. - */ - /** \fn save(std::string, FlowField_sV*); - \see FlowField_sV::FlowField_sV(int, int, float*, FlowField_sV::GLFormat) - */ - /** \fn readInfo(std::string) - \return Information about the flow file (like dimension); Does not read the whole file and is therefore faster than load(std::string). - */ - static void save(std::string filename, FlowField_sV *flowField); - static FlowField_sV* load(std::string filename) throw(FlowRWError); - - static FlowInfo_sV readInfo(std::string filename); - -private: - static const std::string m_magicNumber; - static const char m_version; -}; - -#endif // FLOWRW_SV_H
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/lib/flowTools_sV.cpp
Deleted
@@ -1,377 +0,0 @@ -#include "flowTools_sV.h" -#include <cmath> -#include <cassert> -#include <iostream> - -//#define DEBUG - -void FlowTools_sV::deleteRect(FlowField_sV &field, int top, int left, int bottom, int right) -{ - for (int y = top; y <= bottom; y++) { - for (int x = left; x <= right; x++) { - field.rx(x,y) = FlowField_sV::nullValue; - } - } -} - -void FlowTools_sV::refill(FlowField_sV &field, const Kernel_sV &kernel, int top, int left, int bottom, int right) -{ - assert(top <= bottom); - assert(left <= right); - assert(top >= 0); - assert(left >= 0); - assert(bottom < field.height()); - assert(right < field.width()); - - int newTop = top; - int newLeft = left; - int newRight = right; - int newBottom = bottom; - - if (top > 0) { - refillLine(field, kernel, top, left, right-left+1, true); - newTop++; - } - if (left > 0) { - refillLine(field, kernel, top, left, bottom-top+1, false); - newLeft++; - } - if (right+1 < field.width()) { - refillLine(field, kernel, top, right, bottom-top+1, false); - newRight--; - } - if (bottom+1 < field.height()) { - refillLine(field, kernel, bottom, left, right-left+1, true); - newBottom--; - } - - if (newRight-newLeft >= 0 && newBottom-newTop >= 0) { - refill(field, kernel, newTop, newLeft, newBottom, newRight); - } -} - -void FlowTools_sV::refillLine(FlowField_sV &field, const Kernel_sV &kernel, - int startTop, int startLeft, int length, bool horizontal) -{ - int x = startLeft; - int y = startTop; - - float valX = 0; - float valY = 0; - float weight = 0; - - while (true) { - if (x >= field.width() || (horizontal && x >= startLeft+length) - || y >= field.height() || (!horizontal && y >= startTop+length)) { - break; - } - valX = 0; - valY = 0; - weight = 0; - - for (int dx = -kernel.rX(); dx <= kernel.rX(); dx++) { - for (int dy = -kernel.rY(); dy <= kernel.rY(); dy++) { - if (x+dx >= 0 && x+dx < field.width() - && y+dy >= 0 && y+dy < field.height() - && field.x(x+dx,y+dy) != FlowField_sV::nullValue) { - valX += field.x(x+dx,y+dy) * kernel(dx, dy); - valY += field.y(x+dx,y+dy) * kernel(dx, dy); - weight += kernel(dx, dy); - } - } - } - if (weight > 0) { - std::cout << "Before: " << field.rx(x,y); - field.rx(x,y) = valX/weight; - std::cout << ", Afterwards: " << field.rx(x,y) << std::endl; - field.ry(x,y) = valY/weight; - } - - if (horizontal) { - x++; - } else { - y++; - } - - } -} - -void FlowTools_sV::refill(FlowField_sV &field, int top, int left, int bottom, int right) -{ - assert(top <= bottom); - assert(left <= right); - assert(top >= 0); - assert(left >= 0); - assert(bottom < field.height()); - assert(right < field.width()); - - // Top line - if (top == bottom) { - // Only a single line left. Can be inside an image or at a border. - if (top == 0) { - refillLine(field, top, left, right-left+1, HorizontalFromBottom); - } else if (top == field.height()-1) { - refillLine(field, top, left, right-left+1, HorizontalFromTop); - } else { - refillLine(field, top, left, right-left+1, HorizontalFromBoth); - } - } else if (top > 0){ - if (bottom > top) { - // Fill from above - refillLine(field, top, left, right-left+1, HorizontalFromTop); - } else { - // Only a line left; fill from both sides - refillLine(field, top, left, right-left+1, HorizontalFromBoth); - } - } - // Left line - if (left == right) { - if (left == 0) { - refillLine(field, top, left, bottom-top+1, VerticalFromRight); - } else if (left == field.width()-1) { - refillLine(field, top, left, bottom-top+1, VerticalFromLeft); - } else { - refillLine(field, top, left, bottom-top+1, VerticalFromBoth); - } - } else if (left > 0) { - if (right > left) { - refillLine(field, top, left, bottom-top+1, VerticalFromLeft); - } else { - refillLine(field, top, left, bottom-top+1, VerticalFromBoth); - } - } - // Right line - if (right+1 < field.width() && left != right) { // left == right already handled - if (left < right) { - refillLine(field, top, right, bottom-top+1, VerticalFromRight); - } else { - refillLine(field, top, right, bottom-top+1, VerticalFromBoth); - } - } - // Bottom line - if (bottom+1 < field.height() && bottom != top) { // bottom == top already handled - if (top < bottom) { - refillLine(field, bottom, left, right-left+1, HorizontalFromBottom); - } else { - refillLine(field, bottom, left, right-left+1, HorizontalFromBoth); - } - } - refillCorner(field, top, left, TopLeft); - refillCorner(field, top, right, TopRight); - refillCorner(field, bottom, left, BottomLeft); - refillCorner(field, bottom, right, BottomRight); - - if (bottom-top-2 >= 0 && right-left-2 >= 0) { - refill(field, top+(top > 0 ? 1 : 0), left+(left > 0 ? 1 : 0), - bottom-(bottom < field.height()-1 ? 1 : 0), right-(right < field.width()-1 ? 1 : 0)); - - // Now handle special cases where one line at the border was not filled (rect was only 2 pixels wide) - } else if (bottom-top-1 == 0) { - if (top == 0) { - refill(field, top, left, top, right); - } else if (bottom == field.height()-1) { - refill(field, bottom, left, bottom, right); - } - } else if (right-left-1 == 0) { - if (left == 0) { - refill(field, top, left, bottom, left); - } else if (right == field.width()-1) { - refill(field, top, right, bottom, right); - } - } - -} - -void FlowTools_sV::difference(const FlowField_sV &left, const FlowField_sV &right, FlowField_sV &out) -{ - float dx, dy; - for (int y = 0; y < left.height(); y++) { - for (int x = 0; x < left.width(); x++) { - dx = left.x(x,y); - dy = left.y(x,y); - if (x+dx >= 0 && y+dy >= 0 - && x+dx <= left.width()-1 && y+dy <= left.height()-1) { - dx += right.x(x+dx, y+dy); - dy += right.y(x+dx, y+dy); - } - out.setX(x,y, dx); - out.setY(x,y, dy); - } - } -} -void FlowTools_sV::signedDifference(const FlowField_sV &left, const FlowField_sV &right, FlowField_sV &out) -{ - float lx, ly; - float rx, ry; - for (int y = 0; y < left.height(); y++) { - for (int x = 0; x < left.width(); x++) { - lx = left.x(x,y); - ly = left.y(x,y); - if (x+lx >= 0 && y+ly >= 0 - && x+lx <= left.width()-1 && y+ly <= left.height()-1) { - rx = right.x(x+lx, y+ly); - ry = right.y(x+lx, y+ly); - if (fabs(lx)+fabs(ly) > fabs(rx)+fabs(ry)) { - lx = fabs(lx+rx); - ly = fabs(ly+ry); - } else { - lx = -fabs(lx+rx); - ly = -fabs(ly+ry); - } - } else { - lx = fabs(lx); - rx = fabs(rx); - } - out.setX(x,y, lx); - out.setY(x,y, ly); - } - } -} - - - - -void FlowTools_sV::refillLine(FlowField_sV &field, int startTop, int startLeft, int length, LineFillMode fillMode) -{ - int x = startLeft; - int y = startTop; - - float sumX; - float sumY; - short count = 0; - if (fillMode == HorizontalFromTop || fillMode == HorizontalFromBottom || fillMode == HorizontalFromBoth) { - x++; - while (x < startLeft+length) { - sumX = 0; - sumY = 0; - count = 0; - if (fillMode == HorizontalFromTop || fillMode == HorizontalFromBoth) { - sumX += field.x(x-1, y-1) + field.x(x, y-1) + field.x(x+1, y-1); - sumY += field.y(x-1, y-1) + field.y(x, y-1) + field.y(x+1, y-1); - count += 3; - } - if (fillMode == HorizontalFromBottom || fillMode == HorizontalFromBoth) { - sumX += field.x(x-1, y+1) + field.x(x, y+1) + field.x(x+1, y+1); - sumY += field.y(x-1, y+1) + field.y(x, y+1) + field.y(x+1, y+1); - count += 3; - } -#ifdef DEBUG - sumX *= 1.2; - sumY *= 1.2; -#endif - field.rx(x,y) = sumX/count; - field.ry(x,y) = sumY/count; - x++; - } - } else { - y++; - while (y < startTop + length) { - sumX = 0; - sumY = 0; - count = 0; - if (fillMode == VerticalFromLeft || fillMode == VerticalFromBoth) { - sumX += field.x(x-1, y-1) + field.x(x-1, y) + field.x(x-1, y+1); - sumY += field.y(x-1, y-1) + field.y(x-1, y) + field.y(x-1, y+1); - count += 3; - } - if (fillMode == VerticalFromRight || fillMode == VerticalFromBoth) { - sumX += field.x(x+1, y-1) + field.x(x+1, y) + field.x(x+1, y+1); - sumY += field.y(x+1, y-1) + field.y(x+1, y) + field.y(x+1, y+1); - count += 3; - } -#ifdef DEBUG - sumX *= 1.2; - sumY *= 1.2; -#endif - field.rx(x,y) = sumX/count; - field.ry(x,y) = sumY/count; - y++; - } - } -} - -void FlowTools_sV::refillCorner(FlowField_sV &field, int top, int left, CornerPosition pos) -{ - int dx; - int dy; - if (pos == TopRight || pos == BottomRight) { - dx = 1; - } else { - dx = -1; - } - if (pos == TopRight || pos == TopLeft) { - dy = -1; - } else { - dy = 1; - } - float sumX = 0; - float sumY = 0; - int count = 0; - if (left+dx > 0 && top+dy > 0 - && left+dx < field.width() && top+dy < field.height()) { - sumX += field.x(left+dx, top+dy); - sumY += field.y(left+dx, top+dy); - count++; - } - if (left+dx > 0 && top-dy > 0 - && left+dx < field.width() && top-dy < field.height()) { - sumX += field.x(left+dx, top-dy); - sumY += field.y(left+dx, top-dy); - count++; - } - if (left-dx > 0 && top+dy > 0 - && left-dx < field.width() && top+dy < field.height()) { - sumX += field.x(left-dx, top+dy); - sumY += field.y(left-dx, top+dy); - count++; - } -#ifdef DEBUG - sumX = 100; - sumY = 100; -#endif - field.rx(left,top) = sumX/count; - field.ry(left,top) = sumY/count; -} - - -FlowField_sV* FlowTools_sV::median(const FlowField_sV *const fa, const FlowField_sV *const fb, const FlowField_sV *const fc) -{ - assert(fa != NULL); - assert(fb != NULL); - assert(fc != NULL); - assert(fa->width() == fb->width() && fa->width() == fc->width()); - assert(fa->height() == fb->height() && fa->height() == fc->height()); - - int w = fa->width(); - int h = fa->height(); - FlowField_sV *ff = new FlowField_sV(w, h); - - for (int y = 0; y < h; y++) { - for (int x = 0; x < w; x++) { - float a = fa->x(x,y)*fa->x(x,y) + fa->y(x,y)*fa->y(x,y); - float b = fb->x(x,y)*fb->x(x,y) + fb->y(x,y)*fb->y(x,y); - float c = fc->x(x,y)*fc->x(x,y) + fc->y(x,y)*fc->y(x,y); - - // Determine the median - // < a b c - // a - ? ? - // b ? - ? - // c ? ? - - // The median element has SUM == 1 for its row - char detA = (a < b) + (a < c); - char detB = (b < a) + (b < c); - - if (detA == 1) { - ff->rx(x,y) = fa->x(x,y); - ff->ry(x,y) = fa->y(x,y); - } else if (detB == 1) { - ff->rx(x,y) = fb->x(x,y); - ff->ry(x,y) = fb->y(x,y); - } else { - ff->rx(x,y) = fc->x(x,y); - ff->ry(x,y) = fc->y(x,y); - } - } - } - return ff; -}
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/lib/flowTools_sV.h
Deleted
@@ -1,38 +0,0 @@ -#ifndef FLOWTOOLS_SV_H -#define FLOWTOOLS_SV_H - -#include "flowField_sV.h" -#include "kernel_sV.h" - -class FlowTools_sV -{ -public: - enum LineFillMode { HorizontalFromTop, HorizontalFromBottom, HorizontalFromBoth, - VerticalFromLeft, VerticalFromRight, VerticalFromBoth }; - - enum CornerPosition { TopLeft, TopRight, BottomLeft, BottomRight }; - - static void difference(const FlowField_sV &left, const FlowField_sV &right, FlowField_sV &out); - static void signedDifference(const FlowField_sV &left, const FlowField_sV &right, FlowField_sV &out); - - static void deleteRect(FlowField_sV &field, int top, int left, int bottom, int right); - - /** - \brief Clears the content of the given rectangle and fills it with the surrounding pixels. - - The coordinates are inclusive, so filling <code>(0,0,1,1)</code> fills four pixels. The axis origin <code>(0|0)</code> - is at top left. - */ - static void refill(FlowField_sV &field, int top, int left, int bottom, int right); - - static void refill(FlowField_sV &field, const Kernel_sV &kernel, int top, int left, int bottom, int right); - - static FlowField_sV* median(FlowField_sV const * const fa, FlowField_sV const * const fb, FlowField_sV const * const fc); - -private: - static void refillLine(FlowField_sV &field, int startTop, int startLeft, int length, LineFillMode fillMode); - static void refillLine(FlowField_sV &field, const Kernel_sV &kernel, int startTop, int startLeft, int length, bool horizontal); - static void refillCorner(FlowField_sV &field, int top, int left, CornerPosition pos); -}; - -#endif // FLOWTOOLS_SV_H
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/lib/interpolate_sV.cpp
Deleted
@@ -1,458 +0,0 @@ -/* -slowmoVideo creates slow-motion videos from normal-speed videos. -Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. -*/ - -#include "interpolate_sV.h" -#include "flowField_sV.h" -#include "flowTools_sV.h" -#include "sourceField_sV.h" -#include "vector_sV.h" -#include "bezierTools_sV.h" - -#ifdef WINDOWS -#include <math.h> -#else -#include <cmath> -#endif - -#include <QDebug> -#include <QImage> -#include <QColor> - -#define CLAMP1(x) ( ((x) > 1.0) ? 1.0 : (x) ) -#define CLAMP(x,min,max) ( ((x) < (min)) ? (min) : ( ((x) > (max)) ? (max) : (x) ) ) - -#define INTERPOLATE -//#define FIX_FLOW -#define FIX_BORDERS -//#define DEBUG_I - -enum ColorComponent { CC_Red, CC_Green, CC_Blue }; - - -inline -float interpR(const QColor cols22, float x, float y) -{ - return (1-x)*(1-y) * cols00.redF() - + x*(1-y) * cols10.redF() - + y*(1-x) * cols01.redF() - + x*y * cols11.redF(); -} - -inline -float interpG(const QColor cols22, float x, float y) -{ - return (1-x)*(1-y) * cols00.greenF() - + x*(1-y) * cols10.greenF() - + y*(1-x) * cols01.greenF() - + x*y * cols11.greenF(); -} - -inline -float interpB(const QColor cols22, float x, float y) -{ - return (1-x)*(1-y) * cols00.blueF() - + x*(1-y) * cols10.blueF() - + y*(1-x) * cols01.blueF() - + x*y * cols11.blueF(); -} - -QColor Interpolate_sV::interpolate(const QImage& in, float x, float y) -{ -#ifdef DEBUG_I - if (x >= in.width()-1 || y >= in.height()-1) { - Q_ASSERT(false); - } -#endif - QColor carr22; - int floorX = floor(x); - int floorY = floor(y); - carr00 = QColor(in.pixel(floorX, floorY)); - carr01 = QColor(in.pixel(floorX, floorY+1)); - carr10 = QColor(in.pixel(floorX+1, floorY)); - carr11 = QColor(in.pixel(floorX+1, floorY+1)); - - float dx = x - floorX; - float dy = y - floorY; - QColor out = QColor::fromRgbF( - interpR(carr, dx, dy), - interpG(carr, dx, dy), - interpB(carr, dx, dy) - ); - return out; -} - -/// validated. correct. -QColor Interpolate_sV::blend(const QColor &left, const QColor &right, float pos) -{ - Q_ASSERT(pos >= 0 && pos <= 1); - - float r = (1-pos)*left.redF() + pos*right.redF(); - float g = (1-pos)*left.greenF() + pos*right.greenF(); - float b = (1-pos)*left.blueF() + pos*right.blueF(); - float a = (1-pos)*left.alphaF() + pos*right.alphaF(); - r = CLAMP(r,0.0,1.0); - g = CLAMP(g,0.0,1.0); - b = CLAMP(b,0.0,1.0); - a = CLAMP(a,0.0,1.0); - return QColor::fromRgbF(r, g, b, a); -} - -void Interpolate_sV::blend(ColorMatrix4x4 &c, const QColor &blendCol, float posX, float posY) -{ - Q_ASSERT(posX >= 0 && posX <= 1); - Q_ASSERT(posY >= 0 && posY <= 1); - - if (c.c00.alpha() == 0) { c.c00 = blendCol; } - else { c.c00 = blend(c.c00, blendCol, std::sqrt((1-posX) * (1-posY))); } - - if (c.c10.alpha() == 0) { c.c10 = blendCol; } - else { c.c10 = blend(c.c10, blendCol, std::sqrt( posX * (1-posY))); } - - if (c.c01.alpha() == 0) { c.c01 = blendCol; } - else { c.c01 = blend(c.c01, blendCol, std::sqrt((1-posX) * posY)); } - - if (c.c11.alpha() == 0) { c.c11 = blendCol; } - else {c.c11 = blend(c.c11, blendCol, std::sqrt(posX * posY)); } -} - - -void Interpolate_sV::twowayFlow(const QImage &left, const QImage &right, const FlowField_sV *flowForward, const FlowField_sV *flowBackward, float pos, QImage &output) -{ -#ifdef INTERPOLATE - const float Wmax = left.width()-1.0001; // A little less than the maximum pixel to avoid out of bounds when interpolating - const float Hmax = left.height()-1.0001; - float posX, posY; -#endif - - QColor colOut, colLeft, colRight; - float r,g,b; - Interpolate_sV::Movement forward, backward; - - for (int y = 0; y < left.height(); y++) { - for (int x = 0; x < left.width(); x++) { - forward.moveX = flowForward->x(x, y); - forward.moveY = flowForward->y(x, y); - - backward.moveX = flowBackward->x(x, y); - backward.moveY = flowBackward->y(x, y); - -#ifdef INTERPOLATE - posX = x - pos*forward.moveX; - posY = y - pos*forward.moveY; - posX = CLAMP(posX, 0, Wmax); - posY = CLAMP(posY, 0, Hmax); - colLeft = interpolate(left, posX, posY); - - posX = x - (1-pos)*backward.moveX; - posY = y - (1-pos)*backward.moveY; - posX = CLAMP(posX, 0, Wmax); - posY = CLAMP(posY, 0, Hmax); - colRight = interpolate(right, posX, posY); -#else - colLeft = QColor(left.pixel(x - pos*forward.moveX, y - pos*forward.moveY)); - colRight = QColor(right.pixel(x - (1-pos)*backward.moveX , y - (1-pos)*backward.moveY)); -#endif - r = (1-pos)*colLeft.redF() + pos*colRight.redF(); - g = (1-pos)*colLeft.greenF() + pos*colRight.greenF(); - b = (1-pos)*colLeft.blueF() + pos*colRight.blueF(); - colOut = QColor::fromRgbF( - CLAMP1(r), - CLAMP1(g), - CLAMP1(b) - ); - output.setPixel(x,y, colOut.rgb()); - } - } -} - - -void Interpolate_sV::newTwowayFlow(const QImage &left, const QImage &right, - const FlowField_sV *flowLeftRight, const FlowField_sV *flowRightLeft, - float pos, QImage &output) -{ - const int W = left.width(); - const int H = left.height(); - - - SourceField_sV leftSourcePixel(flowLeftRight, pos); - leftSourcePixel.inpaint(); - SourceField_sV rightSourcePixel(flowRightLeft, 1-pos); - rightSourcePixel.inpaint(); - - float aspect = 1 - (.5 + std::cos(M_PI*pos)/2); - -#if defined(FIX_FLOW) - FlowField_sV diffField(flowLeftRight->width(), flowLeftRight->height()); - FlowTools_sV::difference(*flowLeftRight, *flowRightLeft, diffField); - float diffSum; - float tmpAspect; -#endif - -#ifdef FIX_BORDERS - bool leftOk; - bool rightOk; -#endif - - - float fx, fy; - QColor colLeft, colRight; - for (int y = 0; y < H; y++) { - for (int x = 0; x < W; x++) { - -#ifdef FIX_BORDERS - fx = leftSourcePixel.at(x,y).fromX; - fy = leftSourcePixel.at(x,y).fromY; - if (fx >= 0 && fx < W-1 - && fy >= 0 && fy < H-1) { - colLeft = interpolate(left, fx, fy); - leftOk = true; - } else { - fx = leftSourcePixel.at(x,y).fromX; - fy = leftSourcePixel.at(x,y).fromY; - fx = CLAMP(fx, 0, W-1.01); - fy = CLAMP(fy, 0, H-1.01); - colLeft = interpolate(left, fx, fy); - leftOk = false; - } - - fx = rightSourcePixel.at(x,y).fromX; - fy = rightSourcePixel.at(x,y).fromY; - if (fx >= 0 && fx < W-1 - && fy >= 0 && fy < H-1) { - colRight = interpolate(right, fx, fy); - rightOk = true; - } else { - colRight = qRgb(0,255,0); - rightOk = false; - } - - if (leftOk && rightOk) { - output.setPixel(x,y, blend(colLeft, colRight, aspect).rgba()); - } else if (rightOk) { - output.setPixel(x,y, colRight.rgba()); -// output.setPixel(x,y, qRgb(255, 0, 0)); - } else if (leftOk) { - output.setPixel(x,y, colLeft.rgba()); -// output.setPixel(x,y, qRgb(0, 255, 0)); - } else { - output.setPixel(x,y, colLeft.rgba()); - } -#else - fx = leftSourcePixel.at(x,y).fromX; - fy = leftSourcePixel.at(x,y).fromY; - fx = CLAMP(fx, 0, W-1.01); - fy = CLAMP(fy, 0, H-1.01); - colLeft = interpolate(left, fx, fy); - -#ifdef FIX_FLOW - diffSum = diffField.x(fx, fy)+diffField.y(fx, fy); - if (diffSum > 5) { - tmpAspect = 0; - } else if (diffSum < -5) { - tmpAspect = 1; - } else { - tmpAspect = aspect; - } -#endif - - fx = rightSourcePixel.at(x,y).fromX; - fy = rightSourcePixel.at(x,y).fromY; - fx = CLAMP(fx, 0, W-1.01); - fy = CLAMP(fy, 0, H-1.01); - colRight = interpolate(right, fx, fy); - -#ifdef FIX_FLOW - diffSum = diffField.x(fx, fy)+diffField.y(fx, fy); - if (diffSum < 5) { - tmpAspect = 0; - } else if (diffSum > -5) { - tmpAspect = 1; - } -#endif - -#ifdef FIX_FLOW - output.setPixel(x,y, blend(colLeft, colRight, tmpAspect).rgba()); -#else - output.setPixel(x,y, blend(colLeft, colRight, aspect).rgba()); -#endif - -#endif - } - } -} - -void Interpolate_sV::forwardFlow(const QImage &left, const FlowField_sV *flow, float pos, QImage &output) -{ - qDebug() << "Interpolating flow at offset " << pos; -#ifdef INTERPOLATE - float posX, posY; - const float Wmax = left.width()-1.0001; - const float Hmax = left.height()-1.0001; -#endif - - QColor colOut; - Interpolate_sV::Movement forward; - - for (int y = 0; y < left.height(); y++) { - for (int x = 0; x < left.width(); x++) { - // Forward flow from the left to the right image tells for each pixel in the right image - // from which location in the left image the pixel has come from. - forward.moveX = flow->x(x, y); - forward.moveY = flow->y(x, y); - -#ifdef INTERPOLATE - posX = x - pos*forward.moveX; - posY = y - pos*forward.moveY; - posX = CLAMP(posX, 0, Wmax); - posY = CLAMP(posY, 0, Hmax); - colOut = interpolate(left, posX, posY); -#else - colOut = QColor(left.pixel(x - pos*forward.moveX, y - pos*forward.moveY)); -#endif - output.setPixel(x,y, colOut.rgb()); - } - } -} - -void Interpolate_sV::newForwardFlow(const QImage &left, const FlowField_sV *flow, float pos, QImage &output) -{ - const int W = left.width(); - const int H = left.height(); - - // Calculate the source flow field - SourceField_sV field(flow, pos); - field.inpaint(); - - // Draw the pixels - float fx, fy; - for (int y = 0; y < H; y++) { - for (int x = 0; x < W; x++) { - // Since interpolate() uses the floor()+1 values, - // set the maximum to a little less than size-1 - // such that the pixel always lies inside. - fx = field.at(x,y).fromX; - fx = CLAMP(fx, 0, W-1.01); - fy = field.at(x,y).fromY; - fy = CLAMP(fy, 0, H-1.01); - output.setPixel(x,y, interpolate(left, fx, fy).rgba()); - } - } -} - - -/** - \todo fix bézier interpolation - \code - C prev - / / - / / - / / - A curr - \ - \ - B next (can be NULL) - \endcode - */ -void Interpolate_sV::bezierFlow(const QImage &prev, const QImage &right, const FlowField_sV *flowPrevCurr, const FlowField_sV *flowCurrNext, float pos, QImage &output) -{ - const float Wmax = prev.width()-1.0001; - const float Hmax = prev.height()-1.0001; - - Vector_sV a, b, c; - Vector_sV Ta, Sa; - float dist; - - QColor colOut; - - for (int y = 0; y < prev.height(); y++) { - for (int x = 0; x < prev.width(); x++) { - - a = Vector_sV(x, y); - // WHY minus? - c = a + Vector_sV(flowPrevCurr->x(x, y), flowPrevCurr->y(x, y)); - if (flowCurrNext != NULL) { - b = a + Vector_sV(flowCurrNext->x(x,y), flowCurrNext->y(x,y)); - } else { - b = a; - } - - dist = (b-a).length() + (c-a).length(); - if (dist > 0) { - Ta = b + ( (b-a).length() / dist ) * (c-b); - Sa = (Ta - a).rotate90(); - Sa = a + Sa; - - } else { - Sa = a; - } -#ifdef DEBUG_I - Sa = a; -#endif - - QPointF position = BezierTools_sV::interpolate(pos, c.toQPointF(), c.toQPointF(), Sa.toQPointF(), a.toQPointF()); - position.rx() = x - pos*flowPrevCurr->x(x,y); - position.ry() = y - pos*flowPrevCurr->y(x,y); - position.rx() = CLAMP(position.x(), 0, Wmax); - position.ry() = CLAMP(position.y(), 0, Hmax); - -#ifdef DEBUG_I -// if (x == 100 && y == 100 && false) { -// qDebug() << "Interpolated from " << toString(c.toQPointF()) << ", " << toString(a.toQPointF()) << ", " -// << toString(b.toQPointF()) << " at " << pos << ": " << toString(position); -// } - if (y % 4 == 0) { - position.rx() = x; - position.ry() = y; - } -#endif - - colOut = interpolate(prev, position.x(), position.y()); - -#ifdef DEBUG_I - if (y % 4 == 1 && x % 2 == 0) { - colOut = right.pixel(x, y); - } -#endif - output.setPixel(x,y, colOut.rgb()); - - } - } - - /* - for (int y = 0; y < prev.height(); y++) { - for (int x = 1; x < prev.width()-1; x++) { - if (qAlpha(output.pixel(x,y)) == 0 - && qAlpha(output.pixel(x-1,y)) > 0 - && qAlpha(output.pixel(x+1,y)) > 0) { - output.setPixel(x,y, qRgba( - (qRed(output.pixel(x-1,y)) + qRed(output.pixel(x+1,y)))/2, - (qGreen(output.pixel(x-1,y)) + qGreen(output.pixel(x+1,y)))/2, - (qBlue(output.pixel(x-1,y)) + qBlue(output.pixel(x+1,y)))/2, - (qAlpha(output.pixel(x-1,y)) + qAlpha(output.pixel(x+1,y)))/2 - )); - } - } - } - for (int x = 0; x < prev.width(); x++) { - for (int y = 1; y < prev.height()-1; y++) { - if (qAlpha(output.pixel(x,y)) == 0 - && qAlpha(output.pixel(x,y-1)) > 0 - && qAlpha(output.pixel(x,y+1)) > 0) { - output.setPixel(x,y, qRgba( - (qRed(output.pixel(x,y-1)) + qRed(output.pixel(x,y+1)))/2, - (qGreen(output.pixel(x,y-1)) + qGreen(output.pixel(x,y+1)))/2, - (qBlue(output.pixel(x,y-1)) + qBlue(output.pixel(x,y+1)))/2, - (qAlpha(output.pixel(x,y-1)) + qAlpha(output.pixel(x,y+1)))/2 - )); - } - } - } - */ -}
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/lib/interpolate_sV.h
Deleted
@@ -1,69 +0,0 @@ -/* -slowmoVideo creates slow-motion videos from normal-speed videos. -Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. -*/ - -#include <QtGui/QColor> - -class QImage; -class FlowField_sV; - -/** - \short Provides interpolation methods between frames - \todo Half resolution for optical flow - */ -class Interpolate_sV { - - public: - /** \fn forwardFlow() - Interpolates a frame using only the flow from the first to the second frame. - This algorithm is simplified and only partly correct since it assumes the flow field - to tell where a pixel came from and not where it went to, which usually leads to artifacts - like on object boundaries or like objects that do not move as far as they should, - but is much easier to interpolate. - */ - /** \fn newForwardFlow - Like forwardFlow(), but uses the forward flow correctly. This includes more work like - filling holes if an object expanded (a pixel then becomes larger, or «multiplies», which cannot - be expressed with usual optical flow (<em>where did the pixel go to?</em> cannot be answered - since it went to multiple locations). The benefit is that this algorithm works more precisely. - */ - /** \fn twowayFlow() - Interpolates a frame using optical flow from the first to the second frame, as well as from the second to the first frame. - */ - /** \fn newTwowayFlow() - Like twowayFlow(), but uses forward and backward flow correctly. See also newForwardFlow(). - */ - /** - \fn interpolate(const QImage &in, float x, float y) - \brief Interpolates the colour at position <code>(x|y)</code>. - - \c x should fulfil \f$ 0 \leq x < width-1 \f$, same with y, to avoid reading outside the image. - Not tested inside the function for efficiency reasons. - */ - static void forwardFlow(const QImage& left, const FlowField_sV *flow, float pos, QImage& output); - static void newForwardFlow(const QImage& left, const FlowField_sV *flow, float pos, QImage& output); - static void twowayFlow(const QImage& left, const QImage& right, const FlowField_sV *flowForward, const FlowField_sV *flowBackward, float pos, QImage& output); - static void newTwowayFlow(const QImage &left, const QImage &right, const FlowField_sV *flowLeftRight, const FlowField_sV *flowRightLeft, float pos, QImage &output); - static void bezierFlow(const QImage& left, const QImage& right, const FlowField_sV *flowCurrPrev, const FlowField_sV *flowCurrNext, float pos, QImage &output); - static QColor interpolate(const QImage& in, float x, float y); - - -private: - struct Movement { - float moveX; - float moveY; - }; - struct ColorMatrix4x4 { - QColor c00, c10, c01, c11; - }; - - static void blend(ColorMatrix4x4& colors, const QColor &blendCol, float posX, float posY); - static QColor blend(const QColor& left, const QColor& right, float pos); - -};
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/lib/shutter_sV.cpp
Deleted
@@ -1,171 +0,0 @@ -/* -slowmoVideo creates slow-motion videos from normal-speed videos. -Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. -*/ - -#include "flowField_sV.h" -#include "sourceField_sV.h" -#include "interpolate_sV.h" -#include "intMatrix_sV.h" -#include "shutter_sV.h" - -#include <QtCore/QStringList> -#include <QtCore/QDebug> - -#include <algorithm> -#include <cmath> - - -#define CLAMP(x,min,max) ( ((x) < (min)) ? (min) : ( ((x) > (max)) ? (max) : (x) ) ) - -#define MIN_DIST 0.01 - - -QImage Shutter_sV::combine(const QStringList images) -{ - Q_ASSERT(images.size() > 0); - - QImage img(images.at(0)); - IntMatrix_sV matrix(img.width(), img.height(), 4); - for (int i = 0; i < images.size(); i++) { - img = QImage(images.at(i)); - matrix += img.bits(); - } - matrix /= images.size(); - - unsigned char *bytes = matrix.toBytesArray(); - QImage result(matrix.width(), matrix.height(), QImage::Format_ARGB32); - std::copy(bytes, bytes+matrix.width()*matrix.height()*matrix.channels()+1, result.bits()); - delete bytes; - - return result; -} - -QImage Shutter_sV::combine(const QList<QImage> images) -{ - Q_ASSERT(images.size() > 0); - - IntMatrix_sV matrix(images.at(0).width(), images.at(0).height(), 4); - for (int i = 0; i < images.size(); i++) { - matrix += images.at(i).bits(); - } - matrix /= images.size(); - - unsigned char *bytes = matrix.toBytesArray(); - QImage result(matrix.width(), matrix.height(), QImage::Format_ARGB32); - std::copy(bytes, bytes+matrix.width()*matrix.height()*matrix.channels()+1, result.bits()); - delete bytes; - - return result; -} - -QImage Shutter_sV::convolutionBlur(const QImage source, const FlowField_sV *flow, float length) -{ - Q_ASSERT(source.width() == flow->width()); - Q_ASSERT(source.height() == flow->height()); - - const float Wmax = source.width()-1.001; - const float Hmax = source.height()-1.001; - - QImage blurred(source.size(), source.format()); - ColorStack stack; - float dx, dy; - float xf, yf; - int samples, inc; - for (int y = 0; y < source.height(); y++) { - for (int x = 0; x < source.width(); x++) { - stack = ColorStack(); - dx = length * flow->x(x,y); - dy = length * flow->y(x,y); - dx = CLAMP(x+dx, 0.0, Wmax)-x; - dy = CLAMP(y+dy, 0.0, Hmax)-y; - - samples = ceil(std::sqrt(dx*dx + dy*dy)); - if (samples < 1) { - samples = 1; - } - inc = std::max(1, samples/20); // Lower inc value leads to a smoother result - - xf = CLAMP(x, 0.0, Wmax); - yf = CLAMP(y, 0.0, Hmax); - stack.add(source.pixel(x,y)); // Avoids interpolation error, and interpolation for (x,y) is not necessary anyway - for (int i = 1; i <= samples; i += inc) { - // \todo adjust increment - stack.add(Interpolate_sV::interpolate(source, xf+float(i)/samples * dx, yf+float(i)/samples * dy)); - } - blurred.setPixel(x, y, stack.col().rgba()); - } - } - return blurred; -} - -QImage Shutter_sV::convolutionBlur(const QImage interpolatedAtOffset, const FlowField_sV *flow, float length, float offset) -{ - Q_ASSERT(interpolatedAtOffset.width() == flow->width()); - Q_ASSERT(interpolatedAtOffset.height() == flow->height()); - Q_ASSERT(offset > 0); - Q_ASSERT(offset < 1); - - SourceField_sV source(flow, offset); - source.inpaint(); - - const float Wmax = interpolatedAtOffset.width()-1.01; - const float Hmax = interpolatedAtOffset.height()-1.01; - - QImage blurred(interpolatedAtOffset.size(), interpolatedAtOffset.format()); - ColorStack stack; - float dx, dy; - float xf, yf; - int samples, inc; - for (int y = 0; y < interpolatedAtOffset.height(); y++) { - for (int x = 0; x < interpolatedAtOffset.width(); x++) { - stack = ColorStack(); - dx = -(source.at(x,y).fromX - x); // Get the optical flow vector back from the source field - dy = -(source.at(x,y).fromY - y); - dx = dx/offset * length; // First normalize to one frame, then adjust the length - dy = dy/offset * length; - dx = CLAMP(x+dx, 0.0, Wmax)-x; - dy = CLAMP(y+dy, 0.0, Hmax)-y; - - samples = ceil(std::sqrt(dx*dx + dy*dy)); - if (samples < 1) { - samples = 1; - } - inc = std::max(1, samples/20); - - xf = CLAMP(x, 0.0, Wmax); - yf = CLAMP(y, 0.0, Hmax); - stack.add(interpolatedAtOffset.pixel(x,y)); // Avoids interpolation error, and interpolation for (x,y) is not necessary anyway - for (int i = 1; i <= samples; i += inc) { - // \todo adjust increment - stack.add(Interpolate_sV::interpolate(interpolatedAtOffset, xf+float(i)/samples * dx, yf+float(i)/samples * dy)); - } - blurred.setPixel(x, y, stack.col().rgba()); - } - } - return blurred; - -} - -Shutter_sV::ColorStack::ColorStack() : - r(0), g(0), b(0), a(0), count(0) -{} - -void Shutter_sV::ColorStack::add(QColor col) -{ - r += col.redF(); - g += col.greenF(); - b += col.blueF(); - a += col.alphaF(); - ++count; -} - -QColor Shutter_sV::ColorStack::col() -{ - return QColor::fromRgbF(r/count, g/count, b/count, a/count); -}
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/lib/videoInfo_sV.c
Deleted
@@ -1,99 +0,0 @@ -/* -slowmoVideo creates slow-motion videos from normal-speed videos. -Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. -*/ - -// LibAV docs: http://libav.org/doxygen/master/avformat_8h.html -// Tutorial: http://dranger.com/ffmpeg/tutorial01.html - -#include "videoInfo_sV.h" - -#include <libavcodec/avcodec.h> -#include <libavformat/avformat.h> - -VideoInfoSV getInfo(const char filename) -{ - VideoInfoSV info; - info.frameRateNum = 0; - info.frameRateDen = 0; - info.streamsCount = 0; - info.framesCount = 0; - - av_register_all(); -#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(53,19,0) - avformat_network_init(); -#endif - - AVFormatContext *pFormatContext = NULL; - - printf("Reading info for file %s.\n", filename); - fflush(stdout); - - int ret; -#if LIBAVFORMAT_VERSION_MAJOR < 53 - if ((ret = av_open_input_file(&pFormatContext, filename, NULL, 0, NULL)) != 0) { -#else - if ((ret = avformat_open_input(&pFormatContext, filename, NULL, NULL)) != 0) { -#endif - printf("Could not open file %s.\n", filename); - avformat_close_input(&pFormatContext); -#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(53,19,0) - avformat_network_deinit(); -#endif - return info; - } -#if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(53,9,0) - if (av_find_stream_info(pFormatContext) < 0) { -#else - if (avformat_find_stream_info(pFormatContext, NULL) < 0) { -#endif - printf("No stream information found.\n"); - avformat_close_input(&pFormatContext); -#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(53,19,0) - avformat_network_deinit(); -#endif - return info; - } -#if LIBAVFORMAT_VERSION_MAJOR < 53 - dump_format(pFormatContext, 0, filename, 0); -#else - av_dump_format(pFormatContext, 0, filename, 0); -#endif - - AVCodecContext *pCodecContext; - int videoStream = -1; - for (int i = 0; i < pFormatContext->nb_streams; i++) { -#if LIBAVCODEC_VERSION_INT < (52<<16 | 64<<8 | 0) - if (pFormatContext->streamsi->codec->codec_type == CODEC_TYPE_VIDEO) { -#else - if (pFormatContext->streamsi->codec->codec_type == AVMEDIA_TYPE_VIDEO) { -#endif - videoStream = i; - pCodecContext = pFormatContext->streamsi->codec; - AVRational fps = pFormatContext->streamsi->r_frame_rate; - printf("Frame rate: %d/%d = %f\n", fps.num, fps.den, (float)fps.num / fps.den); - info.frameRateNum = fps.num; - info.frameRateDen = fps.den; - info.width = pCodecContext->width; - info.height = pCodecContext->height; - // info.framesCount = pFormatContext->streamsi->nb_frames; // Doesn't work for each format. - AVRational tb = pFormatContext->streamsi->time_base; // Use the precise timebase of this stream. - info.framesCount = (long)( (double)fps.num/fps.den * pFormatContext->streamsi->duration * (double)tb.num/tb.den ); // Works really good for any type of video. - info.streamsCount++; - printf("Total frames: %ld (Length: %f s)\n", info.framesCount, info.framesCount/((float)fps.num/fps.den)); - } - } - - avformat_close_input(&pFormatContext); - // av_free(pFormatContext); -#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(53,19,0) - avformat_network_deinit(); -#endif - return info; -} -
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/libgui
Deleted
-(directory)
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/libgui/CMakeLists.txt
Deleted
@@ -1,21 +0,0 @@ -set(SRCS - imageDisplay.cpp - combinedShortcuts.cpp -) - -set(SRCS_MOC - imageDisplay.h - combinedShortcuts.h -) - - -qt4_wrap_cpp(MOC_OUT ${SRCS_MOC}) - - -include_directories(${CMAKE_BINARY_DIR}/libgui) - -add_library(sVgui STATIC ${SRCS} ${MOC_OUT}) -target_link_libraries(sVgui ${EXTERNAL_LIBS}) - -# If the library is used in a different project, cmake requires: -#include_directories(${slowmoVideo_SOURCE_DIR}/libgui)
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/libgui/combinedShortcuts.cpp
Deleted
@@ -1,143 +0,0 @@ -/* -This file is part of slowmoVideo. -Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. -*/ - -#include "combinedShortcuts.h" - -#include <QtGui/QShortcut> - -#define DEBUG -#include <QDebug> - -CombinedShortcuts::CombinedShortcuts(QWidget *parent) : - m_parent(parent), - m_signalMapper(parent) -{ - bool b = true; - b &= connect(&m_signalMapper, SIGNAL(mapped(QString)), this, SLOT(slotShortcutUsed(QString))); - Q_ASSERT(b); -} -CombinedShortcuts::~CombinedShortcuts() -{ - for (int i = 0; i < m_qShortcuts.size(); i++) { - delete m_qShortcuts.at(i); - } -} - -QString CombinedShortcuts::shortcutList() const -{ - QStringList shortcuts; - for (int i = 0; i < m_shortcuts.size(); i++) { - shortcuts << m_shortcuts.at(i).shortcut - + "\t" + - m_shortcuts.at(i).desc; - } - return shortcuts.join("\n"); -} - -void CombinedShortcuts::addShortcut(QString shortcut, int id, QString description) -{ - for (int i = 0; i < m_shortcuts.size(); i++) { - if (m_shortcuts.at(i).shortcut == shortcut) { - qDebug() << "Shortcut " << shortcut << " is not unique, used for " - << description << " and " << m_shortcuts.at(i).desc; - Q_ASSERT(false); - return; - } - } - if (shortcut.length() == 1) { - addShortcutKey(shortcut); - m_shortcuts << ShortcutItem(id, shortcut, description); - - } else if (shortcut.length() == 3 && shortcut.at(1) == '-') { - addShortcutKey(shortcut.at(0)); - addShortcutKey(shortcut.at(2)); - m_shortcuts << ShortcutItem(id, shortcut, description); - - } else { - qDebug() << "Cannot add shortcut " << shortcut << ", format not supported."; - Q_ASSERT(false); - } -} - -void CombinedShortcuts::addShortcutKey(QString key) -{ - if (!m_uniqueKeys.contains(key)) { -#ifdef DEBUG - qDebug() << "Adding unique key " << key; -#endif - m_uniqueKeys << key; - - // Create a new shortcut for each unique key - QShortcut *qshortcut = new QShortcut(QKeySequence(key), m_parent); - m_qShortcuts << qshortcut; - - m_signalMapper.setMapping(qshortcut, key); - - // Connect shortcut to the signal mapper - bool b = connect(qshortcut, SIGNAL(activated()), &m_signalMapper, SLOT(map())); - Q_ASSERT(b); - } -} - -void CombinedShortcuts::slotShortcutUsed(QString key) -{ - - TimedShortcut ts; - ts.shortcut = key; - ts.start = QTime::currentTime(); - -#ifdef DEBUG - qDebug() << key << " pressed. Last shortcut: " << m_previousKey.start.elapsed() << " ms ago."; -#endif - -// QString at = QString(" @ %1.%2::%3") -// .arg(ts.start.minute()) -// .arg(ts.start.second()) -// .arg(ts.start.msec()); - - bool handled = false; - - // Use a timeout. Otherwise pressing a key may lead to unpredictable results - // since it may depend on the key you pressed several minutes ago. - if (m_previousKey.start.elapsed() < 600) { - - QString combinedShortcut = QString("%1-%2").arg(m_previousKey.shortcut).arg(key); - - for (int i = 0; i < m_shortcuts.size(); i++) { - if (m_shortcuts.at(i).shortcut == combinedShortcut) { -#ifdef DEBUG - qDebug() << QString("Shortcut %1 (%2) has been triggered!") - .arg(m_shortcuts.at(i).shortcut) - .arg(m_shortcuts.at(i).desc); -#endif - emit signalShortcutUsed(m_shortcuts.at(i).id); - handled = true; - break; - } - } - - } - if (!handled) { - // The key pressed did not belong to a combined shortcut. - // Check if there is a shortcut with a single key for it. - - for (int i = 0; i < m_shortcuts.size(); i++) { - if (m_shortcuts.at(i).shortcut == key) { - emit signalShortcutUsed(m_shortcuts.at(i).id); - handled = true; - break; - } - } - } - - if (!handled) { - m_previousKey = ts; - } -}
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/libgui/combinedShortcuts.h
Deleted
@@ -1,76 +0,0 @@ -/* -This file is part of slowmoVideo. -Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. -*/ - -#ifndef COMBINEDSHORTCUTS_H -#define COMBINEDSHORTCUTS_H - -#include <QtCore/QList> -#include <QtCore/QMap> -#include <QtCore/QSignalMapper> -#include <QtCore/QTime> -#include <QtGui/QWidget> - -class QShortcut; - -/** - \brief Manager for combined shortcuts (known from GMail) - - Combined shortcuts are for example <code>s-a</code> or \c q; the former one - is triggered when the user presses \c s and within a limited amount of time \c a. - */ -class CombinedShortcuts : public QObject -{ - Q_OBJECT -public: - CombinedShortcuts(QWidget *parent); - ~CombinedShortcuts(); - - /// Adds the given shortcut if it does not exist yet - void addShortcut(QString shortcut, int id, QString description); - - /// Returns a list of the available shortcuts that have been added - QString shortcutList() const; - - -signals: - /// Emitted when the shortcut has been used - void signalShortcutUsed(int id); - -private: - struct ShortcutItem { - ShortcutItem(int id, QString shortcut, QString desc) : - id(id), - shortcut(shortcut), - desc(desc) {} - int id; - QString shortcut; - QString desc; - }; - struct TimedShortcut { - QTime start; - QString shortcut; - }; - - QList<ShortcutItem> m_shortcuts; - QList<QString> m_uniqueKeys; - QList<QShortcut*> m_qShortcuts; - TimedShortcut m_previousKey; - - QWidget *m_parent; - QSignalMapper m_signalMapper; - - void addShortcutKey(QString key); - - -private slots: - void slotShortcutUsed(QString key); -}; - -#endif // COMBINEDSHORTCUTS_H
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/libgui/imageDisplay.cpp
Deleted
@@ -1,289 +0,0 @@ -/* -This file is part of slowmoVideo. -Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. -*/ - -#include "imageDisplay.h" -#include <QtCore/QDebug> -#include <QtGui/QPainter> -#include <QtGui/QMenu> -#include <QtGui/QFileDialog> -#include <QtGui/QContextMenuEvent> - -#include <QApplication> -#include <QtCore/QSettings> -#include <QtCore/QFileInfo> - -#include <cmath> - -ImageDisplay::ImageDisplay(QWidget *parent, Qt::WindowFlags f) : - QFrame(parent, f), - m_scale(1) -{ - m_aScaling = new QAction(tr("Scale image to widget size"), this); - m_aScaling->setCheckable(true); - m_aScaling->setChecked(true); - - m_aExportImage = new QAction(tr("Export image"), this); - - bool b = true; - b &= connect(m_aScaling, SIGNAL(triggered()), this, SLOT(repaint())); - b &= connect(m_aExportImage, SIGNAL(triggered()), this, SLOT(slotExportImage())); - Q_ASSERT(b); - - setContentsMargins(5, 5, 5, 5); - - m_states.mouseInitialImagePos = QPointF(0.0,0.0); - m_states.mousePrevPos = QPoint(0,0); - m_states.manhattan = 0; -} -ImageDisplay::~ImageDisplay() -{ - delete m_aScaling; -} - -void ImageDisplay::trackMouse(bool track) -{ - setMouseTracking(track); -} - -void ImageDisplay::loadImage(const QImage img) -{ - if (!img.isNull()) { - m_image = img; - } -} -const QImage& ImageDisplay::image() const -{ - return m_image; -} - -bool ImageDisplay::loadOverlay(const QImage img) -{ - if (img.size() != m_image.size()) { - return false; - } - m_overlay = img; - return true; -} -void ImageDisplay::clearOverlay() -{ - m_overlay = QImage(); -} - -void ImageDisplay::contextMenuEvent(QContextMenuEvent *e) -{ - QMenu menu; - menu.addAction(m_aScaling); - menu.addAction(m_aExportImage); - m_aExportImage->setEnabled(!m_image.isNull()); - menu.exec(e->globalPos()); -} - - -QPointF ImageDisplay::convertCanvasToPixel(QPoint p) const -{ - float scale = m_scale; - if (m_aScaling->isChecked()) { - scale = m_scaledImageSize.width()/float(m_image.width()); - } - return (p - contentsRect().topLeft())/scale; -} -QPointF ImageDisplay::convertCanvasToImage(QPoint p) const -{ - if (!m_aScaling->isChecked()) { - return m_imageOffset + convertCanvasToPixel(p); - } else { - return convertCanvasToPixel(p); - } -} -QPoint ImageDisplay::convertImageToPixel(QPointF p) const -{ - float scale = m_scale; - if (m_aScaling->isChecked()) { - scale = m_scaledImageSize.width()/float(m_image.width()); - } - return (p*scale + QPointF(contentsRect().topLeft())).toPoint(); -} -QPoint ImageDisplay::convertImageToCanvas(QPointF p) const -{ - if (!m_aScaling->isChecked()) { - return convertImageToPixel(p - m_imageOffset); - } else { - return convertImageToPixel(p); - } - -} - -void ImageDisplay::mousePressEvent(QMouseEvent *e) -{ - m_states.mouseInitialImagePos = convertCanvasToImage(e->pos()); - m_states.mousePrevPos = e->pos(); - m_states.manhattan = 0; -} - -void ImageDisplay::mouseMoveEvent(QMouseEvent *e) -{ - if (e->buttons().testFlag(Qt::LeftButton)) { - m_states.manhattan += (e->pos()-m_states.mousePrevPos).manhattanLength(); - } - m_states.mousePrevPos = e->pos(); - - if (!m_aScaling->isChecked()) { -#if QT_VERSION < 0x040700 - if (e->buttons().testFlag(Qt::MidButton)) { -#else - if (e->buttons().testFlag(Qt::MiddleButton)) { -#endif - // Move the viewport - QPointF offset = m_states.mouseInitialImagePos - convertCanvasToPixel(e->pos()); - m_imageOffset = offset; - repaint(); - } - } - - if (hasMouseTracking() && !m_image.isNull()) { - int x = e->pos().x() - contentsRect().x(); - int y = e->pos().y() - contentsRect().y(); - if (x < 0 || y < 0 || x >= contentsRect().width() || y >= contentsRect().height()) { -// qDebug() << "Not inside drawing boundaries."; - return; - } - QPointF pos = convertCanvasToImage(e->pos()); - emit signalMouseMoved(pos.x(), pos.y()); - } - repaint(); -} -void ImageDisplay::mouseReleaseEvent(QMouseEvent *e) -{ - QPointF p0 = m_states.mouseInitialImagePos; - QPointF releasePos = convertCanvasToImage(e->pos()); - - QPointF minPoint = min(p0, releasePos, true); - QPointF maxPoint = max(p0, releasePos, true); - - qDebug() << p0 << releasePos << minPoint << maxPoint; - QRectF mouseRect(minPoint, maxPoint); - - - if (m_states.countsAsMove()) { - emit signalRectDrawn(mouseRect); - } -} - -void ImageDisplay::wheelEvent(QWheelEvent *e) -{ - if (!m_aScaling->isChecked()) { - QPointF mouseOffset = convertCanvasToImage(e->pos()); - if (e->delta() > 0) { - if (m_scale < 20) { - m_scale *= 1.4; - } - } else { - if (m_scale > float(contentsRect().width())/(2*m_image.width())) { - m_scale /= 1.4; - } - } - m_imageOffset = mouseOffset - (e->pos()-contentsRect().topLeft())/m_scale; - repaint(); - } -} - - -void ImageDisplay::paintEvent(QPaintEvent *e) -{ - QFrame::paintEvent(e); - if (!m_image.isNull()) { - QPainter p(this); - - QImage subImg; - if (m_aScaling->isChecked()) { - - // Scale to frame size - subImg = m_image.scaled(contentsRect().size(), Qt::KeepAspectRatio); - m_scaledImageSize = subImg.size(); - - } else { - - // User-defined scaling - subImg = m_image.copy(std::floor(m_imageOffset.x()), std::floor(m_imageOffset.y()), - std::ceil(contentsRect().width()/m_scale+1), std::ceil(contentsRect().height()/m_scale+1)); - subImg = subImg.scaled(m_scale*subImg.size(), Qt::KeepAspectRatio, Qt::SmoothTransformation); - subImg = subImg.copy(m_scale*(m_imageOffset.x()-floor(m_imageOffset.x())), - m_scale*(m_imageOffset.y()-floor(m_imageOffset.y())), - contentsRect().width(), - contentsRect().height()); - } - - p.drawImage(contentsRect().topLeft(), subImg); - - if (m_states.countsAsMove() && !QApplication::mouseButtons().testFlag(Qt::NoButton)) { - QRect r; - QPoint origin = convertImageToCanvas(m_states.mouseInitialImagePos); - - r.setTopLeft(min(m_states.mousePrevPos, origin)); - r.setWidth(abs(m_states.mousePrevPos.x()-origin.x())); - r.setHeight(abs(m_states.mousePrevPos.y()-origin.y())); - - p.drawRect(r); - } - - } -} - -void ImageDisplay::slotExportImage() -{ - Q_ASSERT(!m_image.isNull()); - - QSettings settings; - - QFileDialog dialog(this, tr("Export render preview to image")); - dialog.setAcceptMode(QFileDialog::AcceptSave); - dialog.setFileMode(QFileDialog::AnyFile); - dialog.setDirectory(settings.value("directories/imageDisplay", QDir::homePath()).toString()); - if (dialog.exec() == QDialog::Accepted) { - m_image.save(dialog.selectedFiles().at(0)); - settings.setValue("directories/imageDisplay", QFileInfo(dialog.selectedFiles().at(0)).absolutePath()); - } -} - - - - -qreal ImageDisplay::clamp(qreal val, qreal min, qreal max) const -{ - return (val < min) ? min : ( (val > max) ? max : val ); -} -QPointF ImageDisplay::max(QPointF p1, QPointF p2, bool limitToImage) const -{ - QPointF p(qMax(p1.x(), p2.x()), qMax(p1.y(), p2.y())); - if (limitToImage) { - p.rx() = clamp(p.x(), 0, m_image.width()-1); - p.ry() = clamp(p.y(), 0, m_image.height()-1); - } - return p; -} - -QPointF ImageDisplay::min(QPointF p1, QPointF p2, bool limitToImage) const -{ - QPointF p(qMin(p1.x(), p2.x()), qMin(p1.y(), p2.y())); - if (limitToImage) { - p.rx() = clamp(p.x(), 0, m_image.width()-1); - p.ry() = clamp(p.y(), 0, m_image.height()-1); - } - return p; -} - -QPoint ImageDisplay::min(QPoint p1, QPoint p2) const -{ - return QPoint(qMin(p1.x(), p2.x()), qMin(p1.y(), p2.y())); -} -QPoint ImageDisplay::max(QPoint p1, QPoint p2) const -{ - return QPoint(qMax(p1.x(), p2.x()), qMax(p1.y(), p2.y())); -}
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/libgui/imageDisplay.h
Deleted
@@ -1,96 +0,0 @@ -/* -This file is part of slowmoVideo. -Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. -*/ - -#ifndef IMAGEDISPLAY_H -#define IMAGEDISPLAY_H - -#include <QFrame> -#include <QtCore/QRect> - -/** - \brief Simple image display. - - Images can be scaled to the frame size and exported to a file - via the context menu. - */ -class ImageDisplay : public QFrame -{ - Q_OBJECT -public: - explicit ImageDisplay(QWidget *parent = 0, Qt::WindowFlags f = 0); - ~ImageDisplay(); - - void trackMouse(bool track); - - /// \return The image that is currently displayed - const QImage& image() const; - -public slots: - /// Loads the given image; does \em not call repaint()! - void loadImage(const QImage img); - /// Loads the overlay that will be painted over the image; does \em not call repaint() either. - /// \return \c false if the image sizes do not match - bool loadOverlay(const QImage img); - void clearOverlay(); - -signals: - void signalMouseMoved(float x, float y); - void signalRectDrawn(QRectF imageRect); - -protected slots: - virtual void paintEvent(QPaintEvent *e); - virtual void contextMenuEvent(QContextMenuEvent *e); - virtual void mousePressEvent(QMouseEvent *e); - virtual void mouseMoveEvent(QMouseEvent *e); - virtual void mouseReleaseEvent(QMouseEvent *e); - virtual void wheelEvent(QWheelEvent *e); - -private: - QImage m_image; - QImage m_overlay; - - QAction *m_aScaling; - QAction *m_aExportImage; - - float m_scale; - QPointF m_imageOffset; - QSize m_scaledImageSize; - - struct { - QPointF mouseInitialImagePos; - - QPoint mousePrevPos; - - int manhattan; - - bool countsAsMove() { return manhattan > 4; } - - } m_states; - - /// Convert canvas coordinates to image coordinates. - /// The image may have an offset. - QPointF convertCanvasToImage(QPoint p) const; - /// Convert canvas coordinates to pixel coordinates (ignores the image offset) - QPointF convertCanvasToPixel(QPoint p) const; - QPoint convertImageToCanvas(QPointF p) const; - QPoint convertImageToPixel(QPointF p) const; - - qreal clamp(qreal val, qreal min, qreal max) const; - QPointF max(QPointF p1, QPointF p2, bool limitToImage) const; - QPointF min(QPointF p1, QPointF p2, bool limitToImage) const; - QPoint min(QPoint p1, QPoint p2) const; - QPoint max(QPoint p1, QPoint p2) const; - -private slots: - void slotExportImage(); - -}; - -#endif // IMAGEDISPLAY_H
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/project
Deleted
-(directory)
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/project/CMakeLists.txt
Deleted
@@ -1,43 +0,0 @@ -set(SRCS_PROJ - project_sV.cpp - projectPreferences_sV.cpp - renderPreferences_sV.cpp - tag_sV.cpp - node_sV.cpp - nodeList_sV.cpp - segment_sV.cpp - segmentList_sV.cpp - nodeHandle_sV.cpp - renderTask_sV.cpp - xmlProjectRW_sV.cpp - abstractFrameSource_sV.cpp - imagesFrameSource_sV.cpp - videoFrameSource_sV.cpp - emptyFrameSource_sV.cpp - abstractRenderTarget_sV.cpp - imagesRenderTarget_sV.cpp - videoRenderTarget_sV.cpp - abstractFlowSource_sV.cpp - flowSourceOpenCV_sV.cpp - flowSourceV3D_sV.cpp - interpolator_sV.cpp - shutterFunction_sV.cpp - shutterFunctionList_sV.cpp - motionBlur_sV.cpp - canvasObject_sV.h -) - -set(SRCS_MOC - project_sV.h - renderTask_sV.h - abstractFrameSource_sV.h - imagesFrameSource_sV.h - videoFrameSource_sV.h - emptyFrameSource_sV.h -) - -qt4_wrap_cpp(MOC_OUT ${SRCS_MOC}) - -include_directories(${FFMPEG_INCLUDE_PATHS}) -add_library(sVproj STATIC ${SRCS_PROJ} ${MOC_OUT}) -target_link_libraries(sVproj sV sVinfo sVflow sVencode ${EXTERNAL_LIBS})
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/project/abstractFlowSource_sV.cpp
Deleted
@@ -1,21 +0,0 @@ -/* -This file is part of slowmoVideo. -Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. -*/ - -#include "abstractFlowSource_sV.h" - -AbstractFlowSource_sV::AbstractFlowSource_sV(Project_sV *project) : - m_project(project) -{ -} - -Project_sV* AbstractFlowSource_sV::project() -{ - return m_project; -}
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/project/abstractFlowSource_sV.h
Deleted
@@ -1,45 +0,0 @@ -/* -This file is part of slowmoVideo. -Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. -*/ - -#ifndef ABSTRACTFLOWSOURCE_SV_H -#define ABSTRACTFLOWSOURCE_SV_H - -#include "../lib/defs_sV.hpp" - -class Project_sV; -class FlowField_sV; - -class AbstractFlowSource_sV -{ -public: - AbstractFlowSource_sV(Project_sV *project); - virtual ~AbstractFlowSource_sV() {} - - /** \return The flow field from \c leftFrame to \c rightFrame */ - virtual FlowField_sV* buildFlow(uint leftFrame, uint rightFrame, FrameSize frameSize) throw(FlowBuildingError) = 0; - /** \return The path to the flow file for the given frames */ - virtual const QString flowPath(const uint leftFrame, const uint rightFrame, const FrameSize frameSize = FrameSize_Orig) const = 0; - -public slots: - /** - \fn slotUpdateProjectDir() - Informs the flow source that the project directory has changed. If the flow source created sub-directories - in the old project directories, it can e.g. delete them and create them at the new place. - */ - virtual void slotUpdateProjectDir() = 0; - -protected: - Project_sV* project(); - -private: - Project_sV *m_project; -}; - -#endif // ABSTRACTFLOWSOURCE_SV_H
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/project/abstractFrameSource_sV.cpp
Deleted
@@ -1,26 +0,0 @@ -/* -This file is part of slowmoVideo. -Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. -*/ - -#include "abstractFrameSource_sV.h" - -AbstractFrameSource_sV::AbstractFrameSource_sV(const Project_sV *project) : - m_project(project) -{ -} - -AbstractFrameSource_sV::~AbstractFrameSource_sV() -{ - -} - -double AbstractFrameSource_sV::maxTime() const throw(Div0Exception) -{ - return (framesCount()-1)/fps()->fps(); -}
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/project/abstractFrameSource_sV.h
Deleted
@@ -1,111 +0,0 @@ -/* -This file is part of slowmoVideo. -Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. -*/ - -#ifndef ABSTRACTFRAMESOURCE_SV_H -#define ABSTRACTFRAMESOURCE_SV_H - -#include "../lib/defs_sV.hpp" - -#include <QImage> -#include <QtCore/QDir> - -class Project_sV; - -class Div0Exception {}; - -/** \brief Represents a source for input frames, like a video or an image sequence */ -class AbstractFrameSource_sV : public QObject -{ - Q_OBJECT -public: - AbstractFrameSource_sV(const Project_sV *project); - virtual ~AbstractFrameSource_sV(); - - const Project_sV* project() { return m_project; } - - /** - \fn initialize() - Initializes the frame source (like extracting frames from a video). - When re-implementing this method, the parent function must be called in order for - initialized() to work. - \see signalNextTask() and the other signals - */ - /** - \fn initialized() - \return \c true, if the frame source has been initialized. - */ - virtual void initialize() = 0; - virtual bool initialized() const = 0; - - /** - \fn framesCount() - \return Number of frames in this frame source - */ - virtual int64_t framesCount() const = 0; - virtual const Fps_sV* fps() const = 0; - double maxTime() const throw(Div0Exception); - - /** - \fn frameAt() - \return The frame at the given position, as image. Fails - if the frames have not been extracted yet. - */ - /** - \fn framePath() - \return The path to the frame at position \c frame - */ - virtual QImage frameAt(const uint frame, const FrameSize frameSize = FrameSize_Orig) = 0; - virtual const QString framePath(const uint frame, const FrameSize frameSize = FrameSize_Orig) const = 0; - -signals: - /** - \fn void signalNextTask(const QString taskDescription, int taskSize) - A new task has been started, like extracting frames from a video when loading a new frame source. - \param taskSize Number of task items in this task (e.g. number of frames to extract from a video file) - */ - /** - \fn void signalTaskProgress(int progress) - The current task has made progress. - \param progress Task item that has been completed. Should be smaller than taskSize given in signalNextTask(). - */ - /** - \fn void signalTaskItemDescription(const QString desc) - \param desc Description for the current task (like the file name of an extracted frame) - */ - /** - \fn void signalAllTasksFinished() - All due tasks have been completed. - */ - void signalNextTask(const QString taskDescription, int taskSize); - void signalTaskProgress(int progress); - void signalTaskItemDescription(const QString desc); - void signalAllTasksFinished(); - -public slots: - /** - \fn slotAbortInitialization() - Should abort the initialization of the frame source since this might take a long time - (e.g. extracting large frames from a long video, or re-sizing lots of frames). - */ - /** - \fn slotUpdateProjectDir() - Informs the frame source that the project directory has changed. If the frame source created sub-directories - in the old project directories, it can e.g. delete them and create them at the new place. - */ - virtual void slotAbortInitialization() = 0; - virtual void slotUpdateProjectDir() = 0; - -protected: - const Project_sV *m_project; - -}; - - -#endif // ABSTRACTFRAMESOURCE_SV_H
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/project/abstractRenderTarget_sV.h
Deleted
@@ -1,42 +0,0 @@ -/* -This file is part of slowmoVideo. -Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. -*/ - -#ifndef ABSTRACTRENDERTARGET_SV_H -#define ABSTRACTRENDERTARGET_SV_H - -#include <QtGui/QImage> -#include "../lib/defs_sV.hpp" - -class RenderTask_sV; - -/** \brief Should represent a render target like video or an image sequence */ -class AbstractRenderTarget_sV -{ -public: - AbstractRenderTarget_sV(RenderTask_sV *parentRenderTask); - virtual ~AbstractRenderTarget_sV(); - - RenderTask_sV* renderTask() { return m_renderTask; } - - /// Prepares the render target (if necessary), like initializing video streams etc. - virtual void openRenderTarget() throw(Error_sV) {} - /// Finishes the render target (e.g. writes the trailer to a video file) - virtual void closeRenderTarget() throw(Error_sV) {} - -public slots: - /// Adds one frame to the output - virtual void slotConsumeFrame(const QImage &image, const int frameNumber) = 0; - -private: - RenderTask_sV *m_renderTask; - -}; - -#endif // ABSTRACTRENDERTARGET_SV_H
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/project/emptyFrameSource_sV.h
Deleted
@@ -1,42 +0,0 @@ -/* -This file is part of slowmoVideo. -Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. -*/ - -#ifndef EMPTYFRAMESOURCE_H -#define EMPTYFRAMESOURCE_H - -#include "abstractFrameSource_sV.h" - -class EmptyFrameSource_sV : public AbstractFrameSource_sV -{ - Q_OBJECT - -public: - EmptyFrameSource_sV(const Project_sV *project); - ~EmptyFrameSource_sV() {} - - void initialize(); - bool initialized() const { return true; } - - int64_t framesCount() const { return 1000; } - const Fps_sV* fps() const { return &m_fps; } - int frameRateNum() const { return 24; } - int frameRateDen() const { return 1; } - QImage frameAt(const uint, const FrameSize = FrameSize_Orig) { return QImage(); } - const QString framePath(const uint, const FrameSize) const { return QString(); } - -public slots: - void slotAbortInitialization() {} - void slotUpdateProjectDir() {} - -private: - Fps_sV m_fps; -}; - -#endif // EMPTYFRAMESOURCE_H
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/project/flowSourceOpenCV_sV.cpp
Deleted
@@ -1,186 +0,0 @@ -/* -This file is part of slowmoVideo. -Copyright (C) 2012 Lucas Walter - 2012 Simon A. Eugster (Granjow) <simon.eu@gmail.com> - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. -*/ - -#include "flowSourceOpenCV_sV.h" -#include "project_sV.h" -#include "abstractFrameSource_sV.h" -#include "../lib/flowRW_sV.h" -#include "../lib/flowField_sV.h" - -#include "opencv2/video/tracking.hpp" -#include "opencv2/imgproc/imgproc.hpp" -#include "opencv2/highgui/highgui.hpp" -#include <QtCore/QTime> -#include <iostream> -#include <fstream> -using namespace cv; - -FlowSourceOpenCV_sV::FlowSourceOpenCV_sV(Project_sV *project) : - AbstractFlowSource_sV(project) -{ - createDirectories(); -} - -void FlowSourceOpenCV_sV::slotUpdateProjectDir() -{ - m_dirFlowSmall.rmdir("."); - m_dirFlowOrig.rmdir("."); - createDirectories(); -} - -void FlowSourceOpenCV_sV::createDirectories() -{ - m_dirFlowSmall = project()->getDirectory("cache/oFlowSmall"); - m_dirFlowOrig = project()->getDirectory("cache/oFlowOrig"); -} - - - - -// TODO: check usage of cflowmap ? create a branch ? -void drawOptFlowMap(const Mat& flow, Mat& cflowmap, int step, - double, const Scalar& color, std::string flowname ) -{ - - cv::Mat log_flow, log_flow_neg; - //log_flow = cv::abs( flow/3.0 ); - cv::log(cv::abs(flow)*3 + 1, log_flow); - cv::log(cv::abs(flow*(-1.0))*3 + 1, log_flow_neg); - const float scale = 64.0; - const float offset = 128.0; - - float max_flow = 0.0; - - FlowField_sV flowField(cflowmap.cols, cflowmap.rows); - - for(int y = 0; y < cflowmap.rows; y += step) - for(int x = 0; x < cflowmap.cols; x += step) - { - const Point2f& fxyo = flow.at<Point2f>(y, x); - - flowField.setX(x, y, fxyo.x); - flowField.setY(x, y, fxyo.y); - - Point2f& fxy = log_flow.at<Point2f>(y, x); - const Point2f& fxyn = log_flow_neg.at<Point2f>(y, x); - - if (fxyo.x < 0) { - fxy.x = -fxyn.x; - } - if (fxyo.y < 0) { - fxy.y = -fxyn.y; - } - - - cv::Scalar col = cv::Scalar(offset + fxy.x*scale, offset + fxy.y*scale, offset); - //line(cflowmap, Point(x,y), Point(cvRound(x+fxy.x), cvRound(y+fxy.y)), - // color); - //TODO: usefullness ? - //circle(cflowmap, Point(x,y), 0, col, -1); - - if (fabs(fxy.x) > max_flow) max_flow = fabs(fxy.x); - if (fabs(fxy.y) > max_flow) max_flow = fabs(fxy.y); - } - - std::cout << max_flow << " max flow" << std::endl; - - FlowRW_sV::save(flowname, &flowField); -} - -const QString FlowSourceOpenCV_sV::flowPath(const uint leftFrame, const uint rightFrame, const FrameSize frameSize) const -{ - QDir dir; - if (frameSize == FrameSize_Orig) { - dir = m_dirFlowOrig; - } else { - dir = m_dirFlowSmall; - } - QString direction; - if (leftFrame < rightFrame) { - direction = "forward"; - } else { - direction = "backward"; - } - - return dir.absoluteFilePath(QString("ocv-%1-%2-%3.sVflow").arg(direction).arg(leftFrame).arg(rightFrame)); -} -FlowField_sV* FlowSourceOpenCV_sV::buildFlow(uint leftFrame, uint rightFrame, FrameSize frameSize) throw(FlowBuildingError) -{ - QString flowFileName(flowPath(leftFrame, rightFrame, frameSize)); - - /// \todo Check if size is equal - if (!QFile(flowFileName).exists()) { - - QTime time; - time.start(); - - Mat prevgray, gray, flow, cflow; - QString prevpath = project()->frameSource()->framePath(leftFrame, frameSize); - QString path = project()->frameSource()->framePath(rightFrame, frameSize); -// namedWindow("flow", 1); - - qDebug() << "Building flow for left frame " << leftFrame << " to right frame " << rightFrame << "; Size: " << frameSize; - - prevgray = imread(prevpath.toStdString(), 0); - gray = imread(path.toStdString(), 0); - - //cvtColor(l1, prevgray, CV_BGR2GRAY); - //cvtColor(l2, gray, CV_BGR2GRAY); - - { - - if( prevgray.data ) { - const float pyrScale = 0.5; - const float levels = 3; - const float winsize = 15; - const float iterations = 8; - const float polyN = 5; - const float polySigma = 1.2; - const int flags = 0; - // TBD need sliders for all these parameters - calcOpticalFlowFarneback( - prevgray, gray, - //gray, prevgray, // TBD this seems to match V3D output better but a sign flip could also do that - flow, - pyrScale, //0.5, - levels, //3, - winsize, //15, - iterations, //3, - polyN, //5, - polySigma, //1.2, - flags //0 - ); - cvtColor(prevgray, cflow, CV_GRAY2BGR); - //drawOptFlowMap(flow, cflow, 16, 1.5, CV_RGB(0, 255, 0)); - drawOptFlowMap(flow, cflow, 1, 1.5, CV_RGB(0, 255, 0), flowFileName.toStdString()); - //imshow("flow", cflow); - //imwrite(argv4,cflow); - } else { - qDebug() << "imread: Could not read image " << prevpath; - throw FlowBuildingError(QString("imread: Could not read image " + prevpath)); - } - } - - qDebug() << "Optical flow built for " << flowFileName << " in " << time.elapsed() << " ms."; - - } else { - qDebug().nospace() << "Re-using existing flow image for left frame " << leftFrame << " to right frame " << rightFrame << ": " << flowFileName; - } - - try { - return FlowRW_sV::load(flowFileName.toStdString()); - } catch (FlowRW_sV::FlowRWError &err) { - throw FlowBuildingError(err.message.c_str()); - } -} - - -
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/project/flowSourceOpenCV_sV.h
Deleted
@@ -1,38 +0,0 @@ -/* -This file is part of slowmoVideo. -Copyright (C) 2012 Lucas Walter - 2012 Simon A. Eugster (Granjow) <simon.eu@gmail.com> - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. -*/ - -#ifndef FLOWSOURCEOPENCV_SV_H -#define FLOWSOURCEOPENCV_SV_H - -#include "abstractFlowSource_sV.h" -#include <QtCore/QDir> - -class FlowSourceOpenCV_sV : public AbstractFlowSource_sV -{ -public: - FlowSourceOpenCV_sV(Project_sV *project); - ~FlowSourceOpenCV_sV() {} - - virtual FlowField_sV* buildFlow(uint leftFrame, uint rightFrame, FrameSize frameSize) throw(FlowBuildingError); - virtual const QString flowPath(const uint leftFrame, const uint rightFrame, const FrameSize frameSize = FrameSize_Orig) const; - -public slots: - virtual void slotUpdateProjectDir(); - - -private: - QDir m_dirFlowSmall; - QDir m_dirFlowOrig; - - void createDirectories(); -}; - -#endif // FLOWSOURCEOPENCV_SV_H
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/project/flowSourceV3D_sV.cpp
Deleted
@@ -1,160 +0,0 @@ -/* -This file is part of slowmoVideo. -Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. -*/ - -#include "flowSourceV3D_sV.h" -#include "project_sV.h" -#include "abstractFrameSource_sV.h" -#include "../lib/flowRW_sV.h" - -#include <QtCore/QCoreApplication> -#include <QtCore/QProcess> -#include <QtCore/QSettings> -#include <QtCore/QTime> - -FlowSourceV3D_sV::FlowSourceV3D_sV(Project_sV *project, float lambda) : - AbstractFlowSource_sV(project), - m_lambda(lambda) -{ - createDirectories(); -} - -void FlowSourceV3D_sV::slotUpdateProjectDir() -{ - m_dirFlowSmall.rmdir("."); - m_dirFlowOrig.rmdir("."); - createDirectories(); -} - -void FlowSourceV3D_sV::createDirectories() -{ - m_dirFlowSmall = project()->getDirectory("cache/oFlowSmall"); - m_dirFlowOrig = project()->getDirectory("cache/oFlowOrig"); -} - -void FlowSourceV3D_sV::setLambda(float lambda) -{ - m_lambda = lambda; -} - -FlowField_sV* FlowSourceV3D_sV::buildFlow(uint leftFrame, uint rightFrame, FrameSize frameSize) throw(FlowBuildingError) -{ - QString flowFileName(flowPath(leftFrame, rightFrame, frameSize)); - - /// \todo Check if size is equal - if (!QFile(flowFileName).exists()) { - QSettings settings; - QString programLocation(settings.value("binaries/v3dFlowBuilder", "/usr/local/bin/slowmoFlowBuilder").toString()); - if (!QFile(programLocation).exists()) { - QString newLoc = correctFlowBinaryLocation(); - if (newLoc.length() > 0) { - programLocation = newLoc; - } - } - if (!QFile(programLocation).exists()) { - throw FlowBuildingError("Program\n" + programLocation + "\ndoes not exist (did you compile/make V3D?), cannot build flow!"); - } - QString program(programLocation); - - qDebug() << "Building flow for left frame " << leftFrame << " to right frame " << rightFrame << "; Size: " << frameSize; - - QStringList args; - args << project()->frameSource()->framePath(leftFrame, frameSize) - << project()->frameSource()->framePath(rightFrame, frameSize) - << flowFileName - << QVariant(m_lambda).toString() << "100"; - - qDebug() << "Arguments: " << args; - - - QTime time; - QProcess proc; - - time.start(); - proc.start(program, args); - proc.waitForFinished(-1); - if (proc.exitCode() != 0) { - qDebug() << "Failed: " << proc.readAllStandardError() << proc.readAllStandardOutput(); - throw FlowBuildingError(QString("Flow builder exited with exit code %1; For details see debugging output").arg(proc.exitCode())); - } else { - qDebug() << "Optical flow built for " << flowFileName << " in " << time.elapsed() << " ms"; - qDebug() << proc.readAllStandardError() << proc.readAllStandardOutput(); - } - } else { - qDebug().nospace() << "Re-using existing flow image for left frame " << leftFrame << " to right frame " << rightFrame << ": " << flowFileName; - } - - try { - return FlowRW_sV::load(flowFileName.toStdString()); - } catch (FlowRW_sV::FlowRWError &err) { - throw FlowBuildingError(err.message.c_str()); - } -} - - - -QString FlowSourceV3D_sV::correctFlowBinaryLocation() -{ - QSettings settings; - QString programLocation(settings.value("binaries/v3dFlowBuilder", "/usr/local/bin/slowmoFlowBuilder").toString()); - - QStringList paths; - paths << programLocation; - paths << QDir::currentPath() + "/slowmoFlowBuilder"; - paths << QCoreApplication::applicationDirPath() + "/slowmoFlowBuilder"; - paths << "/usr/bin/slowmoFlowBuilder" << "/usr/local/bin/slowmoFlowBuilder"; - for (int i = 0; i < paths.size(); i++) { - if (validateFlowBinary(paths.at(i))) { - settings.setValue("binaries/v3dFlowBuilder", paths.at(i)); - return paths.at(i); - } - } - return QString(); -} - -bool FlowSourceV3D_sV::validateFlowBinary(const QString path) -{ - bool valid = false; - qDebug() << "Checking " << path << " ..."; - if (QFile(path).exists() && QFileInfo(path).isExecutable()) { - QProcess process; - QStringList args; - args << "--identify"; - process.start(path, args); - process.waitForFinished(2000); - QString output(process.readAllStandardOutput()); - if (output.startsWith("slowmoFlowBuilder")) { - valid = true; - qDebug() << path << " is valid."; - } else { - qDebug() << "Invalid output from flow executable: " << output; - } - process.terminate(); - } - return valid; -} - - -const QString FlowSourceV3D_sV::flowPath(const uint leftFrame, const uint rightFrame, const FrameSize frameSize) const -{ - QDir dir; - if (frameSize == FrameSize_Orig) { - dir = m_dirFlowOrig; - } else { - dir = m_dirFlowSmall; - } - QString direction; - if (leftFrame < rightFrame) { - direction = "forward"; - } else { - direction = "backward"; - } - - return dir.absoluteFilePath(QString("%1-lambda%4_%2-%3.sVflow").arg(direction).arg(leftFrame).arg(rightFrame).arg(m_lambda, 0, 'f', 2)); -}
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/project/flowSourceV3D_sV.h
Deleted
@@ -1,46 +0,0 @@ -/* -This file is part of slowmoVideo. -Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. -*/ - -#ifndef V3DFLOWSOURCE_SV_H -#define V3DFLOWSOURCE_SV_H - -#include "abstractFlowSource_sV.h" - -#include <QtCore/QDir> - -class FlowSourceV3D_sV : public AbstractFlowSource_sV -{ -public: - /** Creates a new flow source using V3D optical flow */ - FlowSourceV3D_sV(Project_sV *project, float lambda = 10); - ~FlowSourceV3D_sV() {} - void setLambda(float lambda); - - - FlowField_sV* buildFlow(uint leftFrame, uint rightFrame, FrameSize frameSize) throw(FlowBuildingError); - const QString flowPath(const uint leftFrame, const uint rightFrame, const FrameSize frameSize) const; - - static bool validateFlowBinary(const QString path); - static QString correctFlowBinaryLocation(); - -public slots: - void slotUpdateProjectDir(); - -private: - QDir m_dirFlowSmall; - QDir m_dirFlowOrig; - - float m_lambda; - - void createDirectories(); - -}; - -#endif // V3DFLOWSOURCE_SV_H
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/project/imagesFrameSource_sV.cpp
Deleted
@@ -1,148 +0,0 @@ -/* -This file is part of slowmoVideo. -Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. -*/ - -#include "imagesFrameSource_sV.h" -#include "project_sV.h" - -#include <QtCore/QFileInfo> -#include <QtCore/QDebug> -#include <QtGui/QImageReader> - -ImagesFrameSource_sV::ImagesFrameSource_sV(Project_sV *project, QStringList images) throw(FrameSourceError) : - AbstractFrameSource_sV(project), - m_fps(24, 1), - m_initialized(false), - m_stopInitialization(false), - m_nextFrame(0) -{ - QString msg = validateImages(images); - if (msg.length() > 0) { - throw FrameSourceError("Image frame source: " + msg); - } - - m_imagesList.append(images); - m_imagesList.sort(); - - QImage repImage(m_imagesList.at(0)); - if (repImage.isNull()) { - qDebug() << "Image is null: " << m_imagesList.at(0); - qDebug() << "Supported image formats: " << QImageReader::supportedImageFormats(); - throw FrameSourceError(QString("Cannot read image: %1").arg(m_imagesList.at(0))); - } - m_sizeSmall = repImage.size(); - if (m_sizeSmall.isEmpty()) { - throw FrameSourceError(QString("Image read from %1 is empty.").arg(m_imagesList.at(0))); - } - while (m_sizeSmall.width() > 600) { - m_sizeSmall = m_sizeSmall/2; - } - - - createDirectories(); -} - -QString ImagesFrameSource_sV::validateImages(const QStringList images) -{ - if (images.size() == 0) { return tr("No images selected."); } - - QSize size = QImage(images.at(0)).size(); - for (int i = 0; i < images.length(); i++) { - if (QImage(images.at(i)).size() != size) { - return tr("Image %1 is not of the same size (%2) as the first image (%3).") - .arg(images.at(i)).arg(toString(QImage(images.at(i)).size())).arg(toString(size)); - } - } - return QString(); -} - -const QStringList ImagesFrameSource_sV::inputFiles() const -{ - return m_imagesList; -} - -void ImagesFrameSource_sV::slotUpdateProjectDir() -{ - m_dirImagesSmall.rmdir("."); - createDirectories(); -} - -void ImagesFrameSource_sV::createDirectories() -{ - m_dirImagesSmall = m_project->getDirectory("frames/imagesSmall"); -} - -void ImagesFrameSource_sV::initialize() -{ - m_stopInitialization = false; - QMetaObject::invokeMethod(this, "slotContinueInitialization", Qt::QueuedConnection); -} -bool ImagesFrameSource_sV::initialized() const -{ - return m_initialized; -} - -/// \todo What if image missing? -void ImagesFrameSource_sV::slotContinueInitialization() -{ - emit signalNextTask(tr("Creating preview images from the input images"), m_imagesList.size()); - for (; m_nextFrame < m_imagesList.size(); m_nextFrame++) { - - QString outputFile(framePath(m_nextFrame, FrameSize_Small)); - if (QFile(outputFile).exists()) { - emit signalTaskItemDescription(tr("Resized image already exists for %1").arg(QFileInfo(m_imagesList.at(m_nextFrame)).fileName())); - } else { - emit signalTaskItemDescription(tr("Re-sizing image %1 to:\n%2") - .arg(QFileInfo(m_imagesList.at(m_nextFrame)).fileName()) - .arg(outputFile)); - QImage small = QImage(m_imagesList.at(m_nextFrame)).scaled(m_sizeSmall, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); - small.save(outputFile); - } - - emit signalTaskProgress(m_nextFrame); - if (m_stopInitialization) { - break; - } - } - m_initialized = true; - emit signalAllTasksFinished(); -} - -void ImagesFrameSource_sV::slotAbortInitialization() -{ - m_stopInitialization = true; -} - -int64_t ImagesFrameSource_sV::framesCount() const -{ - return m_imagesList.size(); -} -const Fps_sV* ImagesFrameSource_sV::fps() const -{ - return &m_fps; -} - -QImage ImagesFrameSource_sV::frameAt(const uint frame, const FrameSize frameSize) -{ - if (int(frame) < m_imagesList.size()) { - return QImage(framePath(frame, frameSize)); - } else { - return QImage(); - } -} -const QString ImagesFrameSource_sV::framePath(const uint frame, const FrameSize frameSize) const -{ - switch (frameSize) { - case FrameSize_Orig: - return QString(m_imagesList.at(frame)); - case FrameSize_Small: - default: - return QString(m_dirImagesSmall.absoluteFilePath(QFileInfo(m_imagesList.at(frame)).completeBaseName() + ".png")); - } -}
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/project/imagesFrameSource_sV.h
Deleted
@@ -1,68 +0,0 @@ -/* -This file is part of slowmoVideo. -Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. -*/ - -#ifndef IMAGESFRAMESOURCE_SV_H -#define IMAGESFRAMESOURCE_SV_H - -#include "abstractFrameSource_sV.h" -#include <QtCore/QStringList> -#include <QtCore/QDir> -#include <QtCore/QSize> - -class Project_sV; - -/** - \todo Allow re-ordering of images - \todo Check image resolution more efficiently for large number of images - \todo Support OpenEXR or similar through ffmpeg. 16-bit images. - */ -class ImagesFrameSource_sV : public AbstractFrameSource_sV -{ - Q_OBJECT -public: - ImagesFrameSource_sV(Project_sV *project, QStringList images) throw(FrameSourceError); - - static QString validateImages(const QStringList images); - - void initialize(); - bool initialized() const; - - int64_t framesCount() const; - const Fps_sV* fps() const; - QImage frameAt(const uint frame, const FrameSize frameSize = FrameSize_Orig); - const QString framePath(const uint frame, const FrameSize frameSize) const; - - const QStringList inputFiles() const; - - -public slots: - void slotAbortInitialization(); - void slotUpdateProjectDir(); - -private: - QStringList m_imagesList; - QDir m_dirImagesSmall; - QSize m_sizeSmall; - - Fps_sV m_fps; - - bool m_initialized; - bool m_stopInitialization; - int m_nextFrame; - - void createDirectories(); - - -private slots: - void slotContinueInitialization(); - -}; - -#endif // IMAGESFRAMESOURCE_SV_H
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/project/imagesRenderTarget_sV.cpp
Deleted
@@ -1,50 +0,0 @@ -/* -This file is part of slowmoVideo. -Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. -*/ - -#include "imagesRenderTarget_sV.h" - -#include <QtCore/QDebug> - -ImagesRenderTarget_sV::ImagesRenderTarget_sV(RenderTask_sV *parentRenderTask) : - AbstractRenderTarget_sV(parentRenderTask) -{ - m_targetDir = QDir::temp(); - m_filenamePattern = "rendered-%1.jpg"; -} - -void ImagesRenderTarget_sV::setTargetDir(const QDir dir) -{ - m_targetDir = dir; -} - -bool ImagesRenderTarget_sV::setFilenamePattern(const QString pattern) -{ - if (pattern.contains("%1")) { - m_filenamePattern = pattern; - return true; - } - return false; -} - -void ImagesRenderTarget_sV::slotConsumeFrame(const QImage &image, const int frameNumber) -{ - if (!m_targetDir.exists()) { - m_targetDir.mkpath("."); - } - QString path = m_targetDir.absoluteFilePath(m_filenamePattern.arg(frameNumber+1, 5, 10, QChar::fromAscii('0'))); - - bool ok; - ok = image.save(path); - if (!ok) { - qDebug() << " Writing image to " << path << " failed!"; - } else { - qDebug() << " Saved frame number " << frameNumber << " to " << path; - } -}
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/project/imagesRenderTarget_sV.h
Deleted
@@ -1,36 +0,0 @@ -/* -This file is part of slowmoVideo. -Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. -*/ - -#ifndef IMAGESRENDERTARGET_SV_H -#define IMAGESRENDERTARGET_SV_H - -#include "abstractRenderTarget_sV.h" - -#include <QtCore/QDir> - -class RenderTask_sV; - -class ImagesRenderTarget_sV : public AbstractRenderTarget_sV -{ -public: - ImagesRenderTarget_sV(RenderTask_sV *parentRenderTask); - - void setTargetDir(const QDir dir); - bool setFilenamePattern(const QString pattern); - -public slots: - void slotConsumeFrame(const QImage &image, const int frameNumber); - -private: - QDir m_targetDir; - QString m_filenamePattern; -}; - -#endif // IMAGESRENDERTARGET_SV_H
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/project/interpolator_sV.cpp
Deleted
@@ -1,103 +0,0 @@ -#include "interpolator_sV.h" -#include "abstractFrameSource_sV.h" -#include "../lib/flowField_sV.h" -#include "../lib/interpolate_sV.h" -#include <QtCore/QObject> - -#define MIN_FRAME_DIST .001 - -QImage Interpolator_sV::interpolate(Project_sV *pr, float frame, const RenderPreferences_sV &prefs) - throw(FlowBuildingError, InterpolationError) -{ - if (frame > pr->frameSource()->framesCount()) { - throw InterpolationError(QObject::tr("Requested frame %1: Not within valid range. (%2 frames)") - .arg(frame).arg(pr->frameSource()->framesCount())); - } - if (frame-floor(frame) > MIN_FRAME_DIST) { - - QImage left = pr->frameSource()->frameAt(floor(frame), prefs.size); - QImage right = pr->frameSource()->frameAt(floor(frame)+1, prefs.size); - QImage out(left.size(), QImage::Format_ARGB32); - - /// Position between two frames, on 0 1 - const float pos = frame-floor(frame); - - if (prefs.interpolation == InterpolationType_Twoway) { - FlowField_sV *forwardFlow = pr->requestFlow(floor(frame), floor(frame)+1, prefs.size); - FlowField_sV *backwardFlow = pr->requestFlow(floor(frame)+1, floor(frame), prefs.size); - - Q_ASSERT(forwardFlow != NULL); - Q_ASSERT(backwardFlow != NULL); - - if (forwardFlow == NULL || backwardFlow == NULL) { - qDebug() << "No flow received!"; - Q_ASSERT(false); - } - - Interpolate_sV::twowayFlow(left, right, forwardFlow, backwardFlow, pos, out); - delete forwardFlow; - delete backwardFlow; - - } else if (prefs.interpolation == InterpolationType_TwowayNew) { - FlowField_sV *forwardFlow = pr->requestFlow(floor(frame), floor(frame)+1, prefs.size); - FlowField_sV *backwardFlow = pr->requestFlow(floor(frame)+1, floor(frame), prefs.size); - - Q_ASSERT(forwardFlow != NULL); - Q_ASSERT(backwardFlow != NULL); - - if (forwardFlow == NULL || backwardFlow == NULL) { - qDebug() << "No flow received!"; - Q_ASSERT(false); - } - - Interpolate_sV::newTwowayFlow(left, right, forwardFlow, backwardFlow, pos, out); - delete forwardFlow; - delete backwardFlow; - - } else if (prefs.interpolation == InterpolationType_Forward) { - FlowField_sV *forwardFlow = pr->requestFlow(floor(frame), floor(frame)+1, prefs.size); - - Q_ASSERT(forwardFlow != NULL); - - if (forwardFlow == NULL) { - qDebug() << "No flow received!"; - Q_ASSERT(false); - } - - Interpolate_sV::forwardFlow(left, forwardFlow, pos, out); - delete forwardFlow; - - } else if (prefs.interpolation == InterpolationType_ForwardNew) { - FlowField_sV *forwardFlow = pr->requestFlow(floor(frame), floor(frame)+1, prefs.size); - - Q_ASSERT(forwardFlow != NULL); - - if (forwardFlow == NULL) { - qDebug() << "No flow received!"; - Q_ASSERT(false); - } - - Interpolate_sV::newForwardFlow(left, forwardFlow, pos, out); - delete forwardFlow; - - } else if (prefs.interpolation == InterpolationType_Bezier) { - FlowField_sV *currNext = pr->requestFlow(floor(frame)+2, floor(frame)+1, prefs.size); // Allowed to be NULL - FlowField_sV *currPrev = pr->requestFlow(floor(frame)+0, floor(frame)+1, prefs.size); - - Q_ASSERT(currPrev != NULL); - - Interpolate_sV::bezierFlow(left, right, currPrev, currNext, pos, out); - - delete currNext; - delete currPrev; - - } else { - qDebug() << "Unsupported interpolation type!"; - Q_ASSERT(false); - } - return out; - } else { - qDebug() << "No interpolation necessary."; - return pr->frameSource()->frameAt(floor(frame), prefs.size); - } -}
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/project/interpolator_sV.h
Deleted
@@ -1,14 +0,0 @@ -#ifndef INTERPOLATOR_SV_H -#define INTERPOLATOR_SV_H - -#include "renderPreferences_sV.h" -#include "project_sV.h" - -class Interpolator_sV -{ -public: - static QImage interpolate(Project_sV *project, float frame, const RenderPreferences_sV& prefs) - throw(FlowBuildingError, InterpolationError); -}; - -#endif // INTERPOLATOR_SV_H
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/project/motionBlur_sV.cpp
Deleted
@@ -1,288 +0,0 @@ -/* -This file is part of slowmoVideo. -Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. -*/ - -#include "motionBlur_sV.h" -#include "project_sV.h" -#include "abstractFrameSource_sV.h" -#include "abstractFlowSource_sV.h" -#include "interpolator_sV.h" -#include "renderTask_sV.h" -#include "../lib/flowField_sV.h" -#include "../lib/shutter_sV.h" - -#define MAX_CONV_FRAMES 5 - -//#define DEBUG - -MotionBlur_sV::MotionBlur_sV(Project_sV *project) : - m_project(project), - m_slowmoSamples(16), - m_maxSamples(64), - m_slowmoMaxFrameDist(.5) -{ - createDirectories(); -} - -QImage MotionBlur_sV::blur(float startFrame, float endFrame, float replaySpeed, RenderPreferences_sV prefs) -throw(RangeTooSmallError_sV) -{ - if (prefs.motionblur == MotionblurType_Nearest) { - return nearest(startFrame, prefs); - } else if (prefs.motionblur == MotionblurType_Convolving) { - return convolutionBlur(startFrame, endFrame, replaySpeed, prefs); - } else { - if (replaySpeed > 0.5) { - return fastBlur(startFrame, endFrame, prefs); - } else { - return slowmoBlur(startFrame, endFrame, prefs); - } - } -} - -QImage MotionBlur_sV::nearest(float startFrame, const RenderPreferences_sV &prefs) -{ - return m_project->frameSource()->frameAt(startFrame, prefs.size); -} - -QImage MotionBlur_sV::fastBlur(float startFrame, float endFrame, const RenderPreferences_sV &prefs) throw(RangeTooSmallError_sV) -{ - float low, high; - if (startFrame < endFrame) { - low = startFrame; high = endFrame; - } else { - low = endFrame; high = startFrame; - } - low = qMax(low, float(0)); - high = qMin(high, (float)m_project->frameSource()->framesCount()-1); - - float dist = 0.125; - float lowRounded; - float highRounded; - for (; ; dist *= 2) { - lowRounded = ceil(low/dist)*dist; - highRounded = floor(high/dist)*dist; - if ((highRounded-lowRounded)/dist <= m_maxSamples) { - break; - } - } - - float pos = lowRounded; - - QStringList frameList; - - while (pos < high) { - frameList << cachedFramePath(pos, prefs); - pos += dist; - } - qDebug() << "Fast blurring " << frameList.size() << " frames from " << startFrame << " to " << endFrame << ", low: " << low - << ", high: " << high << ", with a distance of " << dist; - - if (frameList.size() > 1) { - return Shutter_sV::combine(frameList); - } else { - throw RangeTooSmallError_sV(QObject::tr("Range too small: Start frame is %1, end frame is %2. " - "Using normal interpolation.").arg(startFrame).arg(endFrame)); - } - -} - -/// \todo fixed distance as additional option -QImage MotionBlur_sV::slowmoBlur(float startFrame, float endFrame, const RenderPreferences_sV &prefs) -{ - float low, high; - if (startFrame < endFrame) { - low = startFrame; high = endFrame; - } else { - low = endFrame; high = startFrame; - } - low = qMax(low, float(0)); - high = qMin(high, (float)m_project->frameSource()->framesCount()); - - QStringList frameList; - float increment = (high-low)/(m_slowmoSamples-1); - if (increment < .1) { - qDebug() << "slowmoBlur(): Increasing distance from " << increment << " to .1"; - increment = .1; - } - if (increment > m_slowmoMaxFrameDist) { - qDebug() << "slowmoBlur(): Decreasing distance from " << increment << " to " << m_slowmoMaxFrameDist; - increment = m_slowmoMaxFrameDist; - } - for (float pos = low; pos <= high; pos += increment) { - frameList << cachedFramePath(pos, prefs, true); - } - - return Shutter_sV::combine(frameList); -} - -QImage MotionBlur_sV::convolutionBlur(float startFrame, float endFrame, float replaySpeed, const RenderPreferences_sV &prefs) -{ - float low, high; - if (startFrame < endFrame) { - low = startFrame; high = endFrame; - } else { - low = endFrame; high = startFrame; - } - low = qMax(low, float(0)); - high = qMin(high, (float)m_project->frameSource()->framesCount()-1); - - if (floor(low) == floor(high) && low > .01) { - if (floor(low) < m_project->frameSource()->framesCount()-1) { - qDebug() << "Small shutter." << startFrame << endFrame; - FlowField_sV *field = m_project->requestFlow(floor(low), floor(low)+1, prefs.size); - QImage blur = Shutter_sV::convolutionBlur(Interpolator_sV::interpolate(m_project, startFrame, prefs), - field, - high-low, - low-floor(low)); - delete field; - return blur; - } else { - /// \todo Convolve last frame as well - qDebug() << "No shutter, at the last frame."; - return m_project->frameSource()->frameAt(floor(low), prefs.size); - } - } - - QList<QImage> images; - FlowField_sV *field; - int start = floor(low); - int end = std::min((int64_t)ceil(high), m_project->frameSource()->framesCount()-2); - int inc = 1; - qDebug() << "Large shutter." << startFrame << endFrame << " -- replay speed is " << replaySpeed; - qDebug() << "Additional parts: " << start << end; - if (replaySpeed < 2) { - // \todo Lower weight for those frames when combining - if (low-start > .1) { - qDebug() << "First part: " << start << low; - field = m_project->requestFlow(start, start+1, prefs.size); - images << Shutter_sV::convolutionBlur(Interpolator_sV::interpolate(m_project, startFrame, prefs), - field, - floor(low)+1 - low, - low-floor(low)); - delete field; - start++; - } - if (end-high > .1) { - qDebug() << "Last part: " << end-1 << high; - field = m_project->requestFlow(end-1, end, prefs.size); - images << Shutter_sV::convolutionBlur(m_project->frameSource()->frameAt(end-1, prefs.size), - field, - 1 + high-end); - delete field; - end--; - } - } else { - // \todo Check increment value - while ((end-start) / inc > MAX_CONV_FRAMES) { - if (inc == 1) { - inc = 2; - } else { - inc += 2; - } - } - start = start - start%inc; - end = end - end%inc; - qDebug() << "Parts scaled to " << start << end << " with increment " << inc; - } - for (int f = start; f <= end; f += inc) { - QString name = QString("%1/convolved-%2+%3.png").arg(cacheDir(prefs.size).absolutePath()).arg(f).arg(inc); - if (replaySpeed < 2) { - if (QFileInfo(name).exists()) { - qDebug() << "Using convolved image from cache: " << name; - images << QImage(name); - continue; - } - } - field = m_project->requestFlow(f, f+1, prefs.size); - images << Shutter_sV::convolutionBlur(m_project->frameSource()->frameAt(f, prefs.size), - field, - inc); - if (replaySpeed < 2) { - qDebug() << "Caching convolved image: " << name; - images.last().save(name); - } - - delete field; - } - -#ifdef DEBUG - for (int i = 0; i < images.size(); i++) { - images.at(i).save(QString("/tmp/mblur-%1.png").arg(i)); - } -#endif - - return Shutter_sV::combine(images); -} - -QDir MotionBlur_sV::cacheDir(FrameSize size) const -{ - switch (size) { - case FrameSize_Small: - return m_dirCacheSmall; - case FrameSize_Orig: - return m_dirCacheOrig; - default: - qDebug() << "Unknown frame size in MotionBlur_sV: " << toString(size); - Q_ASSERT(false); - return QDir(); - } -} - -QString MotionBlur_sV::cachedFramePath(float framePos, const RenderPreferences_sV &prefs, bool highPrecision) -{ - int precision = 2; - if (highPrecision) { precision = 2; } /// \todo check precision - int width = 5+1 + precision; - QString name = QString("%2/cached%1.png").arg(framePos, width, 'f', precision, '0'); - if (prefs.size == FrameSize_Small) { - name = name.arg(m_dirCacheSmall.absolutePath()); - } else if (prefs.size == FrameSize_Orig) { - name = name.arg(m_dirCacheOrig.absolutePath()); - } else { - qDebug() << "MotionBlur: Frame size " << toString(prefs.size) << " given, not supported!"; - Q_ASSERT(false); - } - if (fabs(framePos-int(framePos)) < MOTIONBLUR_PRECISION_LIMIT) { - name = m_project->frameSource()->framePath(uint(framePos), prefs.size); - } else { - if (!QFileInfo(name).exists()) { - qDebug() << name << " does not exist yet. Interpolating and saving to cache."; - QImage frm = Interpolator_sV::interpolate(m_project, framePos, prefs); - frm.save(name); - } - } - return name; -} - -void MotionBlur_sV::slotUpdateProjectDir() -{ - m_dirCacheSmall.rmdir("."); - m_dirCacheOrig.rmdir("."); - createDirectories(); -} - - -void MotionBlur_sV::createDirectories() -{ - m_dirCacheSmall = m_project->getDirectory("cache/motionBlurSmall"); - m_dirCacheOrig = m_project->getDirectory("cache/motionBlurOrig"); -} - -void MotionBlur_sV::setSlowmoSamples(int slowmoSamples) -{ - m_slowmoSamples = slowmoSamples; - Q_ASSERT(m_slowmoSamples > 0); -} - -void MotionBlur_sV::setMaxSamples(int maxSamples) -{ - m_maxSamples = maxSamples; - Q_ASSERT(m_maxSamples > 0); -}
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/project/motionBlur_sV.h
Deleted
@@ -1,96 +0,0 @@ -/* -This file is part of slowmoVideo. -Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. -*/ - -#ifndef MOTIONBLUR_SV_H -#define MOTIONBLUR_SV_H - -#include <QtCore/QDir> -#include <QtGui/QImage> -#include "renderPreferences_sV.h" -class Project_sV; - -/// Thrown if the frame range is too small for motion blur to still make sense -class RangeTooSmallError_sV : public Error_sV { -public: - RangeTooSmallError_sV(QString msg) : Error_sV(msg) {} -}; - -/// If a frame is closer than this to a full frame, the full frame will be used instead. -#define MOTIONBLUR_PRECISION_LIMIT .01 - -/** - \brief Renders motion blur - \todo Force fast blurring for a segment? - \todo Use .jpg for cached frames? - */ -class MotionBlur_sV -{ -public: - MotionBlur_sV(Project_sV *project); - - /** - Selects either fastBlur() or slowmoBlur(), depending on the replay speed. - \param replaySpeed Must be >= 0 - */ - QImage blur(float startFrame, float endFrame, float replaySpeed, RenderPreferences_sV prefs) throw(RangeTooSmallError_sV); - - /** - Blurs frames using cached frames on fixed, coarse-grained intervals. - If the replay speed is high enough, it does not matter if frame 1.424242 or frame 1.5 is used - together with other frames for rendering motion blur. That way calculation can be sped up a little bit. - */ - QImage fastBlur(float startFrame, float endFrame, const RenderPreferences_sV &prefs) throw(RangeTooSmallError_sV); - - /** - Blurs frames that are re-played at very low speed, such that fastBlur() cannot be used. - The blurred parts of the image still need to move slowly, rounding frames to interpolate to 0.5 - would not work therefore. - */ - QImage slowmoBlur(float startFrame, float endFrame, const RenderPreferences_sV& prefs); - - QImage convolutionBlur(float startFrame, float endFrame, float replaySpeed, const RenderPreferences_sV& prefs); - - QImage nearest(float startFrame, const RenderPreferences_sV& prefs); - - /** - \fn setSlowmoSamples(); - Sets the minimum number of samples for motion blur. This is ignored by fastBlur() where the interpolation scale - is fixed (i.e. at most 1/8 steps between two frames). However slowmoBlur() uses this exact value for interpolating. - */ - /** - \fn setMaxSamples(); - Sets the maximum number of samples that are used for rendering motion blur. - */ - void setSlowmoSamples(int slowmoSamples); - void setMaxSamples(int maxSamples); - void setSlowmoMaxFrameDistance(float distance); - - int slowmoSamples() const { return m_slowmoSamples; } - int maxSamples() const { return m_maxSamples; } - -public slots: - void slotUpdateProjectDir(); - -private: - Project_sV *m_project; - QDir m_dirCacheSmall; - QDir m_dirCacheOrig; - - int m_slowmoSamples; - int m_maxSamples; - float m_slowmoMaxFrameDist; - - QString cachedFramePath(float framePos, const RenderPreferences_sV &prefs, bool highPrecision = false); - void createDirectories(); - - QDir cacheDir(FrameSize size) const; -}; - -#endif // MOTIONBLUR_SV_H
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/project/nodeList_sV.cpp
Deleted
@@ -1,610 +0,0 @@ -/* -slowmoUI is a user interface for slowmoVideo. -Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. -*/ - -#include "nodeList_sV.h" -#include "node_sV.h" -#include "../lib/bezierTools_sV.h" - -#include <cmath> - -#include <QDebug> - -//#define DEBUG_NL -#ifdef DEBUG_NL -#include <iostream> -#endif - -NodeList_sV::NodeList_sV(float minDist) : - m_maxY(10), - m_list(), - m_minDist(minDist) -{ -} - -void NodeList_sV::setMaxY(qreal time) -{ - Q_ASSERT(time > 0); - m_maxY = time; -} - -qreal NodeList_sV::startTime(bool useMoved) const -{ - if (m_list.length() > 0) { - if (useMoved) { - return m_list0.x(); - } else { - return m_list0.xUnmoved(); - } - } else { -// qDebug() << "No start time available (no nodes)"; - return 0; - } -} -qreal NodeList_sV::endTime(bool useMoved) const -{ - if (m_list.length() > 0) { - if (useMoved) { - return m_listm_list.length()-1.x(); - } else { - return m_listm_list.length()-1.xUnmoved(); - } - } else { -// qDebug() << "No end time available (no nodes)"; - return 0; - } -} -bool NodeList_sV::isInsideCurve(qreal targetTime, bool useMoved) const -{ - return m_list.size() >= 2 && - startTime(useMoved) <= targetTime && - targetTime <= endTime(useMoved); -} -qreal NodeList_sV::totalTime() const -{ - return endTime()-startTime(); -} -qreal NodeList_sV::sourceTime(qreal targetTime) const -{ - qreal srcTime = -1; - int index = find(targetTime); - if (index >= 0) { - if (m_list.size() > index+1) { - if (m_list.at(index).rightCurveType() == CurveType_Bezier - && m_list.at(index+1).leftCurveType() == CurveType_Bezier) { - srcTime = BezierTools_sV::interpolateAtX(targetTime, - m_list.at(index).toQPointF(), - m_list.at(index).toQPointF()+m_list.at(index).rightNodeHandle(), - m_list.at(index+1).toQPointF()+m_list.at(index+1).leftNodeHandle(), - m_list.at(index+1).toQPointF()).y(); - } else { - float ratio = (targetTime-m_listindex.x())/(m_listindex+1.x()-m_listindex.x()); - srcTime = m_listindex.y() + ratio*( m_listindex+1.y()-m_listindex.y() ); - } - } else { - if (index >= m_list.size()) { - qDebug() << "index " << index << " is > list size: " << m_list.size(); - Q_ASSERT(false); - } else { - srcTime = m_listindex.y(); - } - } - } else { - qDebug() << "No node before " << targetTime; - Q_ASSERT(false); - if (m_list.size() > 0) { - srcTime = m_list0.y(); - } - } - return srcTime; -} - -bool NodeList_sV::add(Node_sV node) -{ - bool add = true; - -#ifdef DEBUG_NL - qDebug() << "Before adding: \n" << *this; -#endif - - node.setX(qMax(.0, node.x())); - node.setY(qMax(.0, qMin(m_maxY, node.y()))); - - int pos = find(node.x()); - if (pos >= 0 && m_list.size() > pos) { - add = fabs(node.x()-m_list.at(pos).x()) > m_minDist; -#ifdef DEBUG_NL - qDebug() << "Left distance is " << fabs(node.x()-m_list.at(pos).x()); -#endif - if (add && m_list.size() > pos+1) { - add = fabs(node.x()-m_list.at(pos+1).x()) > m_minDist; -#ifdef DEBUG_NL - qDebug() << "Right distance is " << fabs(node.x()-m_list.at(pos+1).x()); -#endif - } - } -#ifdef DEBUG_NL - qDebug() << "Adding? " << add; -#endif - if (add) { - m_list.append(node); - qSort(m_list); - - if (m_list.size() > 1) { - m_segments.grow(); - } - - // Reset curve type of neighbours if this is a linear node - int index = m_list.indexOf(node); - if (index > 0 && node.leftCurveType() == CurveType_Linear) { - m_listindex-1.setRightCurveType(CurveType_Linear); - } - if (index < m_list.size()-1 && node.rightCurveType() == CurveType_Linear) { - m_listindex+1.setLeftCurveType(CurveType_Linear); - } - - fixHandles(index-1); - fixHandles(index); - } -#ifdef DEBUG_NL - qDebug() << "After adding: \n" << *this; -#endif - - validate(); - return add; -} - -uint NodeList_sV::deleteSelected() -{ - uint counter = 0; - for (int i = 0; i < m_list.size(); ) { - if (m_list.at(i).selected()) { - m_list.removeOne(m_list.at(i)); - if (m_list.size() > 0) { - m_segments.shrink(); - } - counter++; - } else { - i++; - } - } - validate(); - return counter; -} -void NodeList_sV::deleteNode(int index) -{ - Q_ASSERT(index >= 0); - Q_ASSERT(index < m_list.size()); - if (m_list.size() > 0) { - if (m_list.size() > 1) { - m_segments.shrink(); - } - m_list.removeAt(index); - } - if (index > m_list.size() && (index-1) >= 0) { - if (m_list.at(index-1).rightCurveType() != m_list.at(index).leftCurveType()) { - m_listindex-1.setRightCurveType(CurveType_Linear); - m_listindex.setLeftCurveType(CurveType_Linear); - } - } - validate(); -} - - -void NodeList_sV::select(const Node_sV *node, bool newSelection) -{ - if (newSelection) { - unselectAll(); - const_cast<Node_sV*>(node)->select(true); - } else { - const_cast<Node_sV*>(node)->select(!node->selected()); - } -} - -void NodeList_sV::unselectAll() -{ - for (int i = 0; i < m_list.size(); i++) { - m_listi.select(false); - } -} - - -bool NodeList_sV::validate() const -{ - bool valid = true; - qreal last = -m_minDist; - for (int i = 0; i < m_list.size() && valid; i++) { - valid = m_list.at(i).x() >= 0 - && m_list.at(i).y() >= 0 - && m_list.at(i).x() - last >= m_minDist - && m_list.at(i).y() <= m_maxY; - if (!valid) { - qDebug() << "Invalid node position for node " << i << " (" << m_list.size() << " total); Distance is " << m_list.at(i).x() - last; - qDebug() << "Positions: " << last << "/" << m_list.at(i).x(); - Q_ASSERT(false); - break; - } - last = m_list.at(i).x(); - } - if (valid) { - for (int i = 1; i < m_list.size(); i++) { - float space = (m_list.at(i).x() + m_list.at(i).leftNodeHandle().x()) - - (m_list.at(i-1).x() + m_list.at(i-1).rightNodeHandle().x()); - valid = space >= 0; - if (!valid) { - qDebug() << "Invalid handle position for nodes " << i-1 << " and " << i; - qDebug() << "Positions: " << m_list.at(i-1) << " with handle " << toString(m_list.at(i-1).rightNodeHandle()) - << ", " << m_list.at(i) << " with handle " << toString(m_list.at(i).leftNodeHandle()) - << ", space: " << space; - Q_ASSERT(false); - break; - } - } - } - if (valid) { - Q_ASSERT( (m_list.size() == 0 && m_segments.size() == 0) - || (m_list.size() > 0 && m_segments.size() == m_list.size()-1) ); - } - return valid; -} - - -////////// Moving - -void NodeList_sV::moveSelected(const Node_sV &time) -{ - qreal maxRMove = 100000; - qreal maxLMove = -100000; - qreal maxUMove = 100000; - qreal maxDMove = -100000; - const Node_sV *left = NULL; - const Node_sV *right; - for (int i = 0; i < m_list.size(); i++) { - right = &m_list.at(i); - - /* - Get the maximum allowed horizontal movement distance here such that there is no - overlapping. For moving the selected nodes to the left, only unselected nodes - which are directly followed by a selected node need to be taken into account. - O----O - / \ x - -----x \ / - x-----------O - - min( ^1^, ^-----2-----^ ) + minDist - - */ - if (left != NULL) { - if (left->selected() && !right->selected()) { - // Move-right distance - maxRMove = qMin(maxRMove, - right->xUnmoved()+right->leftNodeHandle().x() - - (left->xUnmoved()+left->rightNodeHandle().x()) - - m_minDist); - } else if (!left->selected() && right->selected()) { - // Move-left distance - maxLMove = qMax(maxLMove, - left->xUnmoved()+left->rightNodeHandle().x() - - (right->xUnmoved()+right->leftNodeHandle().x()) + - m_minDist); - } - } - - if (right->selected()) { - maxDMove = qMax(maxDMove, -right->yUnmoved()); - maxUMove = qMin(maxUMove, m_maxY-right->yUnmoved()); - } - - left = right; - } - if (m_list.size() > 0 && m_list.at(0).selected()) { - // Do not allow to move nodes to x < 0 - maxLMove = qMax(maxLMove, -m_list.at(0).xUnmoved()); - } -#ifdef DEBUG_NL - qDebug() << "Max move: left " << maxLMove << ", right: " << maxRMove; -#endif - Node_sV newTime( - qMax(maxLMove, qMin(maxRMove, time.x())), - qMax(maxDMove, qMin(maxUMove, time.y())) - ); - for (int i = 0; i < m_list.size(); i++) { - if (m_list.at(i).selected()) { - m_listi.move(newTime); - } - } -} -void NodeList_sV::shift(qreal after, qreal by) -{ - int pos = nodeAfter(after); - if (pos >= 0) { - if (pos > 0) { - // ----o o------- <- nodes with handles - // <---> <- maximum distance - by = qMax(by, - m_list.at(pos-1).xUnmoved()+m_list.at(pos-1).rightNodeHandle().x() - - (m_list.at(pos).xUnmoved()+m_list.at(pos).leftNodeHandle().x()) + - m_minDist - ); - } - if (pos == 0) { - by = qMax(by, -m_list.at(pos).xUnmoved()); - } - for (; pos < m_list.size(); pos++) { - m_listpos.move(Node_sV(by, 0)); - } - } - if (!validate()) { - qDebug() << "Invalid node configuration! (This should not happen.)"; - } -} - -void NodeList_sV::confirmMove() -{ - for (int i = 0; i < m_list.size(); i++) { - m_listi.confirmMove(); - } - validate(); -} -void NodeList_sV::abortMove() -{ - for (int i = 0; i < m_list.size(); i++) { - if (m_list.at(i).selected()) { - m_listi.abortMove(); - } - } -} - -void NodeList_sV::moveHandle(const NodeHandle_sV *handle, Node_sV relPos) -{ - Node_sV otherNode; - Node_sV *currentNode = const_cast<Node_sV*>(handle->parentNode()); - - int nodeIndex = indexOf(handle->parentNode()); - Q_ASSERT(nodeIndex >= 0); - Q_ASSERT(nodeIndex < m_list.size()); - - if (handle == ¤tNode->leftNodeHandle()) { - // o------ - if (nodeIndex > 0) { - // Ensure that it does not overlap with the left node's handle (injectivity) - otherNode = m_list.at(nodeIndex-1); - qDebug() << "Left node: " << otherNode; - qDebug() << "Right node: " << currentNode; - qDebug() << "Before overlapping check: " << relPos; - relPos.setX(qMax(relPos.x(), -(currentNode->x() - otherNode.x() - otherNode.rightNodeHandle().x()))); - qDebug() << "After overlapping check: " << relPos; - qDebug() << "Space left: " << currentNode->x() + relPos.x() - (otherNode.x() + otherNode.rightNodeHandle().x()); - } - // Additionally the handle has to stay on the left of its node - relPos.setX(qMin(relPos.x(), .0)); - - currentNode->setLeftNodeHandle(relPos.x(), relPos.y()); - - } else { - // -------o - if (nodeIndex+1 < m_list.size()) { - otherNode = m_list.at(nodeIndex+1); - relPos.setX(qMin(relPos.x(), otherNode.x() - currentNode->x() + otherNode.leftNodeHandle().x())); - } - relPos.setX(qMax(relPos.x(), .0)); - - currentNode->setRightNodeHandle(relPos.x(), relPos.y()); - } - validate(); -} - - - - -////////// Curve - -void NodeList_sV::setCurveType(qreal segmentTime, CurveType type) -{ - int left, right; - findBySegment(segmentTime, left, right); -#ifdef DEBUG_NL - qDebug() << "Setting curve type for nodes " << left << " and " << right; -#endif - if (left != -1) { - m_listleft.setRightCurveType(type); - } - if (right != -1) { - m_listright.setLeftCurveType(type); - } -} -void NodeList_sV::fixHandles(int leftIndex) -{ - if (leftIndex >= 0 && (leftIndex+1) < m_list.size()) { - qreal right = m_list.at(leftIndex+1).x() - m_list.at(leftIndex).x(); - qreal leftHandle = m_list.at(leftIndex).rightNodeHandle().x(); - qreal rightHandle = m_list.at(leftIndex+1).leftNodeHandle().x(); - - if (leftHandle < 0) { leftHandle = 0; } - if (rightHandle > 0) { rightHandle = 0; } - - if (leftHandle > right+rightHandle && (leftHandle-rightHandle) > 0) { - qreal factor = right / (leftHandle - rightHandle); - qDebug() << "Factor: " << factor << ", left: " << leftHandle << ", right: " << rightHandle << ", distance: " << right; - leftHandle *= factor; - rightHandle *= factor; - qDebug() << "After scaling: left: " << leftHandle << ", right: " << rightHandle; - Q_ASSERT(leftHandle <= right+rightHandle); - } - m_listleftIndex.setRightNodeHandle(leftHandle, m_list.at(leftIndex).rightNodeHandle().y()); - m_listleftIndex+1.setLeftNodeHandle(rightHandle, m_list.at(leftIndex+1).leftNodeHandle().y()); - } -} -void NodeList_sV::setSpeed(qreal segmentTime, qreal speed) -{ - int left, right; - findBySegment(segmentTime, left, right); - if (left >= 0 && right >= 0) { - Node_sV *leftN = &m_listleft; - Node_sV *rightN = &m_listright; - qreal y = leftN->y() + speed*(rightN->x()-leftN->x()); - if (y > m_maxY || y < 0) { - if (y > m_maxY) { - qDebug() << speed << "x speed would shoot over maximum time. Correcting."; - y = m_maxY; - } else { - qDebug() << speed << "x speed goes below 0. Correcting."; - y = 0; - } - qreal xNew = leftN->x() + (y - leftN->y())/speed; - rightN->setY(y); - if (xNew - leftN->x() >= m_minDist) { - add(Node_sV(xNew, y)); - } else { - qDebug() << "New node would be too close, not adding it."; - } - } else { - rightN->setY(y); - } - } else { - qDebug() << "Outside segment."; - } - validate(); -} - - - - -////////// Access - -int NodeList_sV::indexOf(const Node_sV *node) const -{ - return m_list.indexOf(*node); -} - -int NodeList_sV::find(qreal time) const -{ - int pos; - for ( - pos = 0; - m_list.size() > (pos+1) && m_list.at(pos+1).x() <= time; - pos++ - ) {} - if (m_list.size() == 0 || (pos == 0 && time < m_list0.x())) { -#ifdef DEBUG_NL - if (m_list.size() > 0) { - std::cout.precision(30); - std::cout << "find(): time: " << time << ", left boundary: " << m_list0.x() - << ", unmoved: " << m_list0.xUnmoved() - << ", diff: " << m_listpos.x()-time << std::endl; - } -#endif - pos = -1; - } - return pos; -} -int NodeList_sV::find(QPointF pos, qreal tdelta) const -{ - for (int i = 0; i < m_list.size(); i++) { - if (std::pow(m_list.at(i).xUnmoved() - pos.x(), 2) + std::pow(m_list.at(i).yUnmoved()-pos.y(), 2) - < std::pow(tdelta, 2)) { - return i; - } - } - return -1; -} - -void NodeList_sV::findBySegment(qreal tx, int &leftIndex_out, int &rightIndex_out) const -{ - for (int i = 0; i < m_list.size(); i++) { - leftIndex_out = i-1; - rightIndex_out = i; - if (m_list.at(i).xUnmoved() > tx) { - break; - } - if (i == m_list.size()-1) { - leftIndex_out = i; - rightIndex_out = -1; - } - } -} - -QList<NodeList_sV::PointerWithDistance> NodeList_sV::objectsNear(QPointF pos, qreal tmaxdist) const -{ - qreal maxdist2 = std::pow(tmaxdist, 2); - - QList<PointerWithDistance> objects; - qreal dist; - for (int i = 0; i < m_list.size(); i++) { - - dist = dist2(m_list.at(i).toQPointF() - pos); - if (dist <= maxdist2) { - objects << PointerWithDistance(&m_listi, dist, PointerWithDistance::Node); - } - - if (m_list.at(i).leftCurveType() != CurveType_Linear) { - dist = dist2(m_list.at(i).toQPointF() + m_list.at(i).leftNodeHandle() - pos); - if (dist <= maxdist2) { - objects << PointerWithDistance(&m_listi.leftNodeHandle(), dist, PointerWithDistance::Handle); - } - } - if (m_list.at(i).rightCurveType() != CurveType_Linear) { - dist = dist2(m_list.at(i).toQPointF() + m_list.at(i).rightNodeHandle() - pos); - if (dist <= maxdist2) { - objects << PointerWithDistance(&m_listi.rightNodeHandle(), dist, PointerWithDistance::Handle); - } - } - if (i > 0) { - if (m_list.at(i-1).x() < pos.x() && m_list.at(i).x() > pos.x()) { - objects << PointerWithDistance(&m_segments.at(i-1), std::pow(sourceTime(pos.x()) - pos.y(), 2), PointerWithDistance::Segment); - } - } - } - - qSort(objects); - return objects; -} -qreal NodeList_sV::dist2(QPointF point) const -{ - return std::pow(point.x(), 2) + std::pow(point.y(), 2); -} - -int NodeList_sV::nodeAfter(qreal time) const -{ - int pos = 0; - while (m_list.size() > pos) { - if (m_list.at(pos).xUnmoved() >= time) { - break; - } - pos++; - } - if (pos >= m_list.size()) { - pos = -1; - } - Q_ASSERT(pos < 0 || m_list.at(pos).xUnmoved() >= time); - return pos; -} - -const Node_sV& NodeList_sV::at(int i) const { return m_list.at(i); } -Node_sV& NodeList_sV::operator(int i) { return m_listi; } -int NodeList_sV::size() const { return m_list.size(); } - -SegmentList_sV* NodeList_sV::segments() -{ - return &m_segments; -} - - - - - -////////// Debug - -QDebug operator<<(QDebug dbg, const NodeList_sV &list) -{ - for (int i = 0; i < list.size(); i++) { - dbg.nospace() << i << ": " << list.at(i) << " "; - } - return dbg.maybeSpace(); -}
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/project/nodeList_sV.h
Deleted
@@ -1,170 +0,0 @@ -/* -slowmoUI is a user interface for slowmoVideo. -Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. -*/ - -#ifndef NODELIST_SV_H -#define NODELIST_SV_H - -#include "node_sV.h" -#include "segmentList_sV.h" -#include "canvasObject_sV.h" -#include "../lib/defs_sV.hpp" - -#include <QList> -#include <QtGlobal> - -/** - \brief Represents a curve defined by a Node_sV list. - - This object can be queried for the source time given an output time. - - The curve is (ensured to be) injective, i.e. - \f$ t_1 \neq t_2 \rightarrow f(t_1) \neq f(t_2) \f$ - with \f$ t_1,t_2 \in \f$ target time, \f$ f(t_1),f(t_2) \in \f$ source time. This means that - there is alwas a non-ambiguous answer to the question: - <em>Which frame from the input video has to be displayed at output time \f$ t \f$?</em> - */ -class NodeList_sV -{ -public: - NodeList_sV(float minDist = 1/30.0f); - - /// For sorting objects - struct PointerWithDistance { - - /// Defines the order on object types. Nodes will come first in a sorted list. - enum ObjectType { Node = 1, Handle = 2, Segment = 3, Tag = 4 }; - /// Pointer to the object - const CanvasObject_sV* ptr; - /// Distance to the object from the search position (e.g. mouse position) - qreal dist; - /// The object type should only be used for sorting! - ObjectType type; - - bool operator <(const PointerWithDistance &other) const { - return type < other.type || (type == other.type && dist < other.dist); - } - PointerWithDistance(const CanvasObject_sV* ptr, qreal dist, ObjectType type) : - ptr(ptr), - dist(dist), - type(type) - { } - }; - - - void setMaxY(qreal time); ///< Sets the maximum y value that is allowed, usually the duration of the input. - - qreal sourceTime(qreal targetTime) const; ///< Calculates the source time in seconds for the given output time. - qreal startTime(bool useMoved = false) const; ///< Time of the first node. useMoved uses the unconfirmed position of the node while it is moved. - qreal endTime(bool useMoved = false) const; ///< Time of the rightmost node. See totalTime() for the curve length. - qreal totalTime() const; ///< Length of the curve, ignores space (startTime())at the beginning. - bool isInsideCurve(qreal targetTime, bool useMoved = false) const; ///< Returns true if startTime <= targetTime <= endTime - - /** - Add a new node at the given position. - @return true if the node has been added. The node is NOT added - if it is too close to another node. - */ - bool add(Node_sV node); - uint deleteSelected(); - void deleteNode(int index); - - void select(const Node_sV *node, bool newSelection = true); - void unselectAll(); - - void shift(qreal after, qreal by); - /** - Move the selected nodes by the given time vector. - Only succeeds if the nodes are still within valid bounds. - A move has to be either confirmed or aborted. - */ - void moveSelected(const Node_sV &time); - /** - Confirm the move on all nodes. - */ - void confirmMove(); - /** - Abort the move on all nodes. Resets the temporary movement vector. - */ - void abortMove(); - - void moveHandle(const NodeHandle_sV *handle, Node_sV relPos); - - /// Sets the curve type for the segment at time \c segmentTime. - void setCurveType(qreal segmentTime, CurveType type); - - void fixHandles(int leftIndex); - - void setSpeed(qreal segmentTime, qreal speed); - - - - /** - \brief Returns the \c node's index in the node list - \return -1 if the node could not be located - */ - int indexOf(const Node_sV *node) const; - /** - @return The position of the node whose target time (x()) is <= time, - or -1 if there is no such node. - */ - int find(qreal time) const; - - /** - @return The position of the first node in the list which is within a radius - of \c tdelta around the point <tt>(tx|ty)</tt>, or -1 if no such node exists. - */ - int find(QPointF pos, qreal tdelta) const; - /** - \brief Searches for a segment (or path) between two nodes at time \c tx. - - If a left or right node does not exist (when \c tx is outside of the curve), the return - value for this index is -1. - */ - void findBySegment(qreal tx, int& leftIndex_out, int& rightIndex_out) const; - /** - \brief Searches for node objects (nodes, handles, and segments) around a position. - \param pos Center of the search position. - \param tmaxdist This is the search radius. Elements are included if their euclidian distance - to \c pos is <= tmaxdist, except for segments where only the x position is taken into account. - */ - QList<PointerWithDistance> objectsNear(QPointF pos, qreal tmaxdist) const; - - /** - @return The index of the node whose time is equal or greater than - the given time, or -1 if there is no such node. - */ - int nodeAfter(qreal time) const; - - const Node_sV& at(int i) const; - Node_sV& operator (int i); - int size() const; - - /** - @return false if nodes are not in a valid position. - Nodes must be ordered, and the minimum distance (on the y axis) - must be at least m_minDist. - */ - bool validate() const; - - SegmentList_sV* segments(); - -private: - qreal m_maxY; - QList<Node_sV> m_list; - SegmentList_sV m_segments; - const float m_minDist; - - qreal bezierSourceTime(qreal targetTime, QPointF p0, QPointF p1, QPointF p2, QPointF p3) const; - inline qreal dist2(QPointF point) const; -}; - -QDebug operator<<(QDebug qd, const NodeList_sV &list); - -#endif // NODELIST_SV_H
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/project/projectPreferences_sV.cpp
Deleted
@@ -1,68 +0,0 @@ -#include "projectPreferences_sV.h" -#include <QtCore/QDir> - -ProjectPreferences_sV::ProjectPreferences_sV() : - m_tagAxis(TagAxis_Source), - m_viewport_t0(0, 0), - m_viewport_secRes(50, 50), - m_canvas_xAxisFPS(24), - m_renderSectionMode("full"), - m_renderFrameSize(FrameSize_Orig), - m_renderInterpolationType(InterpolationType_TwowayNew), - m_motionblurType(MotionblurType_Convolving), - m_renderFPS(24), - m_imagesOutputDir(QDir::homePath()), - m_imagesFilenamePattern("rendered-%1.jpg"), - m_videoFilename("/tmp/rendered.mpg"), - m_flowV3DLambda(20.0) -{ -} - -TagAxis& ProjectPreferences_sV::lastSelectedTagAxis() -{ - return m_tagAxis; -} - -QPointF& ProjectPreferences_sV::viewport_secRes() -{ - return m_viewport_secRes; -} -QPointF& ProjectPreferences_sV::viewport_t0() -{ - return m_viewport_t0; -} -Fps_sV& ProjectPreferences_sV::canvas_xAxisFPS() -{ - return m_canvas_xAxisFPS; -} - -FrameSize& ProjectPreferences_sV::renderFrameSize() -{ - return m_renderFrameSize; -} -InterpolationType& ProjectPreferences_sV::renderInterpolationType() -{ - return m_renderInterpolationType; -} -MotionblurType& ProjectPreferences_sV::renderMotionblurType() -{ - return m_motionblurType; -} - -QString& ProjectPreferences_sV::renderSectionMode() { return m_renderSectionMode; } -QString& ProjectPreferences_sV::renderStartTag() { return m_renderStartTag; } -QString& ProjectPreferences_sV::renderEndTag() { return m_renderEndTag; } -QString& ProjectPreferences_sV::renderStartTime() { return m_renderStartTime; } -QString& ProjectPreferences_sV::renderEndTime() { return m_renderEndTime; } - -Fps_sV& ProjectPreferences_sV::renderFPS() { return m_renderFPS; } -QString& ProjectPreferences_sV::renderTarget() { return m_renderTarget; } - -QString& ProjectPreferences_sV::imagesOutputDir() { return m_imagesOutputDir; } -QString& ProjectPreferences_sV::imagesFilenamePattern() { return m_imagesFilenamePattern; } - -QString& ProjectPreferences_sV::videoFilename() { return m_videoFilename; } -QString& ProjectPreferences_sV::videoCodec() { return m_vcodec; } - -float& ProjectPreferences_sV::flowV3DLambda() { return m_flowV3DLambda; } -
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/project/projectPreferences_sV.h
Deleted
@@ -1,66 +0,0 @@ -#ifndef PROJECTPREFERENCES_SV_H -#define PROJECTPREFERENCES_SV_H - -#include "../lib/defs_sV.hpp" -class ProjectPreferences_sV -{ -public: - ProjectPreferences_sV(); - - /** - \return Reference to the previously selected tag axis - */ - TagAxis& lastSelectedTagAxis(); - QPointF& viewport_t0(); - QPointF& viewport_secRes(); - - Fps_sV& canvas_xAxisFPS(); - - // Rendering - QString& renderSectionMode(); - QString& renderStartTag(); - QString& renderEndTag(); - QString& renderStartTime(); - QString& renderEndTime(); - FrameSize& renderFrameSize(); - InterpolationType& renderInterpolationType(); - MotionblurType& renderMotionblurType(); - Fps_sV& renderFPS(); - QString& renderTarget(); - QString& imagesOutputDir(); - QString& imagesFilenamePattern(); - QString& videoFilename(); - QString& videoCodec(); - - float& flowV3DLambda(); - - -private: - TagAxis m_tagAxis; - QPointF m_viewport_t0; - QPointF m_viewport_secRes; - - Fps_sV m_canvas_xAxisFPS; - - QString m_renderSectionMode; - QString m_renderStartTag; - QString m_renderEndTag; - QString m_renderStartTime; - QString m_renderEndTime; - FrameSize m_renderFrameSize; - InterpolationType m_renderInterpolationType; - MotionblurType m_motionblurType; - Fps_sV m_renderFPS; - QString m_renderTarget; - - QString m_imagesOutputDir; - QString m_imagesFilenamePattern; - QString m_videoFilename; - QString m_vcodec; - - float m_flowV3DLambda; - - -}; - -#endif // PROJECTPREFERENCES_SV_H
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/project/project_sV.cpp
Deleted
@@ -1,395 +0,0 @@ -/* -This file is part of slowmoVideo. -Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. -*/ - -#include "project_sV.h" -#include "projectPreferences_sV.h" -#include "videoFrameSource_sV.h" -#include "emptyFrameSource_sV.h" -#include "flowSourceV3D_sV.h" -#include "flowSourceOpenCV_sV.h" -#include "interpolator_sV.h" -#include "motionBlur_sV.h" -#include "nodeList_sV.h" -#include "renderTask_sV.h" -#include "shutterFunction_sV.h" -#include "shutterFunctionList_sV.h" -#include "../lib/shutter_sV.h" -#include "../lib/interpolate_sV.h" -#include "../lib/flowRW_sV.h" -#include "../lib/flowField_sV.h" - -#include <cmath> - -#include <QDebug> -#include <QFile> -#include <QFileInfo> -#include <QSettings> - -//#define DEBUG_P -#ifdef DEBUG_P -#include <iostream> -#endif - - -#define MIN_FRAME_DIST .001 - -Project_sV::Project_sV() : - m_projDir(QDir::temp()) -{ - init(); -} - -Project_sV::Project_sV(QString projectDir) : - m_projDir(projectDir) -{ - init(); - - // Create directory if necessary - qDebug() << "Project directory: " << m_projDir.absolutePath(); - if (!m_projDir.exists()) { - m_projDir.mkpath("."); - } -} - -void Project_sV::init() -{ - m_preferences = new ProjectPreferences_sV(); - m_frameSource = new EmptyFrameSource_sV(this); - m_flowSource = new FlowSourceV3D_sV(this); - m_motionBlur = new MotionBlur_sV(this); - - QSettings settings; - if (settings.value("preferences/flowMethod", "V3D").toString() == "V3D") { - m_flowSource = new FlowSourceV3D_sV(this); - } else { - m_flowSource = new FlowSourceOpenCV_sV(this); - } - - m_tags = new QList<Tag_sV>(); - m_nodes = new NodeList_sV(); - m_shutterFunctions = new ShutterFunctionList_sV(m_nodes); - m_renderTask = NULL; - - m_v3dFailCounter = 0; -} - -Project_sV::~Project_sV() -{ - delete m_preferences; - delete m_frameSource; - delete m_flowSource; - delete m_motionBlur; - delete m_tags; - delete m_nodes; - delete m_renderTask; - delete m_shutterFunctions; -} - -void Project_sV::reloadFlowSource() -{ - Q_ASSERT(m_flowSource != NULL); - - delete m_flowSource; - - QSettings settings; - if (settings.value("preferences/flowMethod", "V3D").toString() == "V3D") { - m_flowSource = new FlowSourceV3D_sV(this); - } else { - m_flowSource = new FlowSourceOpenCV_sV(this); - } -} - -void Project_sV::setProjectDir(QString projectDir) -{ - m_projDir = projectDir; - // Create directory if necessary - qDebug() << "Project directory: " << m_projDir.absolutePath(); - if (!m_projDir.exists()) { - m_projDir.mkpath("."); - } - m_frameSource->slotUpdateProjectDir(); - m_flowSource->slotUpdateProjectDir(); - m_motionBlur->slotUpdateProjectDir(); -} - -void Project_sV::setProjectFilename(QString filename) -{ - m_projectFilename = filename; -} -QString Project_sV::projectFilename() const { - return m_projectFilename; -} - -void Project_sV::loadFrameSource(AbstractFrameSource_sV *frameSource) -{ - if (m_frameSource != NULL) { - delete m_frameSource; - } - if (frameSource == NULL) { - m_frameSource = new EmptyFrameSource_sV(this); - } else { - m_frameSource = frameSource; - } - m_nodes->setMaxY(m_frameSource->maxTime()); -} - -void Project_sV::replaceRenderTask(RenderTask_sV *task) -{ - if (m_renderTask != NULL) { - m_renderTask->slotStopRendering(); - m_renderTask->deleteLater(); - m_renderTask = NULL; - } - m_renderTask = task; -} - -const QDir Project_sV::getDirectory(const QString &name, bool createIfNotExists) const -{ - QDir dir(m_projDir.absolutePath() + "/" + name); - if (createIfNotExists && !dir.exists()) { - dir.mkpath("."); - } - return dir; -} - -QImage Project_sV::render(qreal outTime, RenderPreferences_sV prefs) -{ - if (outTime < m_nodes->startTime() || outTime > m_nodes->endTime()) { -#ifdef DEBUG_P - std::cout.precision(30); - std::cout << m_nodes->startTime() << " -- " << outTime << " -- " << m_nodes->endTime() << std::endl; - std::cout.flush(); -#endif - qDebug() << "Output time out of bounds"; - Q_ASSERT(false); - } - - float sourceTime = m_nodes->sourceTime(outTime); - if (sourceTime < 0) { - sourceTime = 0; - } - if (sourceTime > m_frameSource->maxTime()) { - sourceTime = m_frameSource->maxTime(); - } - - float sourceFrame = sourceTimeToFrame(sourceTime); - - int leftIndex = m_nodes->find(outTime); - if (leftIndex < 0) { - qDebug() << "left node is not here!"; - Q_ASSERT(false); - } - if (leftIndex == m_nodes->size()-1) { - // outTime is at the very end of the node. - // Take next to last node to still have a right node. - leftIndex--; - } - - const Node_sV *leftNode = &(*m_nodes)leftIndex; - const Node_sV *rightNode = &(*m_nodes)leftIndex+1; - - ShutterFunction_sV *shutterFunction = m_shutterFunctions->function(leftNode->shutterFunctionID()); - - if (shutterFunction != NULL) { - float dy = 0; - if (outTime+1/prefs.fps().fps() <= m_nodes->endTime()) { - dy = m_nodes->sourceTime(outTime+1/prefs.fps().fps()) - sourceTime; - } else { - dy = sourceTime - m_nodes->sourceTime(outTime-1/prefs.fps().fps()); - } - float replaySpeed = fabs(dy)*prefs.fps().fps(); - float shutter = shutterFunction->evaluate( - (outTime-leftNode->x())/(rightNode->x()-leftNode->x()), // x on 0,1 - outTime, // t - prefs.fps().fps(), // FPS - sourceFrame, // y - dy // dy to next frame - ); - qDebug() << "Shutter value for output time " << outTime << " is " << shutter; - if (shutter > 0) { - try { - return m_motionBlur->blur(sourceFrame, sourceFrame+shutter*prefs.fps().fps(), - replaySpeed, - prefs); - } catch (RangeTooSmallError_sV &err) {} - } - } - return Interpolator_sV::interpolate(this, sourceFrame, prefs); -} - -FlowField_sV* Project_sV::requestFlow(int leftFrame, int rightFrame, const FrameSize frameSize) throw(FlowBuildingError) -{ - Q_ASSERT(leftFrame < m_frameSource->framesCount()); - Q_ASSERT(rightFrame < m_frameSource->framesCount()); - if (dynamic_cast<EmptyFrameSource_sV*>(m_frameSource) == NULL) { - - FlowSourceV3D_sV *v3d; - if ((v3d = dynamic_cast<FlowSourceV3D_sV*>(m_flowSource)) != NULL) { - v3d->setLambda(m_preferences->flowV3DLambda()); - try { - return m_flowSource->buildFlow(leftFrame, rightFrame, frameSize); - } catch (FlowBuildingError err) { - m_v3dFailCounter++; - qDebug() << "Failed creating optical flow, falling back to OpenCV ..."; - qDebug() << "Failed attempts so far: " << m_v3dFailCounter; - delete m_flowSource; - m_flowSource = new FlowSourceOpenCV_sV (this); - return m_flowSource->buildFlow(leftFrame, rightFrame, frameSize); - } - } - return m_flowSource->buildFlow(leftFrame, rightFrame, frameSize); - } else { - throw FlowBuildingError(tr("Empty frame source; Cannot build flow.")); - } -} - -inline -qreal Project_sV::sourceTimeToFrame(qreal time) const -{ - Q_ASSERT(time >= 0); - return time * m_frameSource->fps()->fps(); -} - -qreal Project_sV::snapToFrame(const qreal time, bool roundUp, const Fps_sV &fps, int *out_framesBeforeHere) -{ - Q_ASSERT(time >= 0); - int frameCount = 0; - double snapTime = 0; - double frameLength; - frameLength = 1.0/fps.fps(); - - while (snapTime < time) { - snapTime += frameLength; - frameCount++; - } - - // snapTime is now >= time - - if (!roundUp && snapTime != time) { - snapTime -= frameLength; - frameCount--; - } - - if (out_framesBeforeHere != NULL) { - *out_framesBeforeHere = frameCount; - } - - return snapTime; -} -qreal Project_sV::snapToOutFrame(qreal time, bool roundUp, const Fps_sV &fps, int *out_framesBeforeHere) const -{ - if (time > m_nodes->endTime()) { - time = m_nodes->endTime(); - } - time -= m_nodes->startTime(); - if (time < 0) { time = 0; } - float snapped = snapToFrame(time, roundUp, fps, out_framesBeforeHere) + m_nodes->startTime(); - return snapped; -} -qreal Project_sV::toOutTime(QString timeExpression, const Fps_sV &fps) const throw(Error_sV) -{ - if (m_nodes->size() < 2) { - throw Error_sV(tr("Not enough nodes available in the project.")); - } - - // t:time l:label f:frame p:percent :start :end time - bool ok = false; - qreal time = 0; - if (timeExpression.startsWith("t:")) { - time = timeExpression.mid(2).toDouble(&ok); - if (!ok) { - throw Error_sV(tr("%1 is not a valid time. Format: t:123.45").arg(timeExpression)); - } - } else if (timeExpression.startsWith("l:")) { - QString label = timeExpression.mid(2); - bool inputAxisFound = false; - for (int i = 0; i < m_tags->size(); i++) { - if (m_tags->at(i).description() == label) { - if (m_tags->at(i).axis() == TagAxis_Output) { - time = m_tags->at(i).time(); - ok = true; - break; - } else { - inputAxisFound = true; - } - } - } - if (!ok) { - if (inputAxisFound) { - throw Error_sV(tr("%1 is an input label and not an output label and cannot be used for rendering.").arg(label)); - } else { - throw Error_sV(tr("No label found for %1").arg(timeExpression)); - } - } - } else if (timeExpression.startsWith("f:")) { - int frame = timeExpression.mid(2).toInt(&ok); - if (ok) { - time = frame / fps.fps(); - } else { - throw Error_sV(tr("%1 is not a valid frame number. Format: f:1234").arg(timeExpression)); - } - } else if (timeExpression.startsWith("p:")) { - QString sPercent = timeExpression.mid(2).trimmed(); - if (sPercent.endsWith("%")) { - sPercent.chop(1); - } - float percent = sPercent.toFloat(&ok); - if (ok) { - if (percent >= 0 && percent <= 100) { - time = m_nodes->startTime() + m_nodes->totalTime()*percent/100; - } else { - throw Error_sV(tr("%1 is not a valid percentage number; must be between 0 and 100.").arg(percent)); - } - } else { - throw Error_sV(tr("%1 is not a valid percentage expression. Format: p:0% until p:100.0%").arg(timeExpression)); - } - } else if (timeExpression.startsWith(":")) { - if (":start" == timeExpression) { - time = m_nodes->startTime(); - } else if (":end" == timeExpression) { - time = m_nodes->endTime(); - } else { - throw Error_sV(tr("%1 is not a valid position. Valid: :start and :end").arg(timeExpression)); - } - } else { - time = timeExpression.toDouble(&ok); - if (!ok) { - throw Error_sV(tr("Not a valid time format. Options: t:1.25 or 1.25 (time), f:1234 (frame), " - "l:slowdown (label), p:42.42% (percentage), :start and :end (project start/end).")); - } - } - - time = qMax(time, m_nodes->startTime()); - time = qMin(time, m_nodes->endTime()); - - return time; -} - -QList<NodeList_sV::PointerWithDistance> Project_sV::objectsNear(QPointF pos, qreal tmaxdist) const -{ - QList<NodeList_sV::PointerWithDistance> list = m_nodes->objectsNear(pos, tmaxdist); - - qreal dist; - for (int i = 0; i < m_tags->size(); i++) { - if (m_tags->at(i).axis() == TagAxis_Source) { - dist = fabs(pos.y() - m_tags->at(i).time()); - } else { - dist = fabs(pos.x() - m_tags->at(i).time()); - } - if (dist <= tmaxdist) { - list << NodeList_sV::PointerWithDistance(&m_tags->at(i), dist, NodeList_sV::PointerWithDistance::Tag); - } - } - - qSort(list); - - return list; -} -
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/project/project_sV.h
Deleted
@@ -1,153 +0,0 @@ -/* -This file is part of slowmoVideo. -Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. -*/ - -#ifndef PROJECT_SV_H -#define PROJECT_SV_H - -#include "tag_sV.h" -#include "nodeList_sV.h" -#include "renderPreferences_sV.h" -#include "../lib/defs_sV.hpp" -extern "C" { -#include "../lib/videoInfo_sV.h" -} - -#include <QtCore/QObject> -#include <QtCore/QFile> -#include <QtCore/QDir> -#include <QtGui/QImage> - -class ProjectPreferences_sV; -class Flow_sV; -class AbstractFrameSource_sV; -class AbstractFlowSource_sV; -class MotionBlur_sV; -class ShutterFunctionList_sV; -class RenderTask_sV; -class FlowField_sV; -class QSignalMapper; -class QProcess; -class QRegExp; -class QTimer; - -/** - \brief slowmoVideo project holding all important information. - \todo Check if width%4 == 0 for V3D - */ -class Project_sV : public QObject -{ - Q_OBJECT - -public: - /** Creates an empty project. A video file can be loaded with loadFile(QString, QString). */ - Project_sV(); - /** - Creates a new project. - \param filename Input video file - \param projectDir Project directory; All cached files will be put in there. - */ - Project_sV(QString projectDir); - ~Project_sV(); - - ProjectPreferences_sV* preferences() { return m_preferences; } - - void setProjectDir(QString projectDir); - /** The project filename should be set when saving or loading the project. */ - void setProjectFilename(QString filename); - /** \return The filename this project was last saved as. */ - QString projectFilename() const; - - /** \param frameSource will be managed (deleted) by the project. If \c NULL, an empty frame source will be used. */ - void loadFrameSource(AbstractFrameSource_sV *frameSource); - - AbstractFrameSource_sV* frameSource() { return m_frameSource; } - AbstractFlowSource_sV* flowSource() { return m_flowSource; } - NodeList_sV *nodes() const { return m_nodes; } - QList<Tag_sV> *tags() const { return m_tags; } - ShutterFunctionList_sV* shutterFunctions() { return m_shutterFunctions; } - MotionBlur_sV *motionBlur() { return m_motionBlur; } - - /** \see replaceRenderTask() */ - RenderTask_sV *renderTask() { return m_renderTask; } - void replaceRenderTask(RenderTask_sV *task); - - - /** - \fn snapToFrame() - \brief Snaps in the given time on a grid given by the number of frames per second. - This allows to, for example, render from 0 to 3.2 seconds and then from 3.2 to 5 seconds - to images with the same effect as rendering all at once. Always starts from 0! - \param time Time to snap in - \param roundUp To chose between rounding up or down - \param fps Frames per second to use. - */ - /** - \fn toOutTime() - \brief Converts a time expression like \c f:123 or \c :start to an output time \c float. - - Accepted input format: - \li \c 24.3 or \c t:24.3 for 24.3 seconds - \li \c f:123 for frame 123 - \li \c p:25% for 25 % - \li \c l:slowdown for the slowdown label (tag) - \li \c :start and \c :end for project start/end - */ - static qreal snapToFrame(const qreal time, bool roundUp, const Fps_sV& fps, int* out_framesBeforeHere); - qreal snapToOutFrame(qreal time, bool roundUp, const Fps_sV& fps, int* out_framesBeforeHere) const; - qreal toOutTime(QString timeExpression, const Fps_sV& fps) const throw(Error_sV); - - - const QDir getDirectory(const QString &name, bool createIfNotExists = true) const; - - QImage render(qreal outTime, RenderPreferences_sV prefs); - - FlowField_sV* requestFlow(int leftFrame, int rightFrame, const FrameSize frameSize) throw(FlowBuildingError); - - /** - \brief Searches for objects near the given \c pos. - This search includes tags. - \see NodeList_sV::objectsNear() Used by this method. Does not include tags. - */ - QList<NodeList_sV::PointerWithDistance> objectsNear(QPointF pos, qreal tmaxdist) const; - - -public: - /// Reload the flow source in case the user changed the default (preferred) method. - void reloadFlowSource(); - - - -private: - QDir m_projDir; - QString m_projectFilename; - - ProjectPreferences_sV *m_preferences; - - AbstractFrameSource_sV *m_frameSource; - AbstractFlowSource_sV *m_flowSource; - MotionBlur_sV *m_motionBlur; - - NodeList_sV *m_nodes; - QList<Tag_sV> *m_tags; - RenderTask_sV *m_renderTask; - ShutterFunctionList_sV *m_shutterFunctions; - - qreal sourceTimeToFrame(qreal time) const; - - void init(); - -private: - /// Count how many times V3D failed, after a certain limit we assume the user does not have an nVidia card - /// and constantly switch to OpenCV - int m_v3dFailCounter; - -}; - -#endif // PROJECT_SV_H
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/project/renderTask_sV.cpp
Deleted
@@ -1,173 +0,0 @@ -/* -This file is part of slowmoVideo. -Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. -*/ - -#include "renderTask_sV.h" -#include "abstractRenderTarget_sV.h" -#include "emptyFrameSource_sV.h" - -#include <QImage> -#include <QMetaObject> -#include "project_sV.h" -#include "nodeList_sV.h" -#include "../lib/defs_sV.hpp" - -RenderTask_sV::RenderTask_sV(Project_sV *project) : - m_project(project), - m_renderTarget(NULL), - m_renderTimeElapsed(0), - m_initialized(false), - m_stopRendering(false), - m_prevTime(-1), - m_connectionType(Qt::QueuedConnection) -{ - m_timeStart = m_project->nodes()->startTime(); - m_timeEnd = m_project->nodes()->endTime(); - - m_nextFrameTime = m_project->nodes()->startTime(); -} - -RenderTask_sV::~RenderTask_sV() -{ - if (m_renderTarget != NULL) { delete m_renderTarget; } -} - -void RenderTask_sV::setRenderTarget(AbstractRenderTarget_sV *renderTarget) -{ - Q_ASSERT(renderTarget != NULL); - - if (m_renderTarget != NULL && m_renderTarget != renderTarget) { - delete m_renderTarget; - } - m_renderTarget = renderTarget; -} - -void RenderTask_sV::setTimeRange(qreal start, qreal end) -{ - Q_ASSERT(start <= end); - Q_ASSERT(start >= m_project->nodes()->startTime()); - Q_ASSERT(end <= m_project->nodes()->endTime()); - - m_timeStart = start; - m_timeEnd = end; -} - -void RenderTask_sV::setTimeRange(QString start, QString end) -{ - Q_ASSERT(m_prefs.fpsSetByUser()); - m_timeStart = m_project->toOutTime(start, m_prefs.fps()); - m_timeEnd = m_project->toOutTime(end, m_prefs.fps()); - Q_ASSERT(m_timeStart < m_timeEnd); -} - -QSize RenderTask_sV::resolution() -{ - return const_cast<Project_sV*>(m_project)->frameSource()->frameAt(0, m_prefs.size).size(); -} - -void RenderTask_sV::setQtConnectionType(Qt::ConnectionType type) -{ - m_connectionType = type; -} - -void RenderTask_sV::slotStopRendering() -{ - m_stopRendering = true; -} - -void RenderTask_sV::slotContinueRendering() -{ - m_stopRendering = false; - if (m_nextFrameTime < m_timeStart) { - m_nextFrameTime = m_timeStart; - int framesBefore; - qreal snapped = m_project->snapToOutFrame(m_nextFrameTime, false, m_prefs.fps(), &framesBefore); - qDebug() << "Frame snapping in from " << m_nextFrameTime << " to " << snapped; - m_nextFrameTime = snapped; - - Q_ASSERT(int((m_nextFrameTime - m_project->nodes()->startTime()) * m_prefs.fps().fps() + .5) == framesBefore); - } - if (!m_initialized) { - try { - m_renderTarget->openRenderTarget(); - m_initialized = true; - } catch (Error_sV &err) { - m_stopRendering = true; - emit signalRenderingAborted(tr("Rendering aborted.") + " " + err.message()); - return; - } - } - qDebug() << "Continuing rendering at " << m_nextFrameTime; - - m_stopwatch.start(); - emit signalRenderingContinued(); - emit signalNewTask(trUtf8("Rendering Slow-Mo …"), int(m_prefs.fps().fps() * (m_timeEnd-m_timeStart))); - bool b = QMetaObject::invokeMethod(this, "slotRenderFrom", m_connectionType, Q_ARG(qreal, m_nextFrameTime)); - if (!b) { - qDebug() << "invokeMethod returned false."; - } -} - -void RenderTask_sV::slotRenderFrom(qreal time) -{ - if (m_renderTarget == NULL) { - m_stopRendering = true; - emit signalRenderingAborted(tr("No rendering target given! Aborting rendering.")); - return; - } - if (dynamic_cast<EmptyFrameSource_sV*>(const_cast<Project_sV*>(m_project)->frameSource()) != NULL) { - m_stopRendering = true; - emit signalRenderingAborted(tr("Empty frame source, cannot be rendered.")); - } - - int outputFrame = (time - m_project->nodes()->startTime()) * m_prefs.fps().fps() + .5; - if (!m_stopRendering) { - - if (time > m_timeEnd) { - m_stopRendering = true; - m_renderTarget->closeRenderTarget(); - m_renderTimeElapsed += m_stopwatch.elapsed(); - emit signalRenderingFinished(QTime().addMSecs(m_renderTimeElapsed).toString("hh:mm:ss")); - qDebug() << "Rendering stopped after " << QTime().addMSecs(m_renderTimeElapsed).toString("hh:mm:ss"); - - } else { - qreal srcTime = m_project->nodes()->sourceTime(time); - - qDebug() << "Rendering frame number " << outputFrame << " @" << time << " from source time " << srcTime; - emit signalItemDesc(tr("Rendering frame %1 @ %2 s from input position: %3 s (frame %4)") - .arg(outputFrame).arg(time).arg(srcTime).arg(srcTime*m_project->frameSource()->fps()->fps())); - try { - QImage rendered = m_project->render(time, m_prefs); - - m_renderTarget->slotConsumeFrame(rendered, outputFrame); - m_nextFrameTime = time + 1/m_prefs.fps().fps(); - - emit signalTaskProgress( (time-m_timeStart) * m_prefs.fps().fps() ); - emit signalFrameRendered(time, outputFrame); - } catch (FlowBuildingError &err) { - m_stopRendering = true; - emit signalRenderingAborted(err.message()); - } catch (InterpolationError &err) { - emit signalItemDesc(err.message()); - } - - m_prevTime = srcTime; - } - - } else { - m_renderTarget->closeRenderTarget(); - m_renderTimeElapsed += m_stopwatch.elapsed(); - emit signalRenderingStopped(QTime().addMSecs(m_renderTimeElapsed).toString("hh:mm:ss")); - qDebug() << "Rendering stopped after " << QTime().addMSecs(m_renderTimeElapsed).toString("hh:mm:ss"); - } - if (!m_stopRendering) { - QMetaObject::invokeMethod(this, "slotRenderFrom", m_connectionType, Q_ARG(qreal, m_nextFrameTime)); - } -} -
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/project/renderTask_sV.h
Deleted
@@ -1,112 +0,0 @@ -/* -This file is part of slowmoVideo. -Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. -*/ - -#ifndef RENDERTASK_SV_H -#define RENDERTASK_SV_H - -#include <QtCore/QObject> -#include <QtCore/QTime> - -#include "renderPreferences_sV.h" - -class Project_sV; -class AbstractRenderTarget_sV; - -/** - \brief Renders a project when started. - */ -class RenderTask_sV : public QObject -{ - Q_OBJECT -public: - RenderTask_sV(Project_sV *project); - ~RenderTask_sV(); - - /** - \fn setRenderTarget() - \brief Manages the \c renderTarget pointer (includes destruction). - */ - /** - \fn setTimeRange(qreal, qreal) - \brief Sets the time range (in seconds) for rendering. By default, the whole project is rendered. - \todo Accept other formats: f:123 for frames, t:Tag for tags, :start/:end for project start/end - */ - /** - \fn setTimeRange(QString, QString) - \brief Sets the time range for rendering. - - Note that setFPS() has to be called \i before this function is called. - - Accepted input format is described in Project_sV::toOutTime(). - */ - /** - \fn setFPS() - Sets the number of frames per second for rendering. - */ - /** - \fn setSize() - Sets the size to use for rendering. - */ - void setRenderTarget(AbstractRenderTarget_sV *renderTarget); - void setTimeRange(qreal start, qreal end); - void setTimeRange(QString start, QString end); - - void setQtConnectionType(Qt::ConnectionType type); - - /// Rendered frames per second - Fps_sV fps() { return m_prefs.fps(); } - /// Output frame resolution - QSize resolution(); - - RenderPreferences_sV& renderPreferences() { return m_prefs; } - - -public slots: - void slotContinueRendering(); - void slotStopRendering(); - // reset? - -signals: - void signalNewTask(QString desc, int taskSize); - void signalItemDesc(QString desc); - void signalTaskProgress(int value); - void signalRenderingContinued(); - void signalRenderingStopped(QString renderTime); - void signalRenderingFinished(QString renderTime); - void signalRenderingAborted(QString reason); - - void signalFrameRendered(qreal time, int frameNumber); - -private: - Project_sV *m_project; - RenderPreferences_sV m_prefs; ///< \todo Set preferences - - AbstractRenderTarget_sV *m_renderTarget; - - qreal m_timeStart; - qreal m_timeEnd; - - QTime m_stopwatch; - int m_renderTimeElapsed; - - bool m_initialized; - bool m_stopRendering; - qreal m_nextFrameTime; - - qreal m_prevTime; - - Qt::ConnectionType m_connectionType; - -private slots: - void slotRenderFrom(qreal time); - -}; - -#endif // RENDERTASK_SV_H
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/project/videoFrameSource_sV.cpp
Deleted
@@ -1,273 +0,0 @@ -/* -This file is part of slowmoVideo. -Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. -*/ - -#include "videoFrameSource_sV.h" -#include "project_sV.h" - -#include <QtCore/QProcess> -#include <QtCore/QTimer> -#include <QtCore/QRegExp> - -QRegExp VideoFrameSource_sV::regexFrameNumber("frame=\\s*(\\d+)"); - -/// \todo Check QProcess::exitCode() to find out if ffmpeg worked or not -VideoFrameSource_sV::VideoFrameSource_sV(const Project_sV *project, const QString &filename) -throw(FrameSourceError) : - AbstractFrameSource_sV(project), - m_inFile(filename), - m_fps(1,1), - m_ffmpegSemaphore(1), - m_initialized(false) -{ - if (!QFileInfo(filename).exists()) { - throw FrameSourceError(tr("Video file %1 does not exist!").arg(filename)); - } - - m_videoInfo = new VideoInfoSV(); - // use copy constructor - *m_videoInfo = getInfo(filename.toStdString().c_str()); - - if (m_videoInfo->streamsCount <= 0) { - qDebug() << "Video info is invalid: " << filename; - throw FrameSourceError(tr("Video is invalid, no streams found in %1").arg(filename)); - } - m_fps = Fps_sV(m_videoInfo->frameRateNum, m_videoInfo->frameRateDen); - - - - createDirectories(); - locateFFmpeg(); - - m_ffmpeg = new QProcess(this); - m_timer = new QTimer(this); - - bool b = true; - b &= connect(m_timer, SIGNAL(timeout()), this, SLOT(slotProgressUpdate())); - Q_ASSERT(b); -} -VideoFrameSource_sV::~VideoFrameSource_sV() -{ - delete m_ffmpeg; - delete m_timer; - delete m_videoInfo; -} - - -void VideoFrameSource_sV::slotUpdateProjectDir() -{ - // Delete old directories if they are empty - m_dirFramesSmall.rmdir("."); - m_dirFramesOrig.rmdir("."); - createDirectories(); -} - -void VideoFrameSource_sV::createDirectories() -{ - m_dirFramesSmall = project()->getDirectory("frames/small"); - m_dirFramesOrig = project()->getDirectory("frames/orig"); -} - -void VideoFrameSource_sV::initialize() -{ - if (!initialized()) { - // Start the frame extraction process - slotExtractSmallFrames(); - } -} -bool VideoFrameSource_sV::initialized() const -{ - return m_initialized; -} - -int64_t VideoFrameSource_sV::framesCount() const -{ - return m_videoInfo->framesCount; -} -const Fps_sV* VideoFrameSource_sV::fps() const -{ - return &m_fps; -} -QImage VideoFrameSource_sV::frameAt(const uint frame, const FrameSize frameSize) -{ - return QImage(framePath(frame, frameSize)); -} -const QString VideoFrameSource_sV::videoFile() const -{ - return m_inFile.fileName(); -} - -const QString VideoFrameSource_sV::framePath(const uint frame, const FrameSize frameSize) const -{ - QString dir; - switch (frameSize) { - case FrameSize_Orig: - dir = m_dirFramesOrig.absolutePath(); - break; - case FrameSize_Small: - default: - dir = m_dirFramesSmall.absolutePath(); - break; - } - - // ffmpeg numbering starts with 1, therefore add 1 to the frame number - return QString("%1/frame%2.png").arg(dir).arg(frame+1, 5, 10, QChar::fromAscii('0')); -} - -void VideoFrameSource_sV::extractFramesFor(const FrameSize frameSize, QProcess *process) -{ - QStringList args; - args << "-i" << m_inFile.fileName(); - args << "-f" << "image2"; - - if (frameSize == FrameSize_Small) { - int w = m_videoInfo->width; - int h = m_videoInfo->height; - while (w > 600) { - w /= 2; - h /= 2; - } - qDebug() << "Thumbnail frame size: " << w << "x" << h; - args << "-s" << QString("%1x%2").arg(w).arg(h); - args << m_dirFramesSmall.absoluteFilePath("frame%05d.png"); - } else { - args << m_dirFramesOrig.absoluteFilePath("frame%05d.png"); - } - - qDebug() << "Extracting frames with " << m_settings.value("binaries/ffmpeg", "ffmpeg").toString() << args; -// { -// QStringList a2; -// a2 << "-version"; -// process->start(m_settings.value("binaries/ffmpeg").toString());//, "ffmpeg").toString(), a2); -// qDebug() << process->readAllStandardOutput(); -// qDebug() << process->readAllStandardError(); -// process->terminate(); -// } - process->start(m_settings.value("binaries/ffmpeg", "ffmpeg").toString(), args); - qDebug() << process->readAllStandardOutput(); - qDebug() << process->readAllStandardError(); -} - -bool VideoFrameSource_sV::rebuildRequired(const FrameSize frameSize) -{ - bool needsRebuild = false; - - QImage frame = frameAt(0, frameSize); - needsRebuild |= frame.isNull(); - - frame = frameAt(m_videoInfo->framesCount-1, frameSize); - needsRebuild |= frame.isNull(); - - return needsRebuild; -} - -void VideoFrameSource_sV::locateFFmpeg() -{ - if (m_avconvInfo.locate(m_settings.value("binaries/ffmpeg", "").toString())) { - m_settings.setValue("binaries/ffmpeg", m_avconvInfo.executablePath()); - m_settings.sync(); - } else { - throw FrameSourceError(tr("ffmpeg/avconv executable not found! Cannot load video." - "\n(It is also possible that it took a little long to respond " - "due to high workload, so you might want to try again.)" - #ifdef WINDOWS - "\nPlease download the 32-bit static ffmpeg build from ffmpeg.zeranoe.com " - "and extract ffmpeg.exe in the same directory as slowmoUI.exe." - #endif - )); - } -} - -void VideoFrameSource_sV::slotExtractSmallFrames() -{ - emit signalNextTask(tr("Extracting thumbnail-sized frames from the video file"), m_videoInfo->framesCount); - m_timer->start(100); - if (rebuildRequired(FrameSize_Small)) { - - m_ffmpegSemaphore.acquire(); - - m_ffmpeg->waitForFinished(2000); - m_ffmpeg->terminate(); - - disconnect(m_ffmpeg, SIGNAL(finished(int)), this, 0); - bool b = true; - b &= connect(m_ffmpeg, SIGNAL(finished(int)), this, SLOT(slotExtractOrigFrames())); - Q_ASSERT(b); - - extractFramesFor(FrameSize_Small, m_ffmpeg); - - m_ffmpegSemaphore.release(); - - } else { - slotExtractOrigFrames(); - } -} - -void VideoFrameSource_sV::slotExtractOrigFrames() -{ - emit signalNextTask(tr("Extracting original-sized frames from the video file"), m_videoInfo->framesCount); - m_timer->start(100); - if (rebuildRequired(FrameSize_Orig)) { - - m_ffmpegSemaphore.acquire(); - - m_ffmpeg->waitForFinished(2000); - m_ffmpeg->terminate(); - - disconnect(m_ffmpeg, SIGNAL(finished(int)), this, 0); - bool b = true; - b &= connect(m_ffmpeg, SIGNAL(finished(int)), this, SLOT(slotInitializationFinished())); - Q_ASSERT(b); - - extractFramesFor(FrameSize_Orig, m_ffmpeg); - - m_ffmpegSemaphore.release(); - - } else { - slotInitializationFinished(); - } -} - -void VideoFrameSource_sV::slotInitializationFinished() -{ - m_timer->stop(); - emit signalAllTasksFinished(); - - m_ffmpegSemaphore.acquire(); - m_ffmpeg->waitForFinished(2000); - m_ffmpeg->terminate(); - m_ffmpegSemaphore.release(); - - if (!rebuildRequired(FrameSize_Small) && !rebuildRequired(FrameSize_Orig)) { - m_initialized = true; - } -} - -void VideoFrameSource_sV::slotAbortInitialization() -{ - m_ffmpegSemaphore.acquire(); - if (m_ffmpeg != NULL) { - m_ffmpeg->terminate(); - } - m_ffmpegSemaphore.release(); - -} - -void VideoFrameSource_sV::slotProgressUpdate() -{ - QRegExp regex(regexFrameNumber); - QString s; - m_ffmpegSemaphore.acquire(); - s = QString(m_ffmpeg->readAllStandardError()); - if (regex.lastIndexIn(s) >= 0) { - emit signalTaskProgress(regex.cap(1).toInt()); - emit signalTaskItemDescription(tr("Frame %1 of %2").arg(regex.cap(1)).arg(m_videoInfo->framesCount)); - } - m_ffmpegSemaphore.release(); -}
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/project/videoFrameSource_sV.h
Deleted
@@ -1,113 +0,0 @@ -/* -This file is part of slowmoVideo. -Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. -*/ - -#ifndef VIDEOFRAMESOURCE_SV_H -#define VIDEOFRAMESOURCE_SV_H - -#include "abstractFrameSource_sV.h" -#include "../lib/defs_sV.hpp" -#include "../lib/avconvInfo_sV.h" -#include <QtCore/QDir> -#include <QtCore/QFile> -#include <QtCore/QTimer> -#include <QtCore/QSettings> -#include <QtCore/QSemaphore> - -extern "C" { -#include "../lib/videoInfo_sV.h" -} - -class QProcess; -class Project_sV; - -/** - \brief Uses frames from a video file - \todo Use libav directly for frame extraction? (not the ffmpeg command) - \todo Extract full frames only before rendering, only used ones - */ -class VideoFrameSource_sV : public AbstractFrameSource_sV -{ - Q_OBJECT -public: - /** Builds a new video frame source from the given file. */ - VideoFrameSource_sV(const Project_sV *project, const QString &filename) - throw(FrameSourceError); - - ~VideoFrameSource_sV(); - - void initialize(); - bool initialized() const; - - int64_t framesCount() const; - const Fps_sV* fps() const; - QImage frameAt(const uint frame, const FrameSize frameSize = FrameSize_Orig); - const QString framePath(const uint frame, const FrameSize frameSize) const; - - /** \return The absolute path of the input video file. */ - const QString videoFile() const; - -public slots: - void slotAbortInitialization(); - void slotUpdateProjectDir(); - -private: - static QRegExp regexFrameNumber; - -private: - QFile m_inFile; - QDir m_dirFramesSmall; - QDir m_dirFramesOrig; - QSettings m_settings; - AvconvInfo m_avconvInfo; - - VideoInfoSV *m_videoInfo; - Fps_sV m_fps; - - QTimer *m_timer; - QProcess *m_ffmpeg; - QSemaphore m_ffmpegSemaphore; - bool m_initialized; - - - void createDirectories(); - /** - Extracts the frames from the video file into single images - */ - void extractFramesFor(const FrameSize frameSize, QProcess *process); - /** - Checks the availability of the frames and decides - whether they need to be extracted with extractFrames() - */ - bool rebuildRequired(const FrameSize frameSize); - - void locateFFmpeg(); - -public: - static bool testFfmpegExecutable(QString path); - -signals: - /** Emitted when the task for extracting original-sized images has finished (or has been terminated) */ - void signalExtractOrigFramesFinished(); - /** Emitted when the task for extracting thumbnail-sized images has finished (or has been terminated) */ - void signalExtractSmallFramesFinished(); - -private slots: - void slotExtractOrigFrames(); - void slotExtractSmallFrames(); - void slotInitializationFinished(); - /** - Checks the progress of the ffmpeg threads by reading their stderr - and emits signalTaskProgress() and signalTaskItemDescription() if necessary. - */ - void slotProgressUpdate(); - -}; - -#endif // VIDEOFRAMESOURCE_SV_H
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/project/videoRenderTarget_sV.cpp
Deleted
@@ -1,73 +0,0 @@ -/* -This file is part of slowmoVideo. -Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. -*/ - -// Against the «UINT64_C not declared» message. -// See: http://code.google.com/p/ffmpegsource/issues/detail?id=11 -#ifdef __cplusplus - #define __STDC_CONSTANT_MACROS - #ifdef _STDINT_H - #undef _STDINT_H - #endif - # include <stdint.h> -#endif - -#include "videoRenderTarget_sV.h" -#include "renderTask_sV.h" -#include <QtCore/QObject> - -extern "C" { -#include "../lib/ffmpegEncode_sV.h" -} - -VideoRenderTarget_sV::VideoRenderTarget_sV(RenderTask_sV *parentRenderTask) : - AbstractRenderTarget_sV(parentRenderTask) -{ - m_videoOut = (VideoOut_sV*)malloc(sizeof(VideoOut_sV)); -} -VideoRenderTarget_sV::~VideoRenderTarget_sV() -{ - free(m_videoOut); -} - -void VideoRenderTarget_sV::setTargetFile(const QString &filename) -{ - m_filename = filename; -} -void VideoRenderTarget_sV::setVcodec(const QString &codec) -{ - m_vcodec = codec; -} - -void VideoRenderTarget_sV::openRenderTarget() throw(Error_sV) -{ - char *vcodec = NULL; - if (m_vcodec.length() > 0) { - vcodec = (char*)malloc(m_vcodec.length()+1); - strcpy(vcodec, m_vcodec.toStdString().c_str()); - } - int worked = - prepare(m_videoOut, m_filename.toStdString().c_str(), vcodec, - renderTask()->resolution().width(), renderTask()->resolution().height(), - renderTask()->fps().fps() * renderTask()->resolution().width() * renderTask()->resolution().height(), - renderTask()->fps().den, renderTask()->fps().num); - if (worked != 0) { - throw Error_sV(QObject::tr("Video could not be prepared (error code %1).\n%2").arg(worked).arg(m_videoOut->errorMessage)); - } -} - -void VideoRenderTarget_sV::slotConsumeFrame(const QImage &image, const int frameNumber) -{ - eatARGB(m_videoOut, image.bits()); -} - -void VideoRenderTarget_sV::closeRenderTarget() throw(Error_sV) -{ - finish(m_videoOut); -}
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/project/videoRenderTarget_sV.h
Deleted
@@ -1,47 +0,0 @@ -/* -This file is part of slowmoVideo. -Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. -*/ - -#ifndef VIDEORENDERTARGET_SV_H -#define VIDEORENDERTARGET_SV_H - -#include "abstractRenderTarget_sV.h" - -class VideoOut_sV; -class RenderTask_sV; - -/// Produces videos from frames. -class VideoRenderTarget_sV : public AbstractRenderTarget_sV -{ -public: - /// Constructs a new video render target - VideoRenderTarget_sV(RenderTask_sV *parentRenderTask); - virtual ~VideoRenderTarget_sV(); - - /// openRenderTarget() will throw an error if the target file cannot be opened. - void setTargetFile(const QString& filename); - /// Set a custom video codec (see <pre>ffmpeg -codecs</pre> for a list of available codecs). - void setVcodec(const QString& codec); - - void openRenderTarget() throw(Error_sV); - void closeRenderTarget() throw(Error_sV); - -public slots: - void slotConsumeFrame(const QImage &image, const int frameNumber); - -private: - QString m_filename; - QString m_vcodec; - VideoOut_sV *m_videoOut; - - int m_width; - int m_height; -}; - -#endif // VIDEORENDERTARGET_SV_H
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/project/xmlProjectRW_sV.cpp
Deleted
@@ -1,593 +0,0 @@ -/* -This file is part of slowmoVideo. -Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. -*/ - -#include "xmlProjectRW_sV.h" - -#include "project_sV.h" -#include "projectPreferences_sV.h" -#include "shutterFunctionList_sV.h" -#include "shutterFunction_sV.h" -#include "nodeList_sV.h" -#include "videoFrameSource_sV.h" -#include "emptyFrameSource_sV.h" -#include "imagesFrameSource_sV.h" -#include "motionBlur_sV.h" - -#include <QDebug> -#include <QTextStream> -#include <QXmlQuery> - - -int XmlProjectRW_sV::saveProject(Project_sV *project, QString filename) throw(Error_sV) -{ - QDomDocument doc; - QDomElement root = doc.createElement("sVproject"); - root.setAttribute("version", SLOWMOPROJECT_VERSION_MAJOR); - root.setAttribute("version_minor", SLOWMOPROJECT_VERSION_MINOR); - doc.appendChild(root); - - // File info - QDomElement info = doc.createElement("info"); - root.appendChild(info); - QDomElement appName = doc.createElement("appName"); - appName.appendChild(doc.createTextNode("slowmoVideo")); - QDomElement version = doc.createElement("version"); - version.setAttribute("major", SLOWMOVIDEO_VERSION_MAJOR); - version.setAttribute("minor", SLOWMOVIDEO_VERSION_MINOR); - version.setAttribute("micro", SLOWMOVIDEO_VERSION_MICRO); - info.appendChild(appName); - info.appendChild(version); - - - ProjectPreferences_sV *pr = project->preferences(); - // Project Preferences - QDomElement preferences = doc.createElement("preferences"); - root.appendChild(preferences); - QDomElement renderSectionMode = doc.createElement("renderSectionMode"); - QDomElement renderStartTag = doc.createElement("renderStartTag"); - QDomElement renderEndTag = doc.createElement("renderEndTag"); - QDomElement renderStartTime = doc.createElement("renderStartTime"); - QDomElement renderEndTime = doc.createElement("renderEndTime"); - QDomElement renderFrameSize = doc.createElement("renderFrameSize"); - QDomElement renderInterpolation = doc.createElement("renderInterpolationType"); - QDomElement renderMotionblur = doc.createElement("renderMotionblurType"); - QDomElement renderFPS = doc.createElement("renderFPS"); - QDomElement renderSlowmoSamples = doc.createElement("renderSlowmoSamples"); - QDomElement renderMaxSamples = doc.createElement("renderMaxSamples"); - QDomElement renderTarget = doc.createElement("renderTarget"); - QDomElement imagesOutputDir = doc.createElement("imagesOutputDir"); - QDomElement imagesFilenamePattern = doc.createElement("imagesFilenamePattern"); - QDomElement videoFilename = doc.createElement("videoFilename"); - QDomElement videoCodec = doc.createElement("videoCodec"); - QDomElement flowV3dLambda = doc.createElement("flowV3dLambda"); - QDomElement prevTagAxis = doc.createElement("prevTagAxis"); - QDomElement viewport_t0 = doc.createElement("viewport_t0"); - QDomElement viewport_secRes = doc.createElement("viewport_secRes"); - QDomElement canvas_xAxisFPS = doc.createElement("canvas_xAxisFPS"); - preferences.appendChild(renderSectionMode); - renderSectionMode.appendChild(renderStartTag); - renderSectionMode.appendChild(renderEndTag); - renderSectionMode.appendChild(renderStartTime); - renderSectionMode.appendChild(renderEndTime); - preferences.appendChild(renderFrameSize); - preferences.appendChild(renderInterpolation); - preferences.appendChild(renderMotionblur); - preferences.appendChild(renderFPS); - preferences.appendChild(renderSlowmoSamples); - preferences.appendChild(renderMaxSamples); - preferences.appendChild(renderTarget); - preferences.appendChild(imagesOutputDir); - preferences.appendChild(imagesFilenamePattern); - preferences.appendChild(videoFilename); - preferences.appendChild(videoCodec); - preferences.appendChild(flowV3dLambda); - preferences.appendChild(prevTagAxis); - preferences.appendChild(viewport_t0); - preferences.appendChild(viewport_secRes); - preferences.appendChild(canvas_xAxisFPS); - renderSectionMode.setAttribute("mode", pr->renderSectionMode()); - renderStartTag.setAttribute("label", pr->renderStartTag()); - renderEndTag.setAttribute("label", pr->renderEndTag()); - renderStartTime.setAttribute("time", pr->renderStartTime()); - renderEndTime.setAttribute("time", pr->renderEndTime()); - renderFrameSize.setAttribute("size", pr->renderFrameSize()); - renderInterpolation.setAttribute("type", pr->renderInterpolationType()); - renderMotionblur.setAttribute("type", pr->renderMotionblurType()); - renderFPS.setAttribute("fps", pr->renderFPS().toString()); - renderSlowmoSamples.setAttribute("number", project->motionBlur()->slowmoSamples()); - renderMaxSamples.setAttribute("number", project->motionBlur()->maxSamples()); - renderTarget.setAttribute("target", pr->renderTarget()); - imagesOutputDir.setAttribute("dir", pr->imagesOutputDir()); - imagesFilenamePattern.setAttribute("pattern", pr->imagesFilenamePattern()); - videoFilename.setAttribute("file", pr->videoFilename()); - videoCodec.setAttribute("codec", pr->videoCodec()); - flowV3dLambda.setAttribute("lambda", pr->flowV3DLambda()); - prevTagAxis.setAttribute("axis", QVariant(pr->lastSelectedTagAxis()).toString()); - viewport_t0.setAttribute("x", pr->viewport_t0().x()); - viewport_t0.setAttribute("y", pr->viewport_t0().y()); - viewport_secRes.setAttribute("x", QString().setNum(pr->viewport_secRes().x())); - viewport_secRes.setAttribute("y", QString().setNum(pr->viewport_secRes().y())); - canvas_xAxisFPS.setAttribute("fps", pr->canvas_xAxisFPS().toString()); - - - // Project Resources - QDomElement resources = doc.createElement("resources"); - root.appendChild(resources); - QDomElement projectDir = doc.createElement("projectDir"); - projectDir.appendChild(doc.createTextNode(project->getDirectory(".", false).absolutePath())); - resources.appendChild(projectDir); - resources.appendChild(frameSource(&doc, project->frameSource())); - - - // Shutter functions - QDomElement shutterFunctions = doc.createElement("shutterFunctions"); - root.appendChild(shutterFunctions); - for (int i = 0; i < project->shutterFunctions()->size(); i++) { - QDomElement func = doc.createElement("function"); - func.setAttribute("id", project->shutterFunctions()->at(i)->id()); - QDomElement code = doc.createElement("code"); - func.appendChild(code); - code.appendChild(doc.createTextNode(project->shutterFunctions()->at(i)->function())); - shutterFunctions.appendChild(func); - } - - - // Nodes - QDomElement nodes = doc.createElement("nodes"); - root.appendChild(nodes); - NodeList_sV *nodeList = project->nodes(); - for (int i = 0; i < nodeList->size(); i++) { - nodes.appendChild(nodeToDom(&doc, &nodeList->at(i))); - } - - // Tags - QDomElement tags = doc.createElement("tags"); - root.appendChild(tags); - for (int i = 0; i < project->tags()->size(); i++) { - tags.appendChild(tagToDom(&doc, project->tags()->at(i))); - } - - QFile outFile(filename); - if (!outFile.open(QIODevice::WriteOnly)) { - throw Error_sV(QObject::tr("Cannot write to %1; please check if you have write permissions.").arg(filename)); - } - QTextStream output(&outFile); - doc.save(output, 4); - output.flush(); - outFile.close(); - - project->setProjectFilename(filename); - - return 0; -} - -const QDomElement XmlProjectRW_sV::nodeToDom(QDomDocument *doc, const Node_sV *node) -{ - QDomElement el = doc->createElement("node"); - QDomElement x = doc->createElement("x"); - QDomElement y = doc->createElement("y"); - QDomElement selected = doc->createElement("selected"); - QDomElement leftHandle = doc->createElement("leftHandle"); - QDomElement rightHandle = doc->createElement("rightHandle"); - QDomElement shutterFunc = doc->createElement("shutterFunction"); - QDomElement leftCurveType = doc->createElement("type"); - QDomElement rightCurveType = doc->createElement("type"); - QDomElement leftX = doc->createElement("x"); - QDomElement leftY = doc->createElement("y"); - QDomElement rightX = doc->createElement("x"); - QDomElement rightY = doc->createElement("y"); - el.appendChild(x); - el.appendChild(y); - el.appendChild(selected); - el.appendChild(leftHandle); - el.appendChild(rightHandle); - if (node->shutterFunctionID().length() > 0) { - el.appendChild(shutterFunc); - } - x.appendChild(doc->createTextNode(QString("%1").arg(node->xUnmoved()))); - y.appendChild(doc->createTextNode(QString("%1").arg(node->yUnmoved()))); - selected.appendChild(doc->createTextNode(QString("%1").arg(node->selected()))); - shutterFunc.appendChild(doc->createTextNode(node->shutterFunctionID())); - - leftHandle.appendChild(leftX); - leftHandle.appendChild(leftY); - leftHandle.appendChild(leftCurveType); - rightHandle.appendChild(rightX); - rightHandle.appendChild(rightY); - rightHandle.appendChild(rightCurveType); - - leftX.appendChild(doc->createTextNode(QString("%1").arg(node->leftNodeHandle().x()))); - leftY.appendChild(doc->createTextNode(QString("%1").arg(node->leftNodeHandle().y()))); - leftCurveType.appendChild(doc->createTextNode(QVariant((int)node->leftCurveType()).toString())); - rightX.appendChild(doc->createTextNode(QString("%1").arg(node->rightNodeHandle().x()))); - rightY.appendChild(doc->createTextNode(QString("%1").arg(node->rightNodeHandle().y()))); - rightCurveType.appendChild(doc->createTextNode(QVariant((int)node->rightCurveType()).toString())); - - return el; -} - -const QDomElement XmlProjectRW_sV::tagToDom(QDomDocument *doc, const Tag_sV &tag) -{ - QDomElement el = doc->createElement("tag"); - QDomElement t = doc->createElement("time"); - QDomElement desc = doc->createElement("description"); - QDomElement axis = doc->createElement("axis"); - el.appendChild(t); - el.appendChild(desc); - el.appendChild(axis); - t.appendChild(doc->createTextNode(QString("%1").arg(tag.time()))); - desc.appendChild(doc->createTextNode(tag.description())); - axis.appendChild(doc->createTextNode(QVariant(tag.axis()).toString())); - return el; -} - -const QDomElement XmlProjectRW_sV::frameSource(QDomDocument *doc, const AbstractFrameSource_sV *frameSource) -{ - QDomElement source = doc->createElement("frameSource"); - if (dynamic_cast<const VideoFrameSource_sV *>(frameSource) != NULL) { - qDebug() << "Frame source is a video."; - - const VideoFrameSource_sV *vfs = dynamic_cast<const VideoFrameSource_sV *>(frameSource); - source.setAttribute("type", "videoFile"); - QDomElement file = doc->createElement("inputFile"); - file.appendChild(doc->createTextNode(vfs->videoFile())); - source.appendChild(file); - - } else if (dynamic_cast<const ImagesFrameSource_sV *>(frameSource) != NULL) { - qDebug() << "Frame source are images."; - - const ImagesFrameSource_sV *ifs = dynamic_cast<const ImagesFrameSource_sV *>(frameSource); - source.setAttribute("type", "images"); - QDomElement files = doc->createElement("inputFiles"); - QStringList images = ifs->inputFiles(); - for (int i = 0; i < images.size(); i++) { - QDomElement file = doc->createElement("file"); - file.appendChild(doc->createTextNode(images.at(i))); - files.appendChild(file); - } - source.appendChild(files); - - } else if (dynamic_cast<const EmptyFrameSource_sV *>(frameSource) != NULL) { - qDebug() << "Frame source is empty."; - source.setAttribute("type", "empty"); - } else { - qDebug() << "Unknown frame source type; cannot save!"; - source.setAttribute("type", "unknown"); - Q_ASSERT(false); - } - return source; -} - -void XmlProjectRW_sV::loadFrameSource(QXmlStreamReader *reader, Project_sV *project) throw(FrameSourceError) -{ - QStringRef frameSourceType = reader->attributes().value("type"); - if (frameSourceType.compare("videoFile") == 0) { - while (reader->readNextStartElement()) { - if (reader->name() == "inputFile") { - VideoFrameSource_sV *frameSource = new VideoFrameSource_sV(project, reader->readElementText()); - project->loadFrameSource(frameSource); - } else { - qDebug() << "Unknown element in video frame source section: " << reader->name(); - reader->skipCurrentElement(); - } - } - - } else if (frameSourceType.compare("images") == 0) { - while (reader->readNextStartElement()) { - if (reader->name() == "inputFiles") { - - QStringList images; - while (reader->readNextStartElement()) { - if (reader->name() == "file") { - images << reader->readElementText(); - } else { - reader->skipCurrentElement(); - } - } - ImagesFrameSource_sV *frameSource = new ImagesFrameSource_sV(project, images); - project->loadFrameSource(frameSource); - } - } - } else if (frameSourceType.compare("empty") == 0) { - EmptyFrameSource_sV *frameSource = new EmptyFrameSource_sV(project); - project->loadFrameSource(frameSource); - reader->skipCurrentElement(); - } else { - reader->skipCurrentElement(); - qDebug() << "Unknown frame source: " << frameSourceType << "; Cannot load!"; - throw FrameSourceError(QObject::trUtf8("Unknown frame source “%1”. Cannot load the project.").arg(frameSourceType.toString())); - } -} - -Project_sV* XmlProjectRW_sV::loadProject(QString filename, QString *warning) throw(FrameSourceError, Error_sV) -{ - QFile file(filename); - if (!file.open(QIODevice::ReadOnly)) { - qDebug() << "Cannot read file " << filename; - throw Error_sV(QObject::tr("Cannot read from file %1. (Opening in read-only mode failed.)").arg(filename)); - } else { - - QXmlStreamReader xml; - xml.setDevice(&file); - if (!xml.readNextStartElement()) { - qDebug() << "Could not read " << filename; - throw Error_sV(QObject::tr("Invalid project file: %1").arg(filename)); - - } else { - if (xml.name() != "sVproject") { - qDebug() << "Invalid project file (incorrect root element): " << filename; - } else { - - int projVersionMajor = xml.attributes().value("version").toString().toInt(); - int projVersionMinor = xml.attributes().value("version_minor").toString().toInt(); - if (projVersionMajor > 0) { - qDebug().nospace() << "Reading project file: version " << projVersionMajor << "." << projVersionMinor; - } else { - qDebug() << "Reading project file of unknown version"; - } - - int version_major = 0, version_minor = 0, version_micro = 0; - - Project_sV *project = new Project_sV(); - project->setProjectFilename(filename); - project->setProjectDir(QFileInfo(filename).absolutePath()); - ProjectPreferences_sV *pr = project->preferences(); - - while (xml.readNextStartElement()) { - if (xml.name() == "info") { - while (xml.readNextStartElement()) { - if (xml.name() == "appName") { - qDebug() << "App name: " << xml.readElementText(); - } else if (xml.name() == "version") { - version_major = xml.attributes().value("major").toString().toInt(); - version_minor = xml.attributes().value("minor").toString().toInt(); - version_micro = xml.attributes().value("micro").toString().toInt(); - xml.skipCurrentElement(); - } else { - xml.skipCurrentElement(); - } - } - } else if (xml.name() == "resources") { - while (xml.readNextStartElement()) { - if (projVersionMajor < 2 && xml.name() == "inputFile") { - QString inFilename = xml.readElementText(); - qDebug() << "Input file: " << inFilename; - project->loadFrameSource(new VideoFrameSource_sV(project, inFilename)); - } else if (xml.name() == "frameSource") { - loadFrameSource(&xml, project); - } else if (xml.name() == "projectDir") { - xml.skipCurrentElement(); - } else { - xml.skipCurrentElement(); - } - } - } else if (xml.name() == "shutterFunctions") { - ShutterFunction_sV func; - while (xml.readNextStartElement()) { - if (xml.name() == "function") { - func.setID(xml.attributes().value("id").toString()); - while (xml.readNextStartElement()) { - if (xml.name() == "code") { - func.updateFunction(xml.readElementText()); - } else { - xml.skipCurrentElement(); - } - } - project->shutterFunctions()->addFunction(func, false); - } else { - xml.skipCurrentElement(); - } - } - } else if (xml.name() == "nodes") { - while (xml.readNextStartElement()) { - if (xml.name() == "node") { - Node_sV node; - while (xml.readNextStartElement()) { - if (xml.name() == "x") { - node.setX(QVariant(xml.readElementText()).toFloat()); - } else if (xml.name() == "y") { - node.setY(QVariant(xml.readElementText()).toFloat()); - } else if (xml.name() == "selected") { - node.select(QVariant(xml.readElementText()).toBool()); - } else if (xml.name() == "shutterFunction") { - node.setShutterFunctionID(xml.readElementText()); - } else if (xml.name() == "leftHandle") { - while (xml.readNextStartElement()) { - QString text = xml.readElementText(); - if (xml.name() == "type") { - node.setLeftCurveType((CurveType)text.toInt()); - } else if (xml.name() == "x") { - node.setLeftNodeHandle(text.toDouble(), node.leftNodeHandle().y()); - } else if (xml.name() == "y") { - node.setLeftNodeHandle(node.leftNodeHandle().x(), text.toDouble()); - } else { - xml.skipCurrentElement(); - } - } - } else if (xml.name() == "rightHandle") { - while (xml.readNextStartElement()) { - QString text = xml.readElementText(); - if (xml.name() == "type") { - node.setRightCurveType((CurveType)text.toInt()); - } else if (xml.name() == "x") { - node.setRightNodeHandle(text.toDouble(), node.rightNodeHandle().y()); - } else if (xml.name() == "y") { - node.setRightNodeHandle(node.rightNodeHandle().x(), text.toDouble()); - } else { - xml.skipCurrentElement(); - } - } - } else { - xml.skipCurrentElement(); - } - } - project->nodes()->add(node); - } else { - xml.skipCurrentElement(); - } - } - } else if (xml.name() == "tags") { - while (xml.readNextStartElement()) { - if (xml.name() == "tag") { - Tag_sV tag; - while (xml.readNextStartElement()) { - if (xml.name() == "time") { - tag.setTime(QVariant(xml.readElementText()).toFloat()); - } else if (xml.name() == "description") { - tag.setDescription(xml.readElementText()); - } else if (xml.name() == "axis") { - tag.setAxis((TagAxis)QVariant(xml.readElementText()).toInt()); - } else { - xml.skipCurrentElement(); - } - } - project->tags()->push_back(tag); - } else { - xml.skipCurrentElement(); - } - } - } else if (xml.name() == "preferences") { - while (xml.readNextStartElement()) { - if (xml.name() == "renderSectionMode") { - pr->renderSectionMode() = xml.attributes().value("mode").toString(); - if (projVersionMajor == 2 && projVersionMinor < 4) { - if (pr->renderSectionMode() == "time") { - pr->renderSectionMode() = "expr"; - } - } - while (xml.readNextStartElement()) { - if (xml.name() == "renderStartTag") { - pr->renderStartTag() = xml.attributes().value("label").toString(); - xml.skipCurrentElement(); - } else if (xml.name() == "renderEndTag") { - pr->renderEndTag() = xml.attributes().value("label").toString(); - xml.skipCurrentElement(); - } else if (xml.name() == "renderStartTime") { - pr->renderStartTime() = xml.attributes().value("time").toString(); - xml.skipCurrentElement(); - } else if (xml.name() == "renderEndTime") { - pr->renderEndTime() = xml.attributes().value("time").toString(); - xml.skipCurrentElement(); - } else { - xml.skipCurrentElement(); - } - } - - } else if (xml.name() == "renderFrameSize") { - pr->renderFrameSize() = (FrameSize) xml.attributes().value("size").toString().toInt(); - xml.skipCurrentElement(); - } else if (xml.name() == "renderInterpolationType") { - pr->renderInterpolationType() = (InterpolationType) xml.attributes().value("type").toString().toInt(); - xml.skipCurrentElement(); - } else if (xml.name() == "renderMotionblurType") { - pr->renderMotionblurType() = (MotionblurType) xml.attributes().value("type").toString().toInt(); - xml.skipCurrentElement(); - } else if (xml.name() == "renderFPS") { - if (projVersionMajor == 2 && projVersionMinor <= 2) { - pr->renderFPS() = xml.attributes().value("fps").toString().toFloat(); - } else { - pr->renderFPS() = xml.attributes().value("fps").toString(); - } - xml.skipCurrentElement(); - - } else if (xml.name() == "renderSlowmoSamples") { - project->motionBlur()->setSlowmoSamples(xml.attributes().value("number").toString().toInt()); - xml.skipCurrentElement(); - } else if (xml.name() == "renderMaxSamples") { - project->motionBlur()->setMaxSamples(xml.attributes().value("number").toString().toInt()); - xml.skipCurrentElement(); - - } else if (xml.name() == "renderTarget") { - pr->renderTarget() = xml.attributes().value("target").toString(); - xml.skipCurrentElement(); - - } else if (xml.name() == "imagesOutputDir") { - pr->imagesOutputDir() = xml.attributes().value("dir").toString(); - xml.skipCurrentElement(); - } else if (xml.name() == "imagesFilenamePattern") { - pr->imagesFilenamePattern() = xml.attributes().value("pattern").toString(); - xml.skipCurrentElement(); - } else if (xml.name() == "videoFilename") { - pr->videoFilename() = xml.attributes().value("file").toString(); - xml.skipCurrentElement(); - } else if (xml.name() == "videoCodec") { - pr->videoCodec() = xml.attributes().value("codec").toString(); - xml.skipCurrentElement(); - - } else if (xml.name() == "flowV3dLambda") { - pr->flowV3DLambda() = xml.attributes().value("lambda").toString().toFloat(); - xml.skipCurrentElement(); - - } else if (xml.name() == "prevTagAxis") { - pr->lastSelectedTagAxis() = (TagAxis)xml.attributes().value("axis").toString().toInt(); - xml.skipCurrentElement(); - } else if (xml.name() == "viewport_t0") { - pr->viewport_t0().rx() = xml.attributes().value("x").toString().toFloat(); - pr->viewport_t0().ry() = xml.attributes().value("y").toString().toFloat(); - xml.skipCurrentElement(); - } else if (xml.name() == "viewport_secRes") { - pr->viewport_secRes().rx() = xml.attributes().value("x").toString().toFloat(); - pr->viewport_secRes().ry() = xml.attributes().value("y").toString().toFloat(); - xml.skipCurrentElement(); - - } else if (xml.name() == "canvas_xAxisFPS") { - pr->canvas_xAxisFPS() = xml.attributes().value("fps").toString(); - xml.skipCurrentElement(); - } - - - else { - xml.skipCurrentElement(); - } - } - } else { - qDebug() << "Unknown element: " << xml.name(); - xml.skipCurrentElement(); - } - } - xml.readNextStartElement(); - if (xml.name().length() > 0) { - qDebug() << "Did not read the whole project file! Stopped at: " << xml.name(); - } - Q_ASSERT(xml.name().length() == 0); - - - file.close(); - - - // Handle new project versions - if (projVersionMajor > SLOWMOPROJECT_VERSION_MAJOR && projVersionMajor) { - throw Error_sV(QString("This file has been created with slowmoVideo %1.%2.%3 which uses a newer " - "project file version (%4.%5; supported: %6.%7). File cannot be loaded " - "(or only partially). Please upgrade to a newer version of slowmoVideo.") - .arg(version_major).arg(version_minor).arg(version_micro) - .arg(projVersionMajor).arg(projVersionMinor) - .arg(SLOWMOPROJECT_VERSION_MAJOR).arg(SLOWMOPROJECT_VERSION_MINOR)); - } else if (projVersionMinor > SLOWMOPROJECT_VERSION_MINOR) { - QString warningMsg = QString("This file has been created with a slightly newer version of slowmoVideo " - "(version %1.%2.%3) which uses project file version %4.%5 (supported: %6.%7). " - "When saving this project, some added properties will be lost.") - .arg(version_major).arg(version_minor).arg(version_micro) - .arg(projVersionMajor).arg(projVersionMinor) - .arg(SLOWMOPROJECT_VERSION_MAJOR).arg(SLOWMOPROJECT_VERSION_MINOR); - qDebug() << warningMsg; - if (warning != NULL) { - *warning = warningMsg; - } - } - - return project; - - } - } - file.close(); - } - return NULL; -}
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/project/xmlProjectRW_sV.h
Deleted
@@ -1,62 +0,0 @@ -/* -This file is part of slowmoVideo. -Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. -*/ - -#ifndef XMLPROJECTRW_SV_H -#define XMLPROJECTRW_SV_H - -#include "../lib/defs_sV.hpp" -#include "tag_sV.h" - -#include <QtXml> - -class Node_sV; -class Project_sV; -class AbstractFrameSource_sV; - -// Remember to change the slowmoVideo version as well -#define SLOWMOPROJECT_VERSION_MAJOR 2 -#define SLOWMOPROJECT_VERSION_MINOR 7 - -/** - \brief Reads and writes project files in XML format - - Additional stored parameters require a minor version change. - Big changes in the schema, like elements moved to a different node, require - a major version change and a function that loads old project files. - - Version changes (both major and minor) require a micro slowmoVideo version change. - */ -class XmlProjectRW_sV -{ -public: - /** - \fn loadProject() - Reads an XML project file. - \param filename Project file to load - \param warning Information message when trying to load project files with a wrong version number - \return NULL if an error ocurred. - */ - /** - \fn saveProject() - Saves a project to an XML project file. - */ - - static Project_sV* loadProject(QString filename, QString *warning = NULL) throw(FrameSourceError, Error_sV); - static int saveProject(Project_sV *project, QString filename) throw(Error_sV); - -private: - static const QDomElement nodeToDom(QDomDocument *doc, const Node_sV *node); - static const QDomElement tagToDom(QDomDocument *doc, const Tag_sV &tag); - - static const QDomElement frameSource(QDomDocument *doc, const AbstractFrameSource_sV *frameSource); - static void loadFrameSource(QXmlStreamReader *reader, Project_sV *project) throw(FrameSourceError); -}; - -#endif // XMLPROJECTRW_SV_H
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/slowmoCLI
Deleted
-(directory)
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/slowmoCLI/CMakeLists.txt
Deleted
@@ -1,20 +0,0 @@ - - -set(SOURCES_MAIN - main.cpp -) - -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99") - -set(SOURCES_VINFO - videoInfo.cpp -) - -add_executable(slowmoInterpolate ${SOURCES_MAIN}) -target_link_libraries(slowmoInterpolate sV sVflow ${EXTERNAL_LIBS}) - -add_executable(slowmoVideoInfo ${SOURCES_VINFO}) -target_link_libraries(slowmoVideoInfo sVinfo ${EXTERNAL_LIBS}) - -install(TARGETS slowmoInterpolate DESTINATION ${DEST}) -install(TARGETS slowmoVideoInfo DESTINATION ${DEST})
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/slowmoCLI/main.cpp
Deleted
@@ -1,209 +0,0 @@ -/* -slowmoCLI is a command-line interface for slowmoVideo. -Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. -*/ - -#include "../lib/interpolate_sV.h" -#include "../lib/flowField_sV.h" -#include "../lib/flowRW_sV.h" - -#include <iostream> -#include <cmath> - -#include <QString> - -#include <QImage> -#include <QColor> -#include <QRgb> - -#include <QDebug> - - - -const int RET_MISSING_PARAM = -1; -const int RET_WRONG_PARAM = -2; -const int RET_MISSING_FILE = -3; -const int RET_SIZE_DIFFERS = -4; - - -char *myName; - -enum FlowMode { - FlowMode_Forward, - FlowMode_Twoway, - FlowMode_Undef -}; - - -void printUsage() { - std::cout << "Usage: " << std::endl; - std::cout << "\t" << myName << " twoway <left image> <right image> <flow image> <reverse image> <output pattern> numberOffset fps " << std::endl; - std::cout << "\t" << myName << " forward <left image> <flow image> <output pattern> numberOffset fps " << std::endl; -} - - -char* nextArg(int argc, int &argi, char *argv) -{ - argi++; - if (argi < argc) { - std::cout << "Arg: " << argvargi << std::endl; - return argvargi; - } else { - std::cout << "Argument " << argi << " missing." << std::endl; - printUsage(); - exit(RET_MISSING_PARAM); - } -} - -const char* nextOptArg(int argc, int &argi, char *argv, const char defaultParam) -{ - argi++; - if (argi < argc) { - std::cout << "Optional argument: " << argvargi << std::endl; - return argvargi; - } else { - std::cout << "Optional argument " << argi << " not given." << std::endl; - return defaultParam; - } -} - - -int main(int argc, char *argv) -{ - myName = argv0; - - - int argi = 0; - char *arg; - - - FlowMode mode = FlowMode_Undef; - - arg = nextArg(argc, argi, argv); - if (strcmp("forward", arg) == 0) { - mode = FlowMode_Forward; - } else if (strcmp("twoway", arg) == 0) { - mode = FlowMode_Twoway; - } - - if (mode == FlowMode_Undef) { - printUsage(); - exit(RET_WRONG_PARAM); - } - - - QImage left, right, output; - FlowField_sV *ffForward, *ffBackward; - - switch (mode) { - case FlowMode_Twoway: - std::cout << "Running two-way flow." << std::endl; - left = QImage(nextArg(argc, argi, argv)); - right = QImage(nextArg(argc, argi, argv)); - ffForward = FlowRW_sV::load(nextArg(argc, argi, argv)); - ffBackward = FlowRW_sV::load(nextArg(argc, argi, argv)); - break; - case FlowMode_Forward: - std::cout << "Running forward flow." << std::endl; - left = QImage(nextArg(argc, argi, argv)); - ffForward = FlowRW_sV::load(nextArg(argc, argi, argv)); - break; - case FlowMode_Undef: - Q_ASSERT(false); - break; - } - QString pattern(nextOptArg(argc, argi, argv, "output%1.png")); - if (!pattern.contains("%1")) { - std::cout << "Error: Output pattern must contain a %1 for the image number. Example: output%1.png." << std::endl; - return RET_WRONG_PARAM; - } - bool ok; - int numberOffset = QString(nextOptArg(argc, argi, argv, "0")).toInt(&ok); - if (!ok) { - std::cout << "Error converting argument to number." << std::endl; - return RET_WRONG_PARAM; - } - const unsigned int fps = QString(nextOptArg(argc, argi, argv, "24")).toInt(&ok); - if (!ok) { - std::cout << "Error converting argument to number." << std::endl; - return RET_WRONG_PARAM; - } - - - - switch (mode) { - case FlowMode_Twoway: - if (ffBackward == NULL) { - std::cout << "Backward flow is not valid." << std::endl; - exit(RET_MISSING_FILE); - } - if (right.isNull()) { - std::cout << "Right image does not exist." << std::endl; - exit(RET_MISSING_FILE); - } - if (ffBackward->width() != left.width() || ffBackward->height() != left.height()) { - qDebug() << "Invalid backward flow field size. Image is " << left.width() - << ", flow is " << ffBackward->width() << "x" << ffBackward->height() << "."; - exit(RET_SIZE_DIFFERS); - } - // Fall through - case FlowMode_Forward: - if (left.isNull()) { - std::cout << "Left image does not exist." << std::endl; - exit(RET_MISSING_FILE); - } - if (ffForward == NULL) { - std::cout << "Forward flow is not valid." << std::endl; - exit(RET_MISSING_FILE); - } - if (left.size() != right.size()) { - qDebug() << "Left image size differs from right image size: " << left.size() << " vs. " << right.size() << "."; - } - if (ffForward->width() != left.width() || ffForward->height() != left.height()) { - qDebug() << "Invalid forward flow field size. Image is " << left.width() - << ", flow is " << ffForward->width() << "x" << ffForward->height() << "."; - exit(RET_SIZE_DIFFERS); - } - break; - case FlowMode_Undef: - qDebug() << "Undefined flow mode selected."; - break; - } - - - - output = QImage(left.size(), QImage::Format_RGB32); - - - - - - //const int stepLog = ceil(log10(numberOffset + steps)); - const int stepLog = 8; - float pos; - const QChar fillChar = QLatin1Char('0'); - qDebug() << stepLog << ": max length"; - QString filename; - - for (unsigned int step = 0; step < fps+1; step++) { - pos = step/float(fps); - if (mode == FlowMode_Twoway) { - Interpolate_sV::twowayFlow(left, right, ffForward, ffBackward, pos, output); - } else if (mode == FlowMode_Forward) { - Interpolate_sV::forwardFlow(left, ffForward, pos, output); - } - filename = pattern.arg(QString::number(numberOffset + step), stepLog, fillChar); - qDebug() << "Saving position " << pos << " to image " << filename; - output.save(filename); - } - - delete ffForward; - if (mode == FlowMode_Twoway) { - delete ffBackward; - } -}
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/slowmoCLI/videoInfo.cpp
Deleted
@@ -1,23 +0,0 @@ - -#include <cstdio> -#include <cstring> - -extern "C" { - #include "../lib/videoInfo_sV.h" -} - -void printUsage(const char progName) -{ - printf("Displays information like frame rate of a video file. \nUsage: %s file\n", progName); -} - -int main(int argc, char *argv) -{ - if (argc < 2 || strcmp("-h", argv1) == 0) { - printUsage(argv0); - return -1; - } - getInfo(argv1); - return 0; - -}
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/slowmoFlowEdit
Deleted
-(directory)
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/slowmoFlowEdit/CMakeLists.txt
Deleted
@@ -1,70 +0,0 @@ - -include_directories(${slowmoVideo_SOURCE_DIR}) - -set(SRCS - main.cpp - mainwindow.cpp - flowEditCanvas.cpp - shortcutListDialog.cpp -) - -set(SRCS_UI - mainwindow.ui - flowEditCanvas.ui - shortcutListDialog.ui -) - - -set(SRCS_MOC - mainwindow.h - flowEditCanvas.h - shortcutListDialog.h -) - -qt4_wrap_ui(UI_H_OUT ${SRCS_UI}) -qt4_wrap_cpp(MOC_OUT ${SRCS_MOC}) - -if(APPLE) - set(BUNDLE "slowmoFlowEdit") - set(ICONS_DIR "${${PROJECT_NAME}_SOURCE_DIR}/slowmoVideo/slowmoUI/res") - message( "OS X build" ) - set(MACOSX_BUNDLE_INFO_STRING "${BUNDLE} ${PROJECT_VERSION}") - set(MACOSX_BUNDLE_BUNDLE_VERSION "${BUNDLE} ${PROJECT_VERSION}") - set(MACOSX_BUNDLE_LONG_VERSION_STRING "${BUNDLE} ${PROJECT_VERSION}") - set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${PROJECT_VERSION}") - set(MACOSX_BUNDLE_COPYRIGHT "${PROJECT_COPYRIGHT_YEAR} ${PROJECT_VENDOR}") - set(MACOSX_BUNDLE_ICON_FILE "slowmoUI.icns") - set(MACOSX_BUNDLE_GUI_IDENTIFIER "${PROJECT_DOMAIN_SECOND}.${PROJECT_DOMAIN_FIRST}") - set(MACOSX_BUNDLE_BUNDLE_NAME "${BUNDLE}") - - set(MACOSX_BUNDLE_RESOURCES "${CMAKE_CURRENT_BINARY_DIR}/${BUNDLE}.app/Contents/Resources") - set(MACOSX_BUNDLE_ICON "${ICONS_DIR}/${MACOSX_BUNDLE_ICON_FILE}") - SET_SOURCE_FILES_PROPERTIES( - ${MACOSX_BUNDLE_ICON} - PROPERTIES MACOSX_PACKAGE_LOCATION Resources) - message(STATUS "Bundle will be : ${MACOSX_BUNDLE} => ${PROJECT_NAME} ") - - set( SRCS ${SRCS} ${MACOSX_BUNDLE_ICON} ) - -endif() - -include_directories(..) -include_directories(${CMAKE_BINARY_DIR}/slowmoVideo/slowmoFlowEdit) -include_directories(${CMAKE_BINARY_DIR}/slowmoVideo/libgui) - -add_executable(slowmoFlowEdit WIN32 MACOSX_BUNDLE ${SRCS} ${MOC_OUT} ${UI_H_OUT}) -target_link_libraries(slowmoFlowEdit sVgui sVflow sVvis ${EXTERNAL_LIBS}) - -install(TARGETS slowmoFlowEdit - BUNDLE DESTINATION . COMPONENT Runtime - RUNTIME DESTINATION ${DEST} COMPONENT Runtime) - -if (APPLE) - #install(TARGETS slowmoUI DESTINATION ".") - include(DeployQt4) - install_qt4_executable(slowmoUI.app "" "" ) - -else() - install(TARGETS slowmoFlowEdit DESTINATION ${DEST}) -endif() -
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/slowmoFlowEdit/flowEditCanvas.cpp
Deleted
@@ -1,106 +0,0 @@ -/* -slowmoFlowEdit is a user interface for editing slowmoVideo's Optical Flow files. -Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. -*/ - -#include "flowEditCanvas.h" -#include "ui_flowEditCanvas.h" - -#include "lib/flowRW_sV.h" -#include "lib/flowTools_sV.h" -#include "lib/flowVisualization_sV.h" - -#include <QtCore/QDebug> - -FlowEditCanvas::FlowEditCanvas(QWidget *parent) : - QWidget(parent), - ui(new Ui::FlowEditCanvas), - m_flowField(NULL), - m_boost(1.0) -{ - ui->setupUi(this); - - ui->flow->trackMouse(true); - - bool b = true; - b &= connect(ui->flow, SIGNAL(signalRectDrawn(QRectF)), this, SLOT(slotRectDrawn(QRectF))); - b &= connect(ui->flow, SIGNAL(signalMouseMoved(float,float)), this, SLOT(slotExamineValues(float,float))); - Q_ASSERT(b); -} - -FlowEditCanvas::~FlowEditCanvas() -{ - delete ui; -} - -float FlowEditCanvas::amplification() const -{ - return m_boost; -} -void FlowEditCanvas::setAmplification(float val) -{ - Q_ASSERT(val > 0); - m_boost = val; - repaintFlow(); -} - -/// \todo Make flow visualization configurable -void FlowEditCanvas::repaintFlow() -{ - if (m_flowField != NULL) { - ui->flow->loadImage(FlowVisualization_sV::colourizeFlow(m_flowField, FlowVisualization_sV::HSV, m_boost)); - repaint(); - } -} - -void FlowEditCanvas::slotRectDrawn(QRectF imageRect) -{ - qDebug() << "Rect drawn: " << imageRect; - Kernel_sV k(8, 8); - k.gauss(); - FlowTools_sV::deleteRect(*m_flowField, imageRect.top(), imageRect.left(), imageRect.bottom(), imageRect.right()); - FlowTools_sV::refill(*m_flowField, k, imageRect.top(), imageRect.left(), imageRect.bottom(), imageRect.right()); - repaintFlow(); -} - -void FlowEditCanvas::slotLoadFlow(QString filename) -{ - if (m_flowField != NULL) { - delete m_flowField; - m_flowField = NULL; - } - m_flowField = FlowRW_sV::load(filename.toStdString()); - m_flowFilename = filename; - - repaintFlow(); -} - -void FlowEditCanvas::slotSaveFlow(QString filename) -{ - if (m_flowField != NULL) { - if (filename.length() == 0) { - filename = m_flowFilename; - } - FlowRW_sV::save(filename.toStdString(), m_flowField); - } else { - qDebug() << "No flow file loaded, cannot save."; - } -} - -void FlowEditCanvas::slotExamineValues(float x, float y) -{ - if (m_flowField != NULL) { - if (x >= 0 && y >= 0 - && x <= m_flowField->width()-1 && y <= m_flowField->height()-1) { - float dx = m_flowField->x(x,y); - float dy = m_flowField->y(x,y); - ui->lblValues->setText(QString("dx/dy: (%1|%2)").arg(dx, 0, 'f', 2).arg(dy, 0, 'f', 2)); - ui->lblPos->setText(QString("(%1|%2)").arg(x).arg(y)); - } - } -}
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/slowmoFlowEdit/flowEditCanvas.h
Deleted
@@ -1,52 +0,0 @@ -/* -slowmoFlowEdit is a user interface for editing slowmoVideo's Optical Flow files. -Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. -*/ - -#ifndef FLOWEDITCANVAS_H -#define FLOWEDITCANVAS_H - -#include <QWidget> -#include <QtCore/QRectF> - -class FlowField_sV; -namespace Ui { - class FlowEditCanvas; -} - -/// \todo Auto-fix feature (confirm to accept) -class FlowEditCanvas : public QWidget -{ - Q_OBJECT - -public: - explicit FlowEditCanvas(QWidget *parent = 0); - ~FlowEditCanvas(); - - void setAmplification(float val); - float amplification() const; - -public slots: - void slotLoadFlow(QString filename); - void slotSaveFlow(QString filename = QString()); - -private: - Ui::FlowEditCanvas *ui; - - FlowField_sV *m_flowField; - QString m_flowFilename; - float m_boost; - - void repaintFlow(); - -private slots: - void slotRectDrawn(QRectF imageRect); - void slotExamineValues(float x, float y); -}; - -#endif // FLOWEDITCANVAS_H
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/slowmoFlowEdit/flowEditCanvas.ui
Deleted
@@ -1,95 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>FlowEditCanvas</class> - <widget class="QWidget" name="FlowEditCanvas"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>1058</width> - <height>608</height> - </rect> - </property> - <property name="windowTitle"> - <string notr="true">Form</string> - </property> - <layout class="QGridLayout" name="gridLayout"> - <item row="0" column="0"> - <widget class="ImageDisplay" name="flow"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Expanding"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="frameShape"> - <enum>QFrame::StyledPanel</enum> - </property> - <property name="frameShadow"> - <enum>QFrame::Raised</enum> - </property> - </widget> - </item> - <item row="1" column="0"> - <layout class="QHBoxLayout" name="horizontalLayout"> - <property name="sizeConstraint"> - <enum>QLayout::SetMinimumSize</enum> - </property> - <item> - <spacer name="horizontalSpacer"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QLabel" name="lblPos"> - <property name="text"> - <string notr="true">TextLabel</string> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer_2"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>10</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QLabel" name="lblValues"> - <property name="text"> - <string>Values at mouse position</string> - </property> - </widget> - </item> - </layout> - </item> - </layout> - </widget> - <customwidgets> - <customwidget> - <class>ImageDisplay</class> - <extends>QFrame</extends> - <header>libgui/imageDisplay.h</header> - <container>1</container> - </customwidget> - </customwidgets> - <resources/> - <connections/> -</ui>
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/slowmoFlowEdit/main.cpp
Deleted
@@ -1,29 +0,0 @@ -/* -slowmoFlowEdit is a user interface for editing slowmoVideo's Optical Flow files. -Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. -*/ - -#include <QtGui/QApplication> -#include "mainwindow.h" - -int main(int argc, char *argv) -{ - QApplication a(argc, argv); - - // Set up preferences for the QSettings file - QCoreApplication::setOrganizationName("Granjow"); - QCoreApplication::setOrganizationDomain("granjow.net"); - QCoreApplication::setApplicationName("slowmoFlowEdit"); - - MainWindow w; - - w.show(); - - return a.exec(); -} -
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/slowmoFlowEdit/mainwindow.cpp
Deleted
@@ -1,245 +0,0 @@ -/* -slowmoFlowEdit is a user interface for editing slowmoVideo's Optical Flow files. -Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. -*/ - -#include "mainwindow.h" -#include "ui_mainwindow.h" - -#include "flowEditCanvas.h" -#include "shortcutListDialog.h" - -#include <QtCore/QDebug> -#include <QtGui/QFileDialog> -#include <QtGui/QMessageBox> - -#define MAX_SEARCH_SHIFT 500 - -MainWindow::MainWindow(QWidget *parent) : - QMainWindow(parent), - ui(new Ui::MainWindow), - m_cs(this) -{ - ui->setupUi(this); - - restoreGeometry(m_settings.value("geometry").toByteArray()); - restoreState(m_settings.value("windowState").toByteArray()); - - m_canvas = new FlowEditCanvas(this); - setCentralWidget(m_canvas); - m_canvas->setAmplification(m_settings.value("view/amplify", 1.0).toFloat()); - - m_cs.addShortcut("o", OPEN, "Open flow file"); - m_cs.addShortcut("s-s", SAVE, "Save"); - m_cs.addShortcut("j", PREV, "Previous file"); - m_cs.addShortcut("k", NEXT, "Next file"); - m_cs.addShortcut("b-1", BOOST1, "No amplification"); - m_cs.addShortcut("b-2", BOOST2, "Low amplification"); - m_cs.addShortcut("b-3", BOOST3, "High amplification (details best visible)"); - m_cs.addShortcut("q-q", QUIT, "Quit"); - m_cs.addShortcut("h-h", HELP, "Show shortcut dialog"); - - ui->actionQuit->setShortcut(QKeySequence("Ctrl+Q")); - ui->actionOpen->setShortcut(QKeySequence("Ctrl+O")); - ui->actionSave->setShortcut(QKeySequence("Ctrl+S")); - ui->actionPrev->setShortcut(QKeySequence("Ctrl+Left")); - ui->actionNext->setShortcut(QKeySequence("Ctrl+Right")); - ui->actionShortcuts->setShortcut(QKeySequence("F1")); - - bool b = true; - b &= connect(ui->actionQuit, SIGNAL(triggered()), this, SLOT(close())); - b &= connect(ui->actionOpen, SIGNAL(triggered()), this, SLOT(slotOpenFlow())); - b &= connect(ui->actionSave, SIGNAL(triggered()), this, SLOT(slotSaveFlow())); - b &= connect(ui->actionNext, SIGNAL(triggered()), this, SLOT(slotNextFile())); - b &= connect(ui->actionPrev, SIGNAL(triggered()), this, SLOT(slotPrevFile())); - b &= connect(ui->actionShortcuts, SIGNAL(triggered()), this, SLOT(slotShowShortcuts())); - b &= connect(&m_cs, SIGNAL(signalShortcutUsed(int)), this, SLOT(slotShortcutUsed(int))); - Q_ASSERT(b); - - - updateTitle(); - if (m_settings.value("prevFlowFile", "").toString().length() != 0) { - loadFlow(m_settings.value("prevFlowFile", "").toString()); - } - - qDebug() << "Shortcut list: " << m_cs.shortcutList(); -} - -MainWindow::~MainWindow() -{ - delete ui; -} - -const CombinedShortcuts& MainWindow::shortcuts() const -{ - return m_cs; -} - -void MainWindow::updateTitle() -{ - QString file = m_lastFlowFile; - if (file.length() == 0) { - file = "no file loaded"; - } - setWindowTitle(QString("slowmo Flow Editor (%1)").arg(file)); -} - -void MainWindow::closeEvent(QCloseEvent *e) -{ - m_settings.setValue("geometry", saveGeometry()); - m_settings.setValue("windowState", saveState()); - if (m_lastFlowFile.length() > 0) { - m_settings.setValue("prevFlowFile", m_lastFlowFile); - } - m_settings.setValue("view/amplify", m_canvas->amplification()); - QMainWindow::closeEvent(e); -} - -QString MainWindow::nextFilename(QString originalName, int shift) const -{ - if (false) { - QStringList parts; - QRegExp e("(\\d+)"); - int min = originalName.indexOf("_"); - int pos = 0; - int prevPos = 0; - while ((pos = e.indexIn(originalName, pos)) != -1) { - parts << originalName.mid(prevPos, pos-prevPos); - - if (pos > min) { - parts << QVariant(e.cap(1).toInt()+shift).toString(); - } else { - parts << e.cap(1); - } - - pos += e.matchedLength(); - prevPos = pos; - } - parts << originalName.mid(prevPos); - return parts.join(""); - } else { - QStringList filters; - filters << "*.sVflow"; - - QDir dir(QFileInfo(originalName).absolutePath()); - QStringList filenames = dir.entryList(filters, QDir::Files | QDir::Readable, QDir::Name); - - QString current = QFileInfo(originalName).fileName(); - QString next; - if (filenames.contains(current)) { - int index = filenames.indexOf(current); - if (filenames.size() > index+shift && index+shift >= 0) { - next = QFileInfo(originalName).absolutePath() + "/" + filenamesindex+shift; - } else { - qDebug() << "No file in this direction"; - } - } else { - qDebug() << filenames; - } - - return next; - } -} - -void MainWindow::loadFlow(QString filename) -{ - if (QFileInfo(filename).exists()) { - m_canvas->slotLoadFlow(filename); - m_lastFlowFile = filename; - updateTitle(); - } -} - -void MainWindow::slotOpenFlow() -{ - QFileDialog dialog(this, "Open flow file"); - dialog.setAcceptMode(QFileDialog::AcceptOpen); - dialog.setFileMode(QFileDialog::ExistingFile); - dialog.setNameFilter("Flow files (*.sVflow)"); - if (m_settings.value("directories/lastFlowDir", "").toString().length() > 0) { - dialog.setDirectory(m_settings.value("directories/lastFlowDir", "").toString()); - } - if (dialog.exec() == QDialog::Accepted) { - m_settings.setValue("directories/lastFlowDir", QFileInfo(dialog.selectedFiles().at(0)).absolutePath()); - loadFlow(dialog.selectedFiles().at(0)); - statusBar()->showMessage("Loaded " + m_lastFlowFile, 3000); - } -} - -void MainWindow::slotSaveFlow() -{ - statusBar()->showMessage("Saving ...", 3000); - m_canvas->slotSaveFlow(); - statusBar()->showMessage("Saved " + m_lastFlowFile, 3000); -} - -void MainWindow::slotNextFile() -{ - slotChangeFile(+1); -} - -void MainWindow::slotPrevFile() -{ - slotChangeFile(-1); -} - -void MainWindow::slotChangeFile(int shift) -{ - for (int i = 1; i < MAX_SEARCH_SHIFT; i++) { - QString name = nextFilename(m_lastFlowFile, i*shift); - if (QFileInfo(name).exists()) { - loadFlow(name); - return; - } - } - QMessageBox::warning(this, "File not found", QString("The flow file %1 does not exist.\n\n " - "I even searched %2 steps for a file in this direction, " - "and still did not find a file.") - .arg(nextFilename(m_lastFlowFile, shift)).arg(MAX_SEARCH_SHIFT), QMessageBox::Ok); -} - -void MainWindow::amplify(float val) -{ - m_canvas->setAmplification(val); - statusBar()->showMessage(QString("Setting visual amplification to %1").arg(val), 3000); -} - -void MainWindow::slotShortcutUsed(int id) -{ - if (id == BOOST1) { - qDebug() << "Amplify 1"; - amplify(1); - } else if (id == BOOST2) { - qDebug() << "Amplify 2"; - amplify(3); - } else if (id == BOOST3) { - qDebug() << "Amplify 3"; - amplify(9); - } else if (id == PREV) { - slotPrevFile(); - } else if (id == NEXT) { - slotNextFile(); - } else if (id == OPEN) { - slotOpenFlow(); - } else if (id == SAVE) { - slotSaveFlow(); - } else if (id == HELP) { - slotShowShortcuts(); - } else if (id == QUIT) { - close(); - } else { - qDebug() << "Shortcut with ID " << id << " has no action!"; - Q_ASSERT(false); - } -} - -void MainWindow::slotShowShortcuts() -{ - ShortcutListDialog dialog(this); - dialog.exec(); -}
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/slowmoFlowEdit/mainwindow.h
Deleted
@@ -1,70 +0,0 @@ -/* -slowmoFlowEdit is a user interface for editing slowmoVideo's Optical Flow files. -Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. -*/ - -#ifndef MAINWINDOW_H -#define MAINWINDOW_H - -#include "../libgui/combinedShortcuts.h" - -#include <QMainWindow> -#include <QSettings> - -class FlowEditCanvas; -namespace Ui { - class MainWindow; -} - -class MainWindow : public QMainWindow -{ - Q_OBJECT - -public: - explicit MainWindow(QWidget *parent = 0); - ~MainWindow(); - - const CombinedShortcuts& shortcuts() const; - -protected slots: - void closeEvent(QCloseEvent *e); - -private: - enum Shortcuts { - BOOST1, BOOST2, BOOST3, OPEN, SAVE, PREV, NEXT, HELP, QUIT - }; - - Ui::MainWindow *ui; - CombinedShortcuts m_cs; - - FlowEditCanvas *m_canvas; - - QSettings m_settings; - QString m_lastFlowFile; - - void updateTitle(); - void loadFlow(QString filename); - - void amplify(float val); - - QString nextFilename(QString originalName, int shift) const; - - -private slots: - void slotOpenFlow(); - void slotSaveFlow(); - - void slotNextFile(); - void slotPrevFile(); - void slotChangeFile(int shift); - - void slotShortcutUsed(int id); - void slotShowShortcuts(); -}; - -#endif // MAINWINDOW_H
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/slowmoFlowEdit/mainwindow.ui
Deleted
@@ -1,89 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>MainWindow</class> - <widget class="QMainWindow" name="MainWindow"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>800</width> - <height>600</height> - </rect> - </property> - <property name="windowTitle"> - <string>slowmo Flow Editor</string> - </property> - <widget class="QWidget" name="centralwidget"/> - <widget class="QMenuBar" name="menubar"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>800</width> - <height>22</height> - </rect> - </property> - <widget class="QMenu" name="menuFile"> - <property name="title"> - <string>File</string> - </property> - <addaction name="actionOpen"/> - <addaction name="actionSave"/> - <addaction name="separator"/> - <addaction name="actionPrev"/> - <addaction name="actionNext"/> - <addaction name="separator"/> - <addaction name="actionQuit"/> - </widget> - <widget class="QMenu" name="menuHelp"> - <property name="title"> - <string>Help</string> - </property> - <addaction name="actionShortcuts"/> - </widget> - <addaction name="menuFile"/> - <addaction name="menuHelp"/> - </widget> - <widget class="QStatusBar" name="statusbar"/> - <action name="actionOpen"> - <property name="text"> - <string>Open</string> - </property> - </action> - <action name="actionSave"> - <property name="text"> - <string>Save</string> - </property> - </action> - <action name="actionQuit"> - <property name="text"> - <string>Quit</string> - </property> - </action> - <action name="actionNext"> - <property name="text"> - <string>Next file</string> - </property> - </action> - <action name="actionPrev"> - <property name="text"> - <string>Previous file</string> - </property> - </action> - <action name="actionAmplify"> - <property name="checkable"> - <bool>true</bool> - </property> - <property name="text"> - <string>Amplify colours</string> - </property> - </action> - <action name="actionShortcuts"> - <property name="text"> - <string>Shortcuts</string> - </property> - </action> - </widget> - <resources/> - <connections/> -</ui>
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/slowmoInfo
Deleted
-(directory)
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/slowmoInfo/CMakeLists.txt
Deleted
@@ -1,5 +0,0 @@ - -add_executable(slowmoInfo slowmoInfo.cpp) -target_link_libraries(slowmoInfo sV ${EXTERNAL_LIBS}) - -install(TARGETS slowmoInfo DESTINATION ${DEST})
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/slowmoInfo/slowmoInfo.cpp
Deleted
@@ -1,20 +0,0 @@ - -#include "../lib/defs_sV.hpp" -#include <iostream> - -int main(int argc, char *argv) -{ - if (argc-1 > 0) { - if (strcmp("platform", argv1) == 0) { - std::cout << Version_sV::platform.toStdString(); - } else if (strcmp("version", argv1) == 0) { - std::cout << Version_sV::version.toStdString(); - } else if (strcmp("bits", argv1) == 0) { - std::cout << Version_sV::bits.toStdString(); - } else { - std::cout << "Argument not recognized; see " << argv0 << " (without arguments) for a list.\n"; - } - } else { - std::cout << "Possible arguments: version, bits, platform\n"; - } -}
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/slowmoRenderer
Deleted
-(directory)
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/slowmoRenderer/CMakeLists.txt
Deleted
@@ -1,15 +0,0 @@ - -include_directories(..) - -set(SRCS - rendererMain.cpp - slowmoRenderer_sV.cpp -) -set(SRCS_MOC - slowmoRenderer_sV.h -) -qt4_wrap_cpp(MOC_OUT ${SRCS_MOC}) - -add_executable(slowmoRenderer ${SRCS} ${MOC_OUT}) -target_link_libraries(slowmoRenderer sVproj ${EXTERNAL_LIBS}) -install(TARGETS slowmoRenderer DESTINATION ${DEST})
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/slowmoRenderer/rendererMain.cpp
Deleted
@@ -1,217 +0,0 @@ -/* -This file is part of slowmoVideo. -Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. -*/ - -#include "slowmoRenderer_sV.h" - -#include <QtCore/QCoreApplication> -#include <QtCore/QStringList> - -#include <iostream> -#include <csignal> -#include <cstdlib> - -QString myName; -SlowmoRenderer_sV renderer; - -int terminateCounter = 0; - -void terminate(int) -{ - if (terminateCounter == 0) { - std::cout << "Telling renderer to stop." << std::endl; - } else if (terminateCounter == 1) { - std::cout << "Really want to kill rendering? Send the SIGINT a third time." << std::endl; - } else { - exit(SIGINT); - } - terminateCounter++; - renderer.abort(); -} -void printProgress(int) -{ - renderer.printProgress(); -} - -void printHelp() -{ - std::cout << "slowmoRenderer for slowmoVideo " << Version_sV::version.toStdString() << std::endl - << myName.toStdString() << " <project>" << std::endl - << "\t-target video <path> <codec>|auto | images <filenamePattern> <directory> " << std::endl - << "\t-size small|orig " << std::endl - << "\t-fps <fps> " << std::endl - << "\t-start <startTime> -end <endTime> " << std::endl - << "\t-interpolation forward2|twoway2 " << std::endl - << "\t -motionblur stack|convolve " << std::endl - << "\t-v3dLambda <lambda> " << std::endl; -} - -void require(int nArgs, int index, int size) -{ - if (size <= index + nArgs) { - std::cout << "Not enough arguments delivered (" << nArgs << " required)." << std::endl; - printHelp(); - exit(-1); - } -} - -int main(int argc, char *argv) -{ - QCoreApplication app(argc, argv); - - // Set up preferences for the QSettings file - QCoreApplication::setOrganizationName("Granjow"); - QCoreApplication::setOrganizationDomain("granjow.net"); - QCoreApplication::setApplicationName("slowmoUI"); - - if (signal(SIGINT, terminate) == SIG_ERR) { - std::cerr << "Could not set up SIGINT handler." << std::endl; - } -#ifndef WINDOWS - if (signal(SIGUSR1, printProgress) == SIG_ERR) { - std::cerr << "Could not set up SIGUSR1 handler." << std::endl; - } -#endif - - QStringList args = app.arguments(); - myName = args.at(0); - if (argc <= 1 - || "--help" == args.at(1) || "-h" == args.at(1)) { - printHelp(); - return 0; - } - - - - renderer.load(args.at(1)); - - QString start = ":start"; - QString end = ":end"; - - const int n = args.size(); - int next = 2; - while (next < n) { - if ("-target" == args.at(next)) { - require(3, next, n); - next++; - if ("video" == args.at(next)) { - next++; - QString filename = args.at(next++); - QString codec = args.at(next++); - if ("auto" == codec) { codec = ""; } - - renderer.setVideoRenderTarget(filename, codec); - - } else if ("images" == args.at(next)) { - next++; - QString filenamePattern = args.at(next++); - QString dir = args.at(next++); - renderer.setImagesRenderTarget(filenamePattern, dir); - - } else { - std::cerr << "Not a valid target: " << args.at(next).toStdString() << std::endl; - return -1; - } - - } else if ("-size" == args.at(next)) { - require(1, next, n); - next++; - if ("small" == args.at(next)) { - renderer.setSize(false); - } else if ("orig" == args.at(next)) { - renderer.setSize(true); - } else { - std::cerr << "Not a valid size: " << args.at(next).toStdString() << std::endl; - return -1; - } - next++; - - } else if ("-fps" == args.at(next)) { - require(1, next, n); - next++; - bool b; - double fps = args.at(next).toDouble(&b); - if (!b) { - std::cerr << "Not a number: " << args.at(next).toStdString() << std::endl; - return -1; - } - renderer.setFps(fps); - next++; - - } else if ("-start" == args.at(next)) { - require(1, next, n); - next++; - start = args.at(next++); - - } else if ("-end" == args.at(next)) { - require(1, next, n); - next++; - end = args.at(next++); - - } else if ("-interpolation" == args.at(next)) { - require(1, next, n); - next++; - if ("forward" == args.at(next)) { - renderer.setInterpolation(InterpolationType_Forward); - } else if ("forward2" == args.at(next)) { - renderer.setInterpolation(InterpolationType_ForwardNew); - } else if ("twoway" == args.at(next)) { - renderer.setInterpolation(InterpolationType_Twoway); - } else if ("twoway2" == args.at(next)) { - renderer.setInterpolation(InterpolationType_TwowayNew); - } else { - std::cerr << "Not a valid interpolation type: " << args.at(next).toStdString() << std::endl; - return -1; - } - next++; - - } else if ("-motionblur" == args.at(next)) { - require(1, next, n); - next++; - if ("stack" == args.at(next)) { - renderer.setMotionblur(MotionblurType_Stacking); - } else if ("convolve" == args.at(next)) { - renderer.setMotionblur(MotionblurType_Convolving); - } else { - std::cerr << "Not a valid motion blur type: " << args.at(next).toStdString() << std::endl; - return -1; - } - next++; - - } else if ("-v3dLambda" == args.at(next)) { - require(1, next, n); - next++; - bool b; - float lambda = args.at(next).toFloat(&b); - if (!b) { - std::cerr << "Not a number: " << args.at(next).toStdString() << std::endl; - return -1; - } - renderer.setV3dLambda(lambda); - next++; - - } else { - std::cout << "Argument not recognized: " << args.at(next).toStdString() << std::endl; - printHelp(); - return -1; - } - } - - renderer.setTimeRange(start, end); - - QString msg; - if (!renderer.isComplete(msg)) { - std::cout << msg.toStdString() << std::endl; - std::cout << "Project will not be rendered." << std::endl; - return 42; - } - - renderer.start(); - -}
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/slowmoRenderer/slowmoRenderer_sV.cpp
Deleted
@@ -1,171 +0,0 @@ -/* -This file is part of slowmoVideo. -Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. -*/ - -#include "slowmoRenderer_sV.h" - -#include "project/project_sV.h" -#include "project/projectPreferences_sV.h" -#include "project/xmlProjectRW_sV.h" -#include "project/renderTask_sV.h" -#include "project/imagesRenderTarget_sV.h" -#include "project/videoRenderTarget_sV.h" -#include "project/flowSourceV3D_sV.h" - -#include <iostream> - -Error::Error(std::string message) : - message(message) {} - -SlowmoRenderer_sV::SlowmoRenderer_sV() : - m_project(NULL), - m_taskSize(0), - m_lastProgress(0), - m_start(":start"), - m_end(":end"), - m_renderTargetSet(false) -{ -} - -SlowmoRenderer_sV::~SlowmoRenderer_sV() -{ - delete m_project; -} - -void SlowmoRenderer_sV::load(QString filename) throw(Error) -{ - if (m_project != NULL) { - delete m_project; - m_project = NULL; - } - QString warning; - try { - Project_sV *proj = XmlProjectRW_sV::loadProject(QString(filename), &warning); - - if (warning.length() > 0) { - std::cout << warning.toStdString() << std::endl; - } - - m_project = proj; - - RenderTask_sV *task = new RenderTask_sV(m_project); - m_project->replaceRenderTask(task); - task->renderPreferences().setFps(24); - task->setTimeRange(m_start, m_end); - task->setQtConnectionType(Qt::AutoConnection); - - bool b = true; - b &= connect(m_project->renderTask(), SIGNAL(signalNewTask(QString,int)), this, SLOT(slotTaskSize(QString,int))); - b &= connect(m_project->renderTask(), SIGNAL(signalTaskProgress(int)), this, SLOT(slotProgressInfo(int))); - b &= connect(m_project->renderTask(), SIGNAL(signalRenderingAborted(QString)), this, SLOT(slotFinished(QString))); - b &= connect(m_project->renderTask(), SIGNAL(signalRenderingFinished(QString)), this, SLOT(slotFinished(QString))); - b &= connect(m_project->renderTask(), SIGNAL(signalRenderingStopped(QString)), this, SLOT(slotFinished(QString))); - Q_ASSERT(b); - - } catch (Error_sV &err) { - throw Error(err.message().toStdString()); - } -} - -void SlowmoRenderer_sV::setTimeRange(QString start, QString end) -{ - m_start = start; - m_end = end; - m_project->renderTask()->setTimeRange(m_start, m_end); -} - -void SlowmoRenderer_sV::setFps(double fps) -{ - m_project->renderTask()->renderPreferences().setFps(fps); -} - -void SlowmoRenderer_sV::setVideoRenderTarget(QString filename, QString codec) -{ - VideoRenderTarget_sV *vrt = new VideoRenderTarget_sV(m_project->renderTask()); - vrt->setTargetFile(QString(filename)); - vrt->setVcodec(QString(codec)); - m_project->renderTask()->setRenderTarget(vrt); - m_renderTargetSet = true; -} - -void SlowmoRenderer_sV::setImagesRenderTarget(QString filenamePattern, QString directory) -{ - ImagesRenderTarget_sV *irt = new ImagesRenderTarget_sV(m_project->renderTask()); - irt->setFilenamePattern(QString(filenamePattern)); - irt->setTargetDir(QString(directory)); - m_project->renderTask()->setRenderTarget(irt); - m_renderTargetSet = true; -} - -void SlowmoRenderer_sV::setInterpolation(InterpolationType interpolation) -{ - m_project->renderTask()->renderPreferences().interpolation = interpolation; -} - -void SlowmoRenderer_sV::setMotionblur(MotionblurType motionblur) -{ - m_project->renderTask()->renderPreferences().motionblur = motionblur; -} - -void SlowmoRenderer_sV::setSize(bool original) -{ - if (original) { - m_project->renderTask()->renderPreferences().size = FrameSize_Orig; - } else { - m_project->renderTask()->renderPreferences().size = FrameSize_Small; - } -} - -void SlowmoRenderer_sV::setV3dLambda(float lambda) -{ - m_project->preferences()->flowV3DLambda() = lambda; -} - -void SlowmoRenderer_sV::start() -{ - m_project->renderTask()->slotContinueRendering(); -} -void SlowmoRenderer_sV::abort() -{ - m_project->renderTask()->slotStopRendering(); -} - - -void SlowmoRenderer_sV::slotProgressInfo(int progress) -{ - m_lastProgress = progress; -} -void SlowmoRenderer_sV::slotTaskSize(QString desc, int size) -{ - std::cout << desc.toStdString() << std::endl; - m_taskSize = size; -} - -void SlowmoRenderer_sV::slotFinished(QString time) -{ - std::cout << std::endl << "Rendering finished. Time taken: " << time.toStdString() << std::endl; -} - - -void SlowmoRenderer_sV::printProgress() -{ - std::cout << m_lastProgress << "/" << m_taskSize << std::endl; -} - -bool SlowmoRenderer_sV::isComplete(QString &message) const -{ - bool b = true; - if (!m_renderTargetSet) { - b = false; - message.append("No render target set.\n"); - } - return b; -} - -
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/slowmoRenderer/slowmoRenderer_sV.h
Deleted
@@ -1,77 +0,0 @@ -/* -This file is part of slowmoVideo. -Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. -*/ - -#ifndef SLOWMORENDERER_SV_H -#define SLOWMORENDERER_SV_H - -#include "lib/defs_sV.hpp" -#include <QtCore/QObject> -#include <QtCore/QCoreApplication> -#include <string> - -class Project_sV; - -class Error { -public: - Error(std::string message); - std::string message; -}; - -/** - \brief Just for rendering. - */ -class SlowmoRenderer_sV : public QObject -{ - Q_OBJECT -public: - SlowmoRenderer_sV(); - ~SlowmoRenderer_sV(); - - void load(QString filename) throw(Error); - void start(); - void abort(); - - void setTimeRange(QString start, QString end); - void setFps(double fps); - void setVideoRenderTarget(QString filename, QString codec); - void setImagesRenderTarget(QString filenamePattern, QString directory); - void setInterpolation(InterpolationType interpolation); - void setMotionblur(MotionblurType motionblur); - void setSize(bool original); - void setV3dLambda(float lambda); - - - void printProgress(); - - /// Checks if all necessary parameters (e.g. paths) are set - /// \param message Will contain an error message if the function returned \c false - bool isComplete(QString &message) const; - - -private: - Project_sV *m_project; - - int m_taskSize; - int m_lastProgress; - - QString m_start; - QString m_end; - - bool m_renderTargetSet; - - -private slots: - void slotProgressInfo(int progress); - void slotTaskSize(QString desc, int size); - void slotFinished(QString time); -}; - - -#endif // SLOWMORENDERER_SV_H
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/slowmoUI
Deleted
-(directory)
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/slowmoUI/CMakeLists.txt
Deleted
@@ -1,127 +0,0 @@ - -# Building Qt+UI apps: -# http://www.qtcentre.org/wiki/index.php?title=Compiling_Qt4_apps_with_CMake -# http://www.cmake.org/pipermail/cmake/2008-September/023908.html - - - -include_directories(${slowmoVideo_SOURCE_DIR}) - -set(SRCS - main.cpp - mainwindow.cpp - canvas.cpp - canvasTools.cpp - frameMonitor.cpp - renderPreview.cpp - dialogues/newProjectDialog.cpp - dialogues/preferencesDialog.cpp - dialogues/projectPreferencesDialog.cpp - dialogues/progressDialog.cpp - dialogues/renderingDialog.cpp - dialogues/shutterFunctionDialog.cpp - dialogues/shutterFunctionFrame.cpp - dialogues/flowExaminer.cpp - dialogues/tagAddDialog.cpp - dialogues/aboutDialog.cpp -) - -set(SRCS_UI - mainwindow.ui - canvas.ui - frameMonitor.ui - renderPreview.ui - dialogues/newProjectDialog.ui - dialogues/preferencesDialog.ui - dialogues/projectPreferencesDialog.ui - dialogues/progressDialog.ui - dialogues/renderingDialog.ui - dialogues/shutterFunctionDialog.ui - dialogues/flowExaminer.ui - dialogues/tagAddDialog.ui - dialogues/aboutDialog.ui -) - -set(SRCS_MOC - mainwindow.h - canvas.h - frameMonitor.h - renderPreview.h - dialogues/newProjectDialog.h - dialogues/preferencesDialog.h - dialogues/projectPreferencesDialog.h - dialogues/progressDialog.h - dialogues/renderingDialog.h - dialogues/shutterFunctionDialog.h - dialogues/shutterFunctionFrame.h - dialogues/flowExaminer.h - dialogues/tagAddDialog.h - dialogues/aboutDialog.h -) - - -if(APPLE) - set(BUNDLE "slowmoUI") - set(ICONS_DIR "${${PROJECT_NAME}_SOURCE_DIR}/slowmoVideo/slowmoUI/res") - message( "OS X build" ) - set(MACOSX_BUNDLE_INFO_STRING "${BUNDLE} ${PROJECT_VERSION}") - set(MACOSX_BUNDLE_BUNDLE_VERSION "${BUNDLE} ${PROJECT_VERSION}") - set(MACOSX_BUNDLE_LONG_VERSION_STRING "${BUNDLE} ${PROJECT_VERSION}") - set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${PROJECT_VERSION}") - set(MACOSX_BUNDLE_COPYRIGHT "${PROJECT_COPYRIGHT_YEAR} ${PROJECT_VENDOR}") - set(MACOSX_BUNDLE_ICON_FILE "slowmoUI.icns") - set(MACOSX_BUNDLE_GUI_IDENTIFIER "${PROJECT_DOMAIN_SECOND}.${PROJECT_DOMAIN_FIRST}") - set(MACOSX_BUNDLE_BUNDLE_NAME "${BUNDLE}") - - set(MACOSX_BUNDLE_RESOURCES "${CMAKE_CURRENT_BINARY_DIR}/${BUNDLE}.app/Contents/Resources") - set(MACOSX_BUNDLE_ICON "${ICONS_DIR}/${MACOSX_BUNDLE_ICON_FILE}") - SET_SOURCE_FILES_PROPERTIES( - ${MACOSX_BUNDLE_ICON} - PROPERTIES MACOSX_PACKAGE_LOCATION Resources) - message(STATUS "Bundle will be : ${MACOSX_BUNDLE} => ${PROJECT_NAME} ") - - set( SRCS ${SRCS} ${MACOSX_BUNDLE_ICON} ) - -endif() - -# Without these includes the promoted widgets fail to compile -# since the headers are not found. (For whatever reason.) -include_directories(dialogues) -include_directories(.) -include_directories(..) - -# Embed images in the binary -set(SRC_RES resources.qrc) -qt4_add_resources(RES_OUT ${SRC_RES}) - -# Generate header files from the .ui files -qt4_wrap_ui(UI_H_OUT ${SRCS_UI}) -qt4_wrap_cpp(MOC_OUT ${SRCS_MOC}) - -# Include the generated header files -include_directories(${CMAKE_BINARY_DIR}/slowmoVideo/slowmoUI) - - - -add_executable(slowmoUI WIN32 MACOSX_BUNDLE ${SRCS} ${MOC_OUT} ${UI_H_OUT} ${RES_OUT}) -target_link_libraries(slowmoUI sVproj sVvis sVgui ${EXTERNAL_LIBS}) - -if(APPLE) - configure_file(${CMAKE_SOURCE_DIR}/slowmoVideo/slowmoUI/res/Info.plist.cmake ${CMAKE_CURRENT_BINARY_DIR}/Info.plist) - set_target_properties(${PROGNAME} PROPERTIES - MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_BINARY_DIR}/Info.plist) -endif() - -install(TARGETS ${slowmoUI} - BUNDLE DESTINATION . COMPONENT Runtime - RUNTIME DESTINATION ${BIN_INSTALL_DIR} COMPONENT Runtime) - -if (APPLE) - install(TARGETS slowmoUI DESTINATION ".") - include(DeployQt4) - install_qt4_executable(slowmoUI.app "" "" ) - -else() - install(TARGETS slowmoUI DESTINATION ${DEST}) -endif() -
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/slowmoUI/canvas.cpp
Deleted
@@ -1,1232 +0,0 @@ -/* -slowmoUI is a user interface for slowmoVideo. -Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. -*/ - -#include "canvas.h" -#include "canvasTools.h" -#include "ui_canvas.h" - -#include "mainwindow.h" -#include "tagAddDialog.h" -#include "shutterFunctionDialog.h" -#include "project/shutterFunction_sV.h" -#include "project/shutterFunctionList_sV.h" -#include "lib/bezierTools_sV.h" - -#include "project/projectPreferences_sV.h" -#include "project/abstractFrameSource_sV.h" - -#include <cmath> -#include <typeinfo> - -#include <QtCore/QDebug> - -#include <QtCore/QPoint> -#include <QtCore/QPointF> -#include <QtCore/QSignalMapper> - -#include <QtGui/QColor> -#include <QtGui/QImage> -#include <QtGui/QMouseEvent> -#include <QtGui/QPainter> -#include <QtGui/QPainterPath> -#include <QtGui/QMenu> -#include <QtGui/QInputDialog> - - - -//#define VALIDATE_BEZIER -#ifdef VALIDATE_BEZIER -#include "lib/bezierTools_sV.h" -#endif - -//#define DEBUG_C -#ifdef DEBUG_C -#include <iostream> -#endif - -QColor Canvas::selectedCol ( 0, 175, 255, 100); -QColor Canvas::hoverCol (255, 175, 0, 200); -QColor Canvas::lineCol (255, 255, 255); -QColor Canvas::selectedLineCol(255, 175, 0, 200); -QColor Canvas::nodeCol (240, 240, 240); -QColor Canvas::gridCol (255, 255, 255, 30); -QColor Canvas::fatGridCol (255, 255, 255, 60); -QColor Canvas::minGridCol (200, 200, 255, 150); -QColor Canvas::handleLineCol(255, 255, 255, 128); -QColor Canvas::srcTagCol ( 30, 245, 0, 150); -QColor Canvas::outTagCol ( 30, 245, 0, 150); -QColor Canvas::backgroundCol( 34, 34, 34); -QColor Canvas::shutterRegionCol(175, 25, 75, 100); -QColor Canvas::shutterRegionBoundCol(240, 0, 60, 150); - -/// \todo move with MMB -/// \todo replay curve - -Canvas::Canvas(Project_sV *project, QWidget *parent) : - QWidget(parent), - ui(new Ui::Canvas), - m_project(project), - m_mouseWithinWidget(false), - m_distLeft(90), - m_distBottom(50), - m_distRight(20), - m_distTop(32), - m_t0(0,0), - m_tmax(10,10), - m_secResX(100), - m_secResY(100), - m_showHelp(false), - m_nodes(project->nodes()), - m_tags(project->tags()), - m_mode(ToolMode_Select) -{ - ui->setupUi(this); - m_shutterFunctionDialog = NULL; - - // Enable mouse tracking (not only when a mouse button is pressed) - this->setMouseTracking(true); - - setContextMenuPolicy(Qt::DefaultContextMenu); - - m_states.prevMousePos = QPoint(0,0); - m_states.contextmenuMouseTime = QPointF(0,0); - m_states.initialContextObject = NULL; - - Q_ASSERT(m_secResX > 0); - Q_ASSERT(m_secResY > 0); - - m_aDeleteNode = new QAction(tr("&Delete node"), this); - m_aSnapInNode = new QAction(tr("&Snap in node"), this); - m_aDeleteTag = new QAction(tr("&Delete tag"), this); - m_aRenameTag = new QAction(tr("&Rename tag"), this); - m_aSetTagTime = new QAction(tr("Set tag &time"), this); - m_hackMapper = new QSignalMapper(this); - m_hackMapper->setMapping(m_aRenameTag, &m_toRenameTag); m_toRenameTag.reason = TransferObject::ACTION_RENAME; - m_hackMapper->setMapping(m_aDeleteTag, &m_toDeleteTag); m_toDeleteTag.reason = TransferObject::ACTION_DELETE; - m_hackMapper->setMapping(m_aDeleteNode, &m_toDeleteNode); m_toDeleteNode.reason = TransferObject::ACTION_DELETE; - m_hackMapper->setMapping(m_aSnapInNode, &m_toSnapInNode); m_toSnapInNode.reason = TransferObject::ACTION_SNAPIN; - m_hackMapper->setMapping(m_aSetTagTime, &m_toSetTagTime); m_toSetTagTime.reason = TransferObject::ACTION_SETTIME; - - m_curveTypeMapper = new QSignalMapper(this); - m_aLinear = new QAction(tr("&Linear curve"), this); - m_aBezier = new QAction(trUtf8("&Bézier curve"), this); - m_curveTypeMapper->setMapping(m_aLinear, CurveType_Linear); - m_curveTypeMapper->setMapping(m_aBezier, CurveType_Bezier); - - m_aCustomSpeed = new QAction(tr("Set &custom speed"), this); - m_aShutterFunction = new QAction(tr("Set/edit shutter &function"), this); - - m_speedsMapper = new QSignalMapper(this); - double arr = {1, .5, 0, -.5, -1}; -#define N_SPEEDS 5 - for (int i = 0; i < N_SPEEDS; i++) { - m_aSpeeds.push_back(new QAction(trUtf8("Set speed to %1×").arg(arri, 0, 'f', 1), this)); - m_speedsMapper->setMapping(m_aSpeeds.back(), QString("%1").arg(arri,0,'f',1)); - } - - m_handleMapper = new QSignalMapper(this); - m_aResetLeftHandle = new QAction(tr("Reset left handle"), this); - m_aResetRightHandle = new QAction(tr("Reset right handle"), this); - m_handleMapper->setMapping(m_aResetLeftHandle, "left"); - m_handleMapper->setMapping(m_aResetRightHandle, "right"); - - - bool b = true; - b &= connect(m_aSnapInNode, SIGNAL(triggered()), m_hackMapper, SLOT(map())); - b &= connect(m_aDeleteNode, SIGNAL(triggered()), m_hackMapper, SLOT(map())); - b &= connect(m_aDeleteTag, SIGNAL(triggered()), m_hackMapper, SLOT(map())); - b &= connect(m_aRenameTag, SIGNAL(triggered()), m_hackMapper, SLOT(map())); - b &= connect(m_aSetTagTime, SIGNAL(triggered()), m_hackMapper, SLOT(map())); - b &= connect(m_hackMapper, SIGNAL(mapped(QObject*)), this, SLOT(slotRunAction(QObject*))); - b &= connect(m_aLinear, SIGNAL(triggered()), m_curveTypeMapper, SLOT(map())); - b &= connect(m_aBezier, SIGNAL(triggered()), m_curveTypeMapper, SLOT(map())); - b &= connect(m_curveTypeMapper, SIGNAL(mapped(int)), this, SLOT(slotChangeCurveType(int))); - b &= connect(m_aResetLeftHandle, SIGNAL(triggered()), m_handleMapper, SLOT(map())); - b &= connect(m_aResetRightHandle, SIGNAL(triggered()), m_handleMapper, SLOT(map())); - b &= connect(m_handleMapper, SIGNAL(mapped(QString)), this, SLOT(slotResetHandle(QString))); - b &= connect(m_aCustomSpeed, SIGNAL(triggered()), this, SLOT(slotSetSpeed())); - b &= connect(m_speedsMapper, SIGNAL(mapped(QString)), this, SLOT(slotSetSpeed(QString))); - b &= connect(m_aShutterFunction, SIGNAL(triggered()), this, SLOT(slotSetShutterFunction())); - for (std::vector<QAction*>::iterator it = m_aSpeeds.begin(); it != m_aSpeeds.end(); ++it) { - b &= connect(*it, SIGNAL(triggered()), m_speedsMapper, SLOT(map())); - } - Q_ASSERT(b); -} - -Canvas::~Canvas() -{ - delete ui; - if (m_shutterFunctionDialog != NULL) { - delete m_shutterFunctionDialog; - } - - while (!m_aSpeeds.empty()) { - delete m_aSpeeds.back(); - m_aSpeeds.pop_back(); - } - delete m_speedsMapper; - delete m_hackMapper; - - delete m_aSnapInNode; - delete m_aDeleteNode; - delete m_aDeleteTag; - delete m_aRenameTag; -} - -void Canvas::load(Project_sV *project) -{ - if (m_shutterFunctionDialog != NULL) { - m_shutterFunctionDialog->close(); - delete m_shutterFunctionDialog; - m_shutterFunctionDialog = NULL; - } - - m_project = project; - m_t0 = m_project->preferences()->viewport_t0(); - m_secResX = m_project->preferences()->viewport_secRes().x(); - m_secResY = m_project->preferences()->viewport_secRes().y(); - Q_ASSERT(m_secResX > 0); - Q_ASSERT(m_secResY > 0); - qDebug() << "Canvas: Project loaded from " << project; - m_nodes = project->nodes(); - m_tags = project->tags(); - qDebug() << "Frame source: " << project->frameSource(); - m_tmax.setY(project->frameSource()->maxTime()); - qDebug() << "tMaxY set to " << m_tmax.y(); - - - repaint(); -} - -void Canvas::showHelp(bool show) -{ - m_showHelp = show; - repaint(); - - m_settings.setValue("ui/displayHelp", show); - m_settings.sync(); -} - -void Canvas::toggleHelp() -{ - showHelp(!m_showHelp); -} - -const QPointF Canvas::prevMouseTime() const -{ - return convertCanvasToTime(m_states.prevMousePos).toQPointF(); -} - -const float Canvas::prevMouseInFrame() const -{ - return convertCanvasToTime(m_states.prevMousePos).toQPointF().y() * m_project->frameSource()->fps()->fps(); -} - - -bool Canvas::selectAt(const QPoint &pos, bool addToSelection) -{ - bool selected = false; - int ti = m_nodes->find(convertCanvasToTime(pos).x()); - qDebug() << "Nearest node index: " << ti; - if (ti != -1 && m_nodes->size() > ti) { - QPoint p = convertTimeToCanvas(m_nodes->at(ti)); - qDebug() << "Mouse pos: " << pos << ", node pos: " << p; - if ( - abs(p.x() - pos.x()) <= NODE_RADIUS+SELECT_RADIUS+4 && - abs(p.y() - pos.y()) <= NODE_RADIUS+SELECT_RADIUS+4 - ) { - qDebug() << "Selected: " << pos.x() << "/" << pos.y(); - - - if (!m_nodes->at(ti).selected() && !addToSelection) { - m_nodes->unselectAll(); - } - - if (addToSelection) { - (*m_nodes)ti.select(!m_nodes->at(ti).selected()); - } else { - (*m_nodes)ti.select(true); - } - selected = true; - } - } - return selected; -} - -bool Canvas::insideCanvas(const QPoint &pos) -{ - return pos.x() >= m_distLeft && - pos.y() >= m_distTop && - pos.x() < width()-m_distRight && - pos.y() < height()-m_distBottom; -} - -QRect Canvas::leftDrawingRect(int y, const int height, const int min, const int max) const -{ - if (y < min) { y = min; } - if (max > 0 && y > max-height) { y = max-height; } - return QRect(8, y-6, m_distLeft-2*8, 50); -} -QRect Canvas::bottomDrawingRect(int x, const int width, const int min, const int max, bool rightJustified) const -{ - if (rightJustified) { - if (max > 0 && x > max) { x = max; } - if (min > 0 && x< min+width) { x = min+width; } - return QRect(x-width, height()-1 - (m_distBottom-8), width, m_distBottom-2*8); - } else { - if (max > 0 && x > max-width) { x = max-width; } - if (min > 0 && x < min) { x = min; } - return QRect(x, height()-1 - (m_distBottom-8), width, m_distBottom-2*8); - } -} - -void Canvas::paintEvent(QPaintEvent *) -{ - QPainter davinci(this); - davinci.setRenderHint(QPainter::Antialiasing, false); - davinci.fillRect(0, 0, width(), height(), backgroundCol); - - QList<NodeList_sV::PointerWithDistance> nearObjects = m_nodes->objectsNear( - convertCanvasToTime(m_states.prevMousePos).toQPointF(), - delta(SELECT_RADIUS)); - if (m_states.prevModifiers.testFlag(Qt::ShiftModifier)) { - while (nearObjects.size() > 0 && nearObjects.at(0).type == NodeList_sV::PointerWithDistance::Node) { - nearObjects.removeFirst(); - } - } - - bool drawLine; - // x grid - for (int tx = ceil(m_t0.x()); true; tx++) { - QPoint pos = convertTimeToCanvas(Node_sV(tx, m_t0.y())); - if (insideCanvas(pos)) { - drawLine = m_secResX >= 7.5; - if (tx%60 == 0) { - davinci.setPen(minGridCol); - drawLine = true; - } else if (tx%10 == 0) { - davinci.setPen(fatGridCol); - drawLine = m_secResX >= .75; - } else { - davinci.setPen(gridCol); - } - - if (drawLine) { - davinci.drawLine(pos.x(), pos.y(), pos.x(), m_distTop); - } - } else { - break; - } - } - // y grid - for (int ty = ceil(m_t0.y()); true; ty++) { - QPoint pos = convertTimeToCanvas(Node_sV(m_t0.x(), ty)); - if (insideCanvas(pos)) { - drawLine = m_secResY >= 7.5; - if (ty%60 == 0) { - davinci.setPen(minGridCol); - drawLine = true; - } else if (ty%10 == 0) { - davinci.setPen(fatGridCol); - drawLine = m_secResX >= .75; - } else { - davinci.setPen(gridCol); - } - - if (drawLine) { - davinci.drawLine(pos.x(), pos.y(), width()-1 - m_distRight, pos.y()); - } - } else { - break; - } - } - { - QPoint pos = convertTimeToCanvas(Node_sV(m_t0.x(), m_tmax.y())); - if (insideCanvas(pos)) { - davinci.setPen(QPen(QBrush(lineCol), 2)); - davinci.drawLine(pos.x(), pos.y(), width()-1-m_distRight, pos.y()); - } - } - - drawModes(davinci, 8, width()-1 - m_distRight); - - // Frames/seconds - davinci.setPen(lineCol); - if (m_mouseWithinWidget && insideCanvas(m_states.prevMousePos)) { - QString timeText, speedText; - Node_sV time = convertCanvasToTime(m_states.prevMousePos); - - const int mX = m_states.prevMousePos.x(); - const int mY = m_states.prevMousePos.y(); - - davinci.drawLine(mX, m_distTop, mX, height()-1 - m_distBottom); - timeText = CanvasTools::outputTimeLabel(this, time); - speedText = CanvasTools::outputSpeedLabel(time, m_project); - // Ensure that the text does not go over the right border - - davinci.drawText(bottomDrawingRect(mX-20, 160, m_distLeft, -180+width()-m_distRight-50), Qt::AlignRight, timeText); - davinci.drawText(bottomDrawingRect(mX+20, 160, m_distLeft+180, width()-m_distRight-50, false), Qt::AlignLeft, speedText); - davinci.drawLine(m_distLeft, mY, mX, mY); - if (time.y() < 60) { - timeText = QString("f %1\n%2 s") - .arg(time.y()*m_project->frameSource()->fps()->fps(), 2, 'f', 2) - .arg(time.y()); - } else { - timeText = QString("f %1\n%2 min\n+%3 s") - .arg(time.y()*m_project->frameSource()->fps()->fps(), 2, 'f', 2) - .arg(int(time.y()/60)) - .arg(time.y()-60*int(time.y()/60), 0, 'f', 2); - } - davinci.drawText(leftDrawingRect(mY, 48, m_distTop+24, height()-m_distBottom), Qt::AlignRight, timeText); - } - { - Node_sV node; QString timeText ; - - // yMax - node = convertCanvasToTime(QPoint(m_distLeft, m_distTop)); - timeText = QString("f %1").arg(node.y(), 0, 'f', 1); - davinci.drawText(leftDrawingRect(m_distTop), Qt::AlignRight, timeText); - - // yMin - node = convertCanvasToTime(QPoint(m_distLeft, height()-1 - m_distBottom)); - timeText = QString("f %1").arg(node.y(), 0, 'f', 1); - davinci.drawText(leftDrawingRect(height()-m_distBottom-8), Qt::AlignRight, timeText); - - // xMin - node = convertCanvasToTime(QPoint(m_distLeft, height()-1 - m_distBottom)); - timeText = QString("f %1").arg(node.x(), 0, 'f', 1); - davinci.drawText(bottomDrawingRect(m_distLeft+8), Qt::AlignRight, timeText); - - // xMax - node = convertCanvasToTime(QPoint(width()-1 - m_distRight, height()-1 - m_distBottom)); - timeText = QString("f %1").arg(node.x(), 0, 'f', 1); - davinci.drawText(bottomDrawingRect(width()-1-m_distRight), Qt::AlignRight, timeText); - - - } - int bottom = height()-1 - m_distBottom; - davinci.drawLine(m_distLeft, bottom, width()-1 - m_distRight, bottom); - davinci.drawLine(m_distLeft, bottom, m_distLeft, m_distTop); - - // Shutter Lengths (for motion blur) - davinci.setRenderHint(QPainter::Antialiasing, false); - const Node_sV *leftNode = NULL; - const Node_sV *rightNode = NULL; - const float outFps = m_project->preferences()->canvas_xAxisFPS().fps(); - const float sourceFps = m_project->frameSource()->fps()->fps(); - for (int i = 0; i < m_nodes->size(); i++) { - rightNode = &m_nodes->at(i); - QPoint p = convertTimeToCanvas(*rightNode); - - if (leftNode != NULL) { - ShutterFunction_sV *shutterFunction = m_project->shutterFunctions()->function(leftNode->shutterFunctionID()); - if (shutterFunction != NULL) { - - QPoint pp = convertTimeToCanvas(*leftNode); - for (int x = pp.x(); x < p.x(); x++) { - qreal progressOnCurve = ((qreal)x - pp.x()) / (p.x() - pp.x()); - - QPointF time; - if (leftNode->rightCurveType() == CurveType_Bezier && rightNode->leftCurveType() == CurveType_Bezier) { - time = BezierTools_sV::interpolateAtX(convertCanvasToTime(QPoint(x, 0)).x(), - leftNode->toQPointF(), leftNode->toQPointF()+leftNode->rightNodeHandle(), - rightNode->toQPointF()+rightNode->leftNodeHandle(), rightNode->toQPointF()); - } else { - time = leftNode->toQPointF() + (rightNode->toQPointF() - leftNode->toQPointF()) * progressOnCurve; - } - - qreal outTime = time.x(); - qreal sourceTime = time.y(); - qreal sourceFrame = sourceTime * sourceFps; - - float dy; - if (outTime + 1/outFps <= m_nodes->endTime()) { - dy = m_nodes->sourceTime(outTime + 1/outFps) - sourceTime; - } else { - dy = sourceTime - m_nodes->sourceTime(outTime - 1/outFps); - } - float shutter = shutterFunction->evaluate( - progressOnCurve, // x on 0,1 - outTime, // t - outFps, // FPS - sourceFrame, // y - dy // dy to next frame - ); - QPoint sourceShutterTimeStart = QPoint(x, convertTimeToCanvas(time).y()); - QPoint sourceShutterTimeEnd = QPoint(x, convertTimeToCanvas(time + QPointF(0, shutter * outFps/sourceFps)).y()); - if (shutter > 0) { - davinci.setPen(shutterRegionCol); - davinci.drawLine(sourceShutterTimeStart, sourceShutterTimeEnd); - } - davinci.setPen(shutterRegionBoundCol); - davinci.drawPoint(x, sourceShutterTimeEnd.y() - 1); - } - - } - } - - leftNode = &m_nodes->at(i); - } - - // Tags - davinci.setRenderHint(QPainter::Antialiasing, false); - for (int i = 0; i < m_tags->size(); i++) { - Tag_sV tag = m_tags->at(i); - if (tag.axis() == TagAxis_Source) { - QPoint p = convertTimeToCanvas(Node_sV(m_t0.x(), tag.time())); - if (insideCanvas(p)) { - davinci.setPen(srcTagCol); - davinci.drawLine(m_distLeft, p.y(), width()-m_distRight, p.y()); - davinci.drawText(m_distLeft+10, p.y()-1, tag.description()); - } - } else { - QPoint p = convertTimeToCanvas(Node_sV(tag.time(), m_t0.y())); - if (insideCanvas(p)) { - davinci.setPen(outTagCol); - davinci.drawLine(p.x(), height()-1 - m_distBottom, p.x(), m_distTop); - davinci.drawText(p.x()+2, m_distTop, tag.description()); - } - } - } - - // Nodes - davinci.setPen(lineCol); - davinci.setRenderHint(QPainter::Antialiasing, true); - const Node_sV *prev = NULL; - const Node_sV *curr = NULL; - for (int i = 0; i < m_nodes->size(); i++) { - curr = &m_nodes->at(i); - - QPoint p = convertTimeToCanvas(*curr); - - if (curr->selected()) { - davinci.setPen(QPen(QBrush(selectedCol), 2.0)); - davinci.fillRect(p.x()-NODE_RADIUS, p.y()-NODE_RADIUS, 2*NODE_RADIUS+1, 2*NODE_RADIUS+1, selectedCol); - } - davinci.setPen(nodeCol); - if (nearObjects.size() > 0 && curr == nearObjects.at(0).ptr) { - davinci.setPen(hoverCol); - } - davinci.drawRect(p.x()-NODE_RADIUS, p.y()-NODE_RADIUS, 2*NODE_RADIUS+1, 2*NODE_RADIUS+1); - if (prev != NULL) { - if (m_project->nodes()->segments()->at(i-1).selected()) { - davinci.setPen(selectedLineCol); - } else { - davinci.setPen(lineCol); - } - if (prev->rightCurveType() == CurveType_Bezier && curr->leftCurveType() == CurveType_Bezier) { - QPainterPath path; - path.moveTo(convertTimeToCanvas(*prev)); - path.cubicTo( - convertTimeToCanvas(prev->toQPointF() + prev->rightNodeHandle()), - convertTimeToCanvas(curr->toQPointF() + curr->leftNodeHandle()), - convertTimeToCanvas(*curr)); - davinci.drawPath(path); -#ifdef VALIDATE_BEZIER - for (int x = convertTimeToCanvas(*prev).x(); x < p.x(); x++) { - QPointF py = BezierTools_sV::interpolateAtX(convertCanvasToTime(QPoint(x, 0)).x(), - prev->toQPointF(), prev->toQPointF()+prev->rightNodeHandle(), - curr->toQPointF()+curr->leftNodeHandle(), curr->toQPointF()); - qreal y = convertTimeToCanvas(py).y(); -// qDebug() << convertCanvasToTime(QPoint(x, 0)).x() << ": " << x << y; - davinci.drawPoint(x, y); - } -#endif - } else { - davinci.drawLine(convertTimeToCanvas(*prev), p); - } - } - - // Handles - if (i > 0 && curr->leftCurveType() != CurveType_Linear && prev->rightCurveType() != CurveType_Linear) { - davinci.setPen(handleLineCol); - if (nearObjects.size() > 0 && &curr->leftNodeHandle() == nearObjects.at(0).ptr) { - davinci.setPen(hoverCol); - } - QPoint h = convertTimeToCanvas(curr->toQPointF() + curr->leftNodeHandle()); - davinci.drawLine(convertTimeToCanvas(*curr), h); - davinci.drawEllipse(QPoint(h.x(), h.y()), HANDLE_RADIUS, HANDLE_RADIUS); - - davinci.setPen(handleLineCol); - if (nearObjects.size() > 0 && &prev->rightNodeHandle() == nearObjects.at(0).ptr) { - davinci.setPen(hoverCol); - } - h = convertTimeToCanvas(prev->toQPointF() + prev->rightNodeHandle()); - davinci.drawLine(convertTimeToCanvas(*prev), h); - davinci.drawEllipse(QPoint(h.x(), h.y()), HANDLE_RADIUS, HANDLE_RADIUS); - } - - prev = &m_nodes->at(i); - } - - if (m_showHelp) { - MainWindow *mw; - if ((mw = dynamic_cast<MainWindow*>(parentWidget())) != NULL) { - mw->displayHelp(davinci); - } else { - qDebug() << "Cannot show help; wrong parent widget?"; - Q_ASSERT(false); - } - } -} - -void Canvas::drawModes(QPainter &davinci, int t, int r) -{ - qreal opacity = davinci.opacity(); - int w = 16; - int d = 8; - int dR = 0; - - dR += w; - - davinci.setOpacity(.5 + ((m_mode == ToolMode_Select) ? .5 : 0)); - davinci.drawImage(r - dR, t, QImage(":icons/iconSel.png").scaled(16, 16)); - dR += d+w; - - davinci.setOpacity(.5 + ((m_mode == ToolMode_Move) ? .5 : 0)); - davinci.drawImage(r - dR, t, QImage(":icons/iconMov.png").scaled(16, 16)); - - davinci.setOpacity(opacity); -} - -void Canvas::mousePressEvent(QMouseEvent *e) -{ - m_states.reset(); - - m_states.prevMousePos = e->pos(); - m_states.initialMousePos = e->pos(); - - m_states.prevModifiers = e->modifiers(); - m_states.initialModifiers = e->modifiers(); - m_states.initialButtons = e->buttons(); - - m_states.initialContextObject = objectAt(e->pos(), e->modifiers()); - m_states.initial_t0 = m_t0; - - if (m_states.initialContextObject != NULL) { - qDebug() << "Mouse pressed. Context: " << typeid(*m_states.initialContextObject).name(); - } -} - -void Canvas::mouseMoveEvent(QMouseEvent *e) -{ - m_mouseWithinWidget = true; - - m_states.travel((m_states.prevMousePos - e->pos()).manhattanLength()); - m_states.prevMousePos = e->pos(); - m_states.prevModifiers = e->modifiers(); - - if (e->buttons().testFlag(Qt::LeftButton)) { - - Node_sV diff = convertCanvasToTime(e->pos()) - convertCanvasToTime(m_states.initialMousePos); -#ifdef DEBUG_C - qDebug() << m_states.initialMousePos << "to" << e->pos() << "; Diff: " << diff; -#endif - - if (m_mode == ToolMode_Select) { - if (dynamic_cast<const NodeHandle_sV*>(m_states.initialContextObject) != NULL) { - const NodeHandle_sV *handle = dynamic_cast<const NodeHandle_sV*>(m_states.initialContextObject); - int index = m_nodes->indexOf(handle->parentNode()); - if (index < 0) { - qDebug () << "FAIL!"; - } -#ifdef DEBUG_C - qDebug() << "Moving handle" << handle << " of node " << handle->parentNode() - << QString(" (%1)").arg(index); - qDebug() << "Parent node x: " << handle->parentNode()->x(); - qDebug() << "Handle x: " << handle->x(); -#endif - - if (index >= 0) { - m_nodes->moveHandle( - handle, - convertCanvasToTime(e->pos())-m_nodes->at(index) - ); - } else { - for (int i = 0; i < m_nodes->size(); i++) { - qDebug() << "Node " << i << " is at " << &m_nodes->at(i); - } - } - } else if (dynamic_cast<const Node_sV*>(m_states.initialContextObject) != NULL) { - const Node_sV *node = (const Node_sV*) m_states.initialContextObject; - - if (!m_states.nodesMoved) { - qDebug() << "Moving node " << node; - } - if (!m_states.moveAborted) { - if (m_states.countsAsMove()) { - if (!node->selected()) { - if (!m_states.selectAttempted) { - m_states.selectAttempted = true; - m_nodes->select(node, !e->modifiers().testFlag(Qt::ControlModifier)); - } - } - if (e->modifiers().testFlag(Qt::ControlModifier)) { - if (qAbs(diff.x()) < qAbs(diff.y())) { - diff.setX(0); - } else { - diff.setY(0); - } - } - m_nodes->moveSelected(diff); - } - } - m_states.nodesMoved = true; - } else { - // Cannot move this object, so move the canvas instead. -// if (m_states.initialContextObject != NULL) { -// qDebug() << "Trying to move " << typeid(*m_states.initialContextObject).name() << ": Not supported yet!"; -// } - - m_t0 = m_states.initial_t0 - diff; - if (m_t0.y() < 0) { m_t0.setY(0); } - if (m_t0.x() < 0) { m_t0.setX(0); } - if (m_t0.y() > m_tmax.y()) { m_t0.setY(m_tmax.y()); } - - } - - } else if (m_mode == ToolMode_Move) { - if (!m_states.moveAborted) { - m_nodes->shift(convertCanvasToTime(m_states.initialMousePos).x(), diff.x()); - } - m_states.nodesMoved = true; - } - } - - // Emit the source time at the mouse position - emit signalMouseInputTimeChanged( - convertCanvasToTime(m_states.prevMousePos).y() - * m_project->frameSource()->fps()->fps() - ); - - - // Emit the source time at the intersection of the out time and the curve - qreal timeOut = convertCanvasToTime(m_states.prevMousePos).x(); - if (m_nodes->size() > 1 && m_nodes->startTime() <= timeOut && timeOut <= m_nodes->endTime()) { - -#ifdef DEBUG_C - std::cout.precision(32); - std::cout << "start: " << m_nodes->startTime() << ", out: " << timeOut << ", end: " << m_nodes->endTime() << std::endl; -#endif - - if (m_nodes->find(timeOut) >= 0) { - emit signalMouseCurveSrcTimeChanged( - m_nodes->sourceTime(timeOut) - * m_project->frameSource()->fps()->fps()); - } - } - - repaint(); -} - -void Canvas::mouseReleaseEvent(QMouseEvent *) -{ - if (m_states.initialButtons.testFlag(Qt::LeftButton)) { - if (!m_states.moveAborted) { - switch (m_mode) { - case ToolMode_Select: - if (m_states.countsAsMove()) { - m_nodes->confirmMove(); - qDebug() << "Move confirmed."; - emit nodesChanged(); - } else { - if (m_states.initialMousePos.x() >= m_distLeft && m_states.initialMousePos.y() < this->height()-m_distBottom - && !m_states.selectAttempted) { - - // Try to select a node below the mouse. If there is none, add a point. - if (m_states.initialContextObject == NULL || dynamic_cast<const Node_sV*>(m_states.initialContextObject) == NULL) { - if (m_mode == ToolMode_Select) { - Node_sV p = convertCanvasToTime(m_states.initialMousePos); - m_nodes->add(p); - emit nodesChanged(); - } else { - qDebug() << "Not adding node. Mode is " << m_mode; - } - - } else if (dynamic_cast<const Node_sV*>(m_states.initialContextObject) != NULL) { - m_nodes->select((const Node_sV*) m_states.initialContextObject, !m_states.initialModifiers.testFlag(Qt::ControlModifier)); - } - repaint(); - - } else { - qDebug() << "Not inside bounds."; - } - } - break; - case ToolMode_Move: - m_nodes->confirmMove(); - qDebug() << "Move confirmed."; - emit nodesChanged(); - break; - } - } -#if QT_VERSION < 0x040700 - } else if (m_states.initialButtons.testFlag(Qt::RightButton) || m_states.initialButtons.testFlag(Qt::MidButton)) { -#else - } else if (m_states.initialButtons.testFlag(Qt::RightButton) || m_states.initialButtons.testFlag(Qt::MiddleButton)) { -#endif - QList<NodeList_sV::PointerWithDistance> nearObjects = m_project->objectsNear(convertCanvasToTime(m_states.initialMousePos).toQPointF(), delta(10)); - qDebug() << "Nearby objects:"; - for (int i = 0; i < nearObjects.size(); i++) { - qDebug() << typeid(*(nearObjects.at(i).ptr)).name() << " at distance " << nearObjects.at(i).dist; - } - } -} - -void Canvas::contextMenuEvent(QContextMenuEvent *e) -{ - qDebug() << "Context menu requested"; - m_states.contextmenuMouseTime = convertCanvasToTime(e->pos()).toQPointF(); - - QMenu menu; - QMenu speedMenu(trUtf8("Segment replay &speed …"), &menu); - - const CanvasObject_sV *obj = objectAt(e->pos(), m_states.prevModifiers); - - if (dynamic_cast<const Node_sV*>(obj)) { - Node_sV *node = (Node_sV *) obj; - m_toDeleteNode.objectPointer = node; - m_toSnapInNode.objectPointer = node; - - int nodeIndex = m_nodes->indexOf(node); - - menu.addAction(QString(tr("Node %1")).arg(nodeIndex))->setEnabled(false); - menu.addAction(m_aDeleteNode); -// menu.addAction(m_aSnapInNode); // \todo Activate Snap in - menu.addSeparator()->setText(tr("Handle actions")); - menu.addAction(m_aResetLeftHandle); - menu.addAction(m_aResetRightHandle); - - } else if (dynamic_cast<const Segment_sV*>(obj) != NULL) { - const Segment_sV* segment = (const Segment_sV*) obj; - int leftNode = segment->leftNodeIndex(); - - menu.addAction(QString(tr("Segment between node %1 and %2")).arg(leftNode).arg(leftNode+1))->setEnabled(false); - menu.addAction(m_aLinear); - menu.addAction(m_aBezier); - menu.addAction(m_aShutterFunction); - - speedMenu.addAction(m_aCustomSpeed); - std::vector<QAction*>::iterator it = m_aSpeeds.begin(); - while (it != m_aSpeeds.end()) { - speedMenu.addAction(*it); - it++; - } - menu.addMenu(&speedMenu); - - } else if (dynamic_cast<const Tag_sV*>(obj) != NULL) { - Tag_sV* tag = (Tag_sV*) obj; - m_toDeleteTag.objectPointer = tag; - m_toRenameTag.objectPointer = tag; - m_toSetTagTime.objectPointer = tag; - - menu.addAction(QString(tr("Tag %1")).arg(tag->description())); - menu.addAction(m_aDeleteTag); - menu.addAction(m_aRenameTag); - menu.addAction(m_aSetTagTime); - - } else { - if (obj != NULL) { - qDebug() << "No context menu available for object of type " << typeid(*obj).name(); - } - return; - } - menu.exec(e->globalPos()); -} - -void Canvas::leaveEvent(QEvent *) -{ - m_mouseWithinWidget = false; - repaint(); -} - -void Canvas::wheelEvent(QWheelEvent *e) -{ - // Mouse wheel movement in degrees - int deg = e->delta()/8; - - if (e->modifiers().testFlag(Qt::ControlModifier)) { - zoom(deg > 0, e->pos()); - } else if (e->modifiers().testFlag(Qt::ShiftModifier)) { - // Horizontal scrolling - m_t0 -= Node_sV(SCROLL_FACTOR*convertDistanceToTime(QPoint(deg, 0)).x(),0); - if (m_t0.x() < 0) { m_t0.setX(0); } - } else { - //Vertical scrolling - m_t0 += Node_sV(0, SCROLL_FACTOR*convertDistanceToTime(QPoint(deg, 0)).x()); - if (m_t0.y() < 0) { m_t0.setY(0); } - if (m_t0.y() > m_tmax.y()) { m_t0.setY(m_tmax.y()); } - } - - - m_project->preferences()->viewport_t0() = m_t0.toQPointF(); - m_project->preferences()->viewport_secRes().rx() = m_secResX; - m_project->preferences()->viewport_secRes().ry() = m_secResY; - - Q_ASSERT(m_secResX > 0); - Q_ASSERT(m_secResY > 0); - Q_ASSERT(m_t0.x() >= 0); - Q_ASSERT(m_t0.y() >= 0); - - repaint(); -} -void Canvas::zoom(bool in, QPoint pos) -{ - Node_sV n0 = convertCanvasToTime(pos); - - // Update the line resolution - if (in) { - m_secResX *= ZOOM_FACTOR; - } else { - m_secResX /= ZOOM_FACTOR; - } - if (m_secResX < .05) { m_secResX = .05; } - // Y resolution is the same as X resolution (at least at the moment) - m_secResY = m_secResX; -// qDebug() << "Resolution: " << m_secResX; - - // Adjust t0 such that the mouse points to the same time as before - Node_sV nDiff = convertCanvasToTime(pos) - convertCanvasToTime(QPoint(m_distLeft, height()-1-m_distBottom)); - m_t0 = n0 - nDiff; - if (m_t0.x() < 0) { m_t0.setX(0); } - if (m_t0.y() < 0) { m_t0.setY(0); } - - Q_ASSERT(m_secResX > 0); - Q_ASSERT(m_secResY > 0); - Q_ASSERT(m_t0.x() >= 0); - Q_ASSERT(m_t0.y() >= 0); - repaint(); -} -void Canvas::slotZoomIn() -{ - zoom(true, QCursor::pos()); -} -void Canvas::slotZoomOut() -{ - zoom(false, QCursor::pos()); -} - - - -const CanvasObject_sV* Canvas::objectAt(QPoint pos, Qt::KeyboardModifiers modifiers) const -{ - QList<NodeList_sV::PointerWithDistance> nearObjects = - m_project->objectsNear(convertCanvasToTime(pos).toQPointF(), convertDistanceToTime(QPoint(SELECT_RADIUS,0)).x()); - - if (modifiers.testFlag(Qt::ShiftModifier)) { - // Ignore nodes with Shift pressed - while (nearObjects.size() > 0 && dynamic_cast<const Node_sV*>(nearObjects.at(0).ptr) != NULL) { - nearObjects.removeFirst(); - } - } - - if (nearObjects.size() > 0) { - return nearObjects.at(0).ptr; - } else { - return NULL; - } -} - - - -////////// Conversion Time <--> Screen pixels - -Node_sV Canvas::convertCanvasToTime(const QPoint &p) const -{ - Q_ASSERT(m_secResX > 0); - Q_ASSERT(m_secResY > 0); - - QPointF tDelta = convertDistanceToTime(QPoint( - p.x()-m_distLeft, - height()-1 - m_distBottom - p.y() - )); - QPointF tFinal = tDelta + m_t0.toQPointF(); - return Node_sV(tFinal.x(), tFinal.y()); -} -QPoint Canvas::convertTimeToCanvas(const Node_sV &p) const -{ - return convertTimeToCanvas(p.toQPointF()); -} -QPoint Canvas::convertTimeToCanvas(const QPointF &p) const -{ - QPoint tDelta = convertTimeToDistance(QPointF( - p.x()-m_t0.x(), - p.y()-m_t0.y() - )); - QPoint out( - tDelta.x() + m_distLeft, - height()-1 - m_distBottom - tDelta.y() - ); - return out; -} -QPointF Canvas::convertDistanceToTime(const QPoint &p) const -{ - QPointF out( - float(p.x()) / m_secResX, - float(p.y()) / m_secResY - ); - return out; -} -QPoint Canvas::convertTimeToDistance(const QPointF &time) const -{ - QPoint out( - time.x()*m_secResX, - time.y()*m_secResY - ); - return out; -} -float Canvas::delta(int px) const -{ - return convertDistanceToTime(QPoint(px, 0)).x(); -} - - - -////////// Slots - -void Canvas::slotAbort(Canvas::Abort abort) -{ - qDebug() << "Signal: " << abort; - switch (abort) { - case Abort_General: - m_states.moveAborted = true; - m_nodes->abortMove(); - repaint(); - break; - case Abort_Selection: - m_nodes->unselectAll(); - repaint(); - break; - } - -} - -void Canvas::slotAddTag() -{ - if (m_mouseWithinWidget) { - TagAddDialog dialog(m_project->preferences()->lastSelectedTagAxis(), this); - - if (dialog.exec() == QDialog::Accepted) { - Tag_sV tag = dialog.buildTag(convertCanvasToTime(m_states.prevMousePos).toQPointF()); - m_project->preferences()->lastSelectedTagAxis() = tag.axis(); - - m_tags->push_back(tag); - qDebug() << "Tag added. Number is now: " << m_tags->size(); - repaint(); - - } else { - qDebug() << "Tag dialog not accepted."; - } - } else { - qDebug() << "Mouse outside widget."; - } -} - -void Canvas::slotDeleteNodes() -{ - qDebug() << "Will delete"; - uint nDel = m_nodes->deleteSelected(); - qDebug() << nDel << " deleted."; - if (nDel > 0) { - repaint(); - emit nodesChanged(); - } -} - -void Canvas::slotSetToolMode(ToolMode mode) -{ - m_mode = mode; - qDebug() << "Mode set to: " << mode; - repaint(); -} - - - - -void Canvas::slotRunAction(QObject *o) -{ - TransferObject *to = (TransferObject*) o; - - qDebug() << "Desired action: " << toString(to->reason); - - if (dynamic_cast<Tag_sV*>(to->objectPointer) != NULL) { - - /// Tag actions /// - - Tag_sV* tag = (Tag_sV*) to->objectPointer; - qDebug() << " ... on Tag " << tag->description(); - switch (to->reason) { - case TransferObject::ACTION_DELETE: - for (int i = 0; i < m_tags->size(); ++i) { - if (&m_tags->at(i) == tag) { - qDebug() << "Tag found, removing: " << m_tags->at(i).description(); - m_tags->removeAt(i); - break; - } - } - break; - case TransferObject::ACTION_RENAME: - { - bool ok; - QString newName = QInputDialog::getText(this, tr("New tag name"), tr("Tag:"), QLineEdit::Normal, tag->description(), &ok); - if (ok) { - tag->setDescription(newName); - } - break; - } - case TransferObject::ACTION_SETTIME: - { - bool ok; - double d = QInputDialog::getDouble(this, tr("New tag time"), tr("Time:"), tag->time(), 0, 424242, 5, &ok); - if (ok) { - tag->setTime(d); - } - break; - } - default: - qDebug() << "Unknown action on Tag: " << toString(to->reason); - Q_ASSERT(false); - break; - } - } else if (dynamic_cast<Node_sV*>(to->objectPointer)) { - - /// Node actions /// - - Node_sV const* node = (Node_sV const*) to->objectPointer; - qDebug() << " ... on node " << *node; - switch (to->reason) { - case TransferObject::ACTION_DELETE: - m_nodes->deleteNode(m_nodes->indexOf(node)); - break; - default: - qDebug() << "Unknown action on Node: " << toString(to->reason); - Q_ASSERT(false); - break; - } - } - - repaint(); -} - -void Canvas::slotChangeCurveType(int curveType) -{ - qDebug() << "Changing curve type to " << toString((CurveType)curveType) << " at " << convertCanvasToTime(m_states.prevMousePos).x(); - m_nodes->setCurveType(convertCanvasToTime(m_states.prevMousePos).x(), (CurveType) curveType); - emit nodesChanged(); -} -void Canvas::slotResetHandle(const QString &position) -{ - if (dynamic_cast<const Node_sV*>(m_states.initialContextObject) != NULL) { - Node_sV *node = const_cast<Node_sV*>(dynamic_cast<const Node_sV*>(m_states.initialContextObject)); - if (position == "left") { - node->setLeftNodeHandle(0, 0); - } else { - node->setRightNodeHandle(0, 0); - } - emit nodesChanged(); - } else { - qDebug() << "Object at mouse position is " << m_states.initialContextObject << ", cannot reset the handle."; - } -} -void Canvas::setCurveSpeed(double speed) -{ - qDebug() << "Setting curve to " << speed << "x speed."; - m_nodes->setSpeed(convertCanvasToTime(m_states.prevMousePos).x(), speed); - emit nodesChanged(); - repaint(); -} - - -void Canvas::slotSetSpeed() -{ - bool ok = true; - - double d = m_settings.value("canvas/replaySpeed", 1.0).toDouble(); - qDebug() << "Getting: " << d; - d = QInputDialog::getDouble(this, tr("Replay speed for current segment"), tr("Speed:"), d, -1000, 1000, 3, &ok); - if (ok) { - setCurveSpeed(d); - m_settings.setValue("canvas/replaySpeed", d); - qDebug() << "Setting: " << d; - } -} -void Canvas::slotSetSpeed(QString s) -{ - bool ok = true; - double d = s.toDouble(&ok); - if (ok) { - setCurveSpeed(d); - } else { - qDebug() << "Not ok: " << s; - } -} -void Canvas::slotSetShutterFunction() -{ - int left = m_nodes->find(m_states.contextmenuMouseTime.x()); - if (left == m_nodes->size()-1) { - left = m_nodes->size()-2; - } - - if (m_shutterFunctionDialog == NULL) { - m_shutterFunctionDialog = new ShutterFunctionDialog(m_project, this); - bool b = true; - b &= connect(this, SIGNAL(nodesChanged()), m_shutterFunctionDialog, SLOT(slotNodesUpdated())); - Q_ASSERT(b); - } - - m_shutterFunctionDialog->setSegment(left); - if (!m_shutterFunctionDialog->isVisible()) { - m_shutterFunctionDialog->show(); - } - -} - -QDebug operator <<(QDebug qd, const Canvas::ToolMode &mode) -{ - switch(mode) { - case Canvas::ToolMode_Select: - qd << "Select tool"; - break; - case Canvas::ToolMode_Move: - qd << "Move tool"; - break; - } - return qd.maybeSpace(); -} - -QDebug operator <<(QDebug qd, const Canvas::Abort &abort) -{ - switch(abort) { - case Canvas::Abort_General: - qd << "Abort General"; - break; - case Canvas::Abort_Selection: - qd << "Abort Selection"; - break; - } - return qd.maybeSpace(); -} - -QString toString(TransferObject::Reason reason) -{ - switch (reason) { - case TransferObject::ACTION_DELETE : - return "Delete"; - case TransferObject::ACTION_SNAPIN : - return "Snap in"; - case TransferObject::ACTION_RENAME : - return "Rename"; - case TransferObject::ACTION_SETTIME : - return "Set time"; - default : - Q_ASSERT(false); - return "Unknown action"; - } -}
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/slowmoUI/canvas.h
Deleted
@@ -1,254 +0,0 @@ -/* -slowmoUI is a user interface for slowmoVideo. -Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. -*/ - -#ifndef CANVAS_H -#define CANVAS_H - -#include "../project/node_sV.h" -#include "../project/nodeList_sV.h" -#include "../project/project_sV.h" -#include "../project/tag_sV.h" - -#include <QWidget> -#include <QList> -#include <QSettings> - - - -#define NODE_RADIUS 6 -#define SELECT_RADIUS 12 -#define HANDLE_RADIUS 4 -#define MOVE_THRESHOLD 3 -#define SCROLL_FACTOR 3 -#define ZOOM_FACTOR 1.414 - - - -class QColor; -class QPoint; -class CanvasTools; -class ShutterFunctionDialog; - -namespace Ui { - class Canvas; -} - - - -/** - This class is for building helper objects for the signals&slots mechanism - for passing pointers to objects which are not QObjects. - */ -class TransferObject : public QObject { - Q_OBJECT - -public: - CanvasObject_sV* objectPointer; - enum Reason { - ACTION_DELETE, - ACTION_RENAME, - ACTION_SETTIME, - ACTION_SNAPIN - } reason; - - - TransferObject() : objectPointer(NULL), reason(ACTION_SNAPIN) {} - TransferObject(CanvasObject_sV* objectPointer, Reason reason) : - objectPointer(objectPointer), reason(reason) {} -}; - - -class Project_sV; - -/** - \brief Canvas for drawing motion curves. - - \todo Frame lines on high zoom - \todo Custom speed factor to next node - */ -class Canvas : public QWidget -{ - Q_OBJECT - - friend class CanvasTools; - -public: - explicit Canvas(Project_sV *project, QWidget *parent = 0); - ~Canvas(); - - enum ToolMode { ToolMode_Select, ToolMode_Move }; - enum Abort { Abort_General, Abort_Selection }; - - static QColor lineCol; - static QColor selectedLineCol; - static QColor nodeCol; - static QColor gridCol; - static QColor fatGridCol; - static QColor minGridCol; - static QColor selectedCol; - static QColor hoverCol; - static QColor srcTagCol; - static QColor outTagCol; - static QColor handleLineCol; - static QColor backgroundCol; - static QColor shutterRegionCol; - static QColor shutterRegionBoundCol; - - void load(Project_sV *project); - - void showHelp(bool show); - void toggleHelp(); - - const QPointF prevMouseTime() const; - const float prevMouseInFrame() const; - -public slots: - void slotAbort(Canvas::Abort abort); - void slotAddTag(); - void slotDeleteNodes(); - void slotSetToolMode(Canvas::ToolMode mode); - -signals: - void signalMouseInputTimeChanged(qreal frame); - void signalMouseCurveSrcTimeChanged(qreal frame); - void nodesChanged(); - -protected: - void paintEvent(QPaintEvent *); - void mouseMoveEvent(QMouseEvent *); - void mousePressEvent(QMouseEvent *); - void mouseReleaseEvent(QMouseEvent *); - void wheelEvent(QWheelEvent *); - void leaveEvent(QEvent *); - void contextMenuEvent(QContextMenuEvent *); - -private: - Ui::Canvas *ui; - QSettings m_settings; - Project_sV *m_project; - ShutterFunctionDialog *m_shutterFunctionDialog; - bool m_mouseWithinWidget; - int m_distLeft; - int m_distBottom; - int m_distRight; - int m_distTop; - Node_sV m_t0; ///< Viewport, bottom left - Node_sV m_tmax; ///< Upper bounds for the viewport (so the user does not get lost by zooming too far up) - float m_secResX; ///< How many pixels wide is one output second? - float m_secResY; ///< How many pixels wide is one input second? - - bool m_showHelp; - - NodeList_sV *m_nodes; - QList<Tag_sV> *m_tags; - - ToolMode m_mode; - /** - Saves states about mouse events. - The prev... variables are updated when the mouse moves, - the initial... variables only on mouse clicks. - */ - struct { - bool nodesMoved; - bool selectAttempted; - bool moveAborted; - - QPoint prevMousePos; - QPoint initialMousePos; - QPointF contextmenuMouseTime; - Node_sV initial_t0; - - Qt::KeyboardModifiers prevModifiers; - Qt::KeyboardModifiers initialModifiers; - - Qt::MouseButtons initialButtons; - - const CanvasObject_sV *initialContextObject; - - void reset() { - moveAborted = false; - nodesMoved = false; - selectAttempted = false; - initialContextObject = NULL; - travelledDistance = 0; - } - void travel(int length) { travelledDistance += length; } - bool countsAsMove() { return travelledDistance >= MOVE_THRESHOLD; } - - private: - int travelledDistance; - } m_states; - - /* - The transfer objects to each action defines the action to take - when the slot is called, and additionally stores a pointer to the - object it was called on (the object is known in the context menu event). - */ - QAction *m_aDeleteNode; TransferObject m_toDeleteNode; - QAction *m_aSnapInNode; TransferObject m_toSnapInNode; - QAction *m_aDeleteTag; TransferObject m_toDeleteTag; - QAction *m_aRenameTag; TransferObject m_toRenameTag; - QAction *m_aSetTagTime; TransferObject m_toSetTagTime; - QSignalMapper *m_hackMapper; - - QSignalMapper *m_curveTypeMapper; - QSignalMapper *m_handleMapper; - QSignalMapper *m_speedsMapper; - QAction *m_aLinear; - QAction *m_aBezier; - QAction *m_aResetLeftHandle; - QAction *m_aResetRightHandle; - QAction *m_aCustomSpeed; - QAction *m_aShutterFunction; - std::vector<QAction *> m_aSpeeds; - - Node_sV convertCanvasToTime(const QPoint &p) const; - QPoint convertTimeToCanvas(const Node_sV &p) const; - QPoint convertTimeToCanvas(const QPointF &p) const; - QPointF convertDistanceToTime(const QPoint &p) const; - QPoint convertTimeToDistance(const QPointF &time) const; - - /** \return The distance in px converted to time */ - float delta(int px) const; - - bool insideCanvas(const QPoint& pos); - - bool selectAt(const QPoint& pos, bool addToSelection = false); - - void drawModes(QPainter &davinci, int top, int right); - - const CanvasObject_sV* objectAt(QPoint pos, Qt::KeyboardModifiers modifiers) const; - - void setCurveSpeed(double speed); - -private slots: - void slotRunAction(QObject *o); - void slotChangeCurveType(int curveType); - void slotResetHandle(const QString &position); - void slotSetSpeed(); - void slotSetSpeed(QString s); - void slotSetShutterFunction(); - void slotZoomIn(); - void slotZoomOut(); - -private: - void zoom(bool in, QPoint pos); - - QRect leftDrawingRect(int y, const int height = 12, const int min = -1, const int max = -1) const; - QRect bottomDrawingRect(int x, const int width = 160, const int min = -1, const int max = -1, bool rightJustified = true) const; - -}; - -QDebug operator<<(QDebug qd, const Canvas::ToolMode &mode); -QDebug operator<<(QDebug qd, const Canvas::Abort &abort); - -QString toString(TransferObject::Reason reason); - -#endif // CANVAS_H
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/slowmoUI/dialogues
Deleted
-(directory)
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/slowmoUI/dialogues/aboutDialog.ui
Deleted
@@ -1,173 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>AboutDialog</class> - <widget class="QDialog" name="AboutDialog"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>903</width> - <height>354</height> - </rect> - </property> - <property name="windowTitle"> - <string>About</string> - </property> - <layout class="QGridLayout" name="gridLayout"> - <item row="1" column="1"> - <widget class="QLabel" name="label"> - <property name="font"> - <font> - <family>Gentium Basic</family> - <pointsize>19</pointsize> - <weight>75</weight> - <bold>true</bold> - </font> - </property> - <property name="text"> - <string>About slowmoVideo</string> - </property> - </widget> - </item> - <item row="3" column="0" colspan="2"> - <widget class="QLabel" name="label_2"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Bitstream Vera Sans'; font-size:10pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-style:italic;">slowmoVideo</span> is developed by Simon A. Eugster (aka. Granjow, co-author of Kdenlive) and licensed under GPLv3.</p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-style:italic;">slowmoVideo</span> allows to change the speed of a video clip based upon a curve. If the speed becomes higher than 1×, an exposure (shutter) effect simulates motion blur. For lower speed, frames are interpolated with optical flow.</p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Thanks for contributing:</p> -<ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Mirko Götze <span style=" font-style:italic;">&lt;mail@mgo80.de&gt;</span> for converting <span style=" font-weight:600;">Cg to GLSL</span> (Removing the nVidia dependency)</li> -<li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Morten Sylvest Olsen <span style=" font-style:italic;">&lt;mso@kapowsoftware.com&gt;</span> for the <span style=" font-weight:600;">V3D speedup</span> and removing the unnecessary window</li> -<li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Elias Vanderstuyft for displaying the <span style=" font-weight:600;">shutter function</span> on the canvas</li> -<li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Christian Frisson <span style=" font-style:italic;">&lt;christian.frisson@umons.ac.be&gt;</span> for<span style=" font-weight:600;"> OpenCV on MXE</span> (allowed me to compile slowmoVideo for Windows)</li> -<li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Per <span style=" font-style:italic;">&lt;per@stuffmatic.com&gt;</span> for the<span style=" font-weight:600;"> OpenCV</span> code (slowmoVideo can run on CPU only with it)</li></ul> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Visit <a href="http://slowmoVideo.granjow.net"><span style=" text-decoration: underline; color:#0057ae;">slowmoVideo.granjow.net</span></a> for more information.</p></body></html></string> - </property> - <property name="textFormat"> - <enum>Qt::RichText</enum> - </property> - <property name="wordWrap"> - <bool>true</bool> - </property> - </widget> - </item> - <item row="1" column="0"> - <spacer name="horizontalSpacer"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - <item row="2" column="0"> - <spacer name="verticalSpacer_2"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - <item row="0" column="0"> - <spacer name="verticalSpacer_3"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>10</height> - </size> - </property> - </spacer> - </item> - <item row="7" column="0" colspan="2"> - <layout class="QHBoxLayout" name="horizontalLayout"> - <item> - <widget class="QLabel" name="lblVersion"> - <property name="font"> - <font> - <pointsize>8</pointsize> - </font> - </property> - <property name="text"> - <string notr="true">version number goes here.</string> - </property> - </widget> - </item> - <item> - <widget class="QLabel" name="label_3"> - <property name="font"> - <font> - <pointsize>8</pointsize> - </font> - </property> - <property name="text"> - <string>(c) 2012 Simon A. Eugster</string> - </property> - <property name="alignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> - </property> - </widget> - </item> - </layout> - </item> - <item row="5" column="0"> - <layout class="QHBoxLayout" name="horizontalLayout_2"> - <item> - <widget class="QFrame" name="iconFrame"> - <property name="frameShape"> - <enum>QFrame::NoFrame</enum> - </property> - <property name="frameShadow"> - <enum>QFrame::Raised</enum> - </property> - </widget> - </item> - <item> - <spacer name="verticalSpacer"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>40</height> - </size> - </property> - </spacer> - </item> - </layout> - </item> - </layout> - </widget> - <resources/> - <connections/> -</ui>
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/slowmoUI/dialogues/flowExaminer.cpp
Deleted
@@ -1,100 +0,0 @@ -#include "flowExaminer.h" -#include "ui_flowExaminer.h" -#include "project/project_sV.h" -#include "project/abstractFrameSource_sV.h" -#include "lib/flowVisualization_sV.h" - -#include <QtCore/QDebug> -#include <QtGui/QPainter> - -FlowExaminer::FlowExaminer(Project_sV *project, QWidget *parent) : - QDialog(parent), - ui(new Ui::FlowExaminer), - m_project(project), - m_flowLR(NULL), - m_flowRL(NULL) -{ - ui->setupUi(this); -// ui->leftFrame->trackMouse(true); -// ui->rightFrame->trackMouse(true); - - bool b = true; - b &= connect(ui->leftFrame, SIGNAL(signalMouseMoved(float,float)), this, SLOT(slotMouseMoved(float,float))); - b &= connect(ui->rightFrame, SIGNAL(signalMouseMoved(float,float)), this, SLOT(slotMouseMoved(float,float))); - b &= connect(ui->bClose, SIGNAL(clicked()), this, SLOT(close())); - Q_ASSERT(b); -} - -FlowExaminer::~FlowExaminer() -{ - delete ui; - if (m_flowLR != NULL) { - delete m_flowLR; - } - if (m_flowRL != NULL) { - delete m_flowRL; - } -} - -/// \todo Make flow visualization configurable -void FlowExaminer::examine(int leftFrame) -{ - if (m_flowLR != NULL) { - delete m_flowLR; - m_flowLR = NULL; - } - if (m_flowRL != NULL) { - delete m_flowRL; - m_flowRL = NULL; - } - try { - m_flowLR = m_project->requestFlow(leftFrame, leftFrame+1, FrameSize_Orig); - m_flowRL = m_project->requestFlow(leftFrame+1, leftFrame, FrameSize_Orig); - ui->leftFrame->loadImage(m_project->frameSource()->frameAt(leftFrame, FrameSize_Orig)); - ui->rightFrame->loadImage(m_project->frameSource()->frameAt(leftFrame+1, FrameSize_Orig)); - ui->leftFlow->loadImage(FlowVisualization_sV::colourizeFlow(m_flowLR, FlowVisualization_sV::HSV)); - ui->rightFlow->loadImage(FlowVisualization_sV::colourizeFlow(m_flowRL, FlowVisualization_sV::HSV)); - } catch (FlowBuildingError &err) { } - - repaint(); -} - -/// \todo Show vectors etc. -void FlowExaminer::slotMouseMoved(float x, float y) -{ - if (QObject::sender() == ui->leftFrame) { - qDebug() << "Should display something in the right frame now."; - if (m_flowLR != NULL) { - float moveX = m_flowLR->x(x,y); - float moveY = m_flowLR->y(x,y); - QImage leftOverlay(m_flowLR->width(), m_flowLR->height(), QImage::Format_ARGB32); - QImage rightOverlay(leftOverlay.size(), QImage::Format_ARGB32); - QPainter davinci; - - davinci.begin(&leftOverlay); - davinci.drawLine(x, y, x+moveX, y+moveY); - davinci.end(); - - qDebug() << "Line coordinates: " << x << y << moveX << moveY; - bool ok; - ok = ui->leftFrame->loadOverlay(leftOverlay); - Q_ASSERT(ok); - - davinci.begin(&rightOverlay); - davinci.drawEllipse(x+moveX, y+moveY, 2, 2); - davinci.end(); - - ui->rightFrame->loadOverlay(rightOverlay); - - repaint(); - } else { - qDebug() << "Flow is 0!"; - } - } else if (QObject::sender() == ui->rightFrame) { - qDebug() << "Should display something in the left frame now."; - - } else { - qDebug() << "Unknown sender!"; - Q_ASSERT(false); - } -}
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/slowmoUI/dialogues/flowExaminer.h
Deleted
@@ -1,33 +0,0 @@ -#ifndef FLOWEXAMINER_H -#define FLOWEXAMINER_H - -#include <QDialog> - -namespace Ui { - class FlowExaminer; -} -class Project_sV; -class FlowField_sV; - -class FlowExaminer : public QDialog -{ - Q_OBJECT - -public: - explicit FlowExaminer(Project_sV *project, QWidget *parent = 0); - ~FlowExaminer(); - - void examine(int leftFrame); - -private: - Ui::FlowExaminer *ui; - - Project_sV *m_project; - FlowField_sV *m_flowLR; - FlowField_sV *m_flowRL; - -private slots: - void slotMouseMoved(float x, float y); -}; - -#endif // FLOWEXAMINER_H
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/slowmoUI/dialogues/flowExaminer.ui
Deleted
@@ -1,113 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>FlowExaminer</class> - <widget class="QDialog" name="FlowExaminer"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>918</width> - <height>603</height> - </rect> - </property> - <property name="windowTitle"> - <string notr="true">Dialog</string> - </property> - <layout class="QVBoxLayout" name="verticalLayout"> - <item> - <layout class="QHBoxLayout" name="horizontalLayout"> - <item> - <widget class="ImageDisplay" name="leftFrame"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Expanding"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="frameShape"> - <enum>QFrame::StyledPanel</enum> - </property> - <property name="frameShadow"> - <enum>QFrame::Raised</enum> - </property> - </widget> - </item> - <item> - <widget class="ImageDisplay" name="rightFrame"> - <property name="frameShape"> - <enum>QFrame::StyledPanel</enum> - </property> - <property name="frameShadow"> - <enum>QFrame::Raised</enum> - </property> - </widget> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_2"> - <item> - <widget class="ImageDisplay" name="leftFlow"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Expanding"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="frameShape"> - <enum>QFrame::StyledPanel</enum> - </property> - <property name="frameShadow"> - <enum>QFrame::Raised</enum> - </property> - </widget> - </item> - <item> - <widget class="ImageDisplay" name="rightFlow"> - <property name="frameShape"> - <enum>QFrame::StyledPanel</enum> - </property> - <property name="frameShadow"> - <enum>QFrame::Raised</enum> - </property> - </widget> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_3"> - <item> - <spacer name="horizontalSpacer"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>0</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QPushButton" name="bClose"> - <property name="text"> - <string>Close</string> - </property> - </widget> - </item> - </layout> - </item> - </layout> - </widget> - <customwidgets> - <customwidget> - <class>ImageDisplay</class> - <extends>QFrame</extends> - <header>libgui/imageDisplay.h</header> - <container>1</container> - </customwidget> - </customwidgets> - <resources/> - <connections/> -</ui>
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/slowmoUI/dialogues/newProjectDialog.cpp
Deleted
@@ -1,238 +0,0 @@ -/* -slowmoUI is a user interface for slowmoVideo. -Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. -*/ - -#include "newProjectDialog.h" -#include "ui_newProjectDialog.h" - -#include "project/videoFrameSource_sV.h" -#include "project/imagesFrameSource_sV.h" - - -#include <QDebug> - -#include <QtCore/QFile> -#include <QtCore/QDir> - -#include <QFileDialog> -#include <QButtonGroup> - -NewProjectDialog::NewProjectDialog(QWidget *parent) : - QDialog(parent), - ui(new Ui::NewProjectDialog) -{ - ui->setupUi(this); - - m_buttonGroup = new QButtonGroup(this); - m_buttonGroup->addButton(ui->radioVideo); - m_buttonGroup->addButton(ui->radioImages); - ui->radioVideo->setChecked(true); - - ui->projectDir->setText(m_settings.value("directories/lastProjectDir", QDir::current().absolutePath()).toString()); - m_videoInfo.streamsCount = 0; - - bool b = true; - b &= connect(ui->browseInputVideo, SIGNAL(clicked()), this, SLOT(slotSelectVideoFile())); - b &= connect(ui->browseInputImages, SIGNAL(clicked()), this, SLOT(slotSelectImages())); - b &= connect(ui->browseProjectDir, SIGNAL(clicked()), this, SLOT(slotSelectProjectDir())); - b &= connect(ui->inputVideo, SIGNAL(textChanged(QString)), this, SLOT(slotUpdateVideoInfo())); - b &= connect(ui->projectDir, SIGNAL(textChanged(QString)), this, SLOT(slotUpdateButtonStates())); - b &= connect(ui->projectFilename, SIGNAL(textChanged(QString)), this, SLOT(slotUpdateButtonStates())); - - b &= connect(ui->bAbort, SIGNAL(clicked()), this, SLOT(reject())); - b &= connect(ui->bOk, SIGNAL(clicked()), this, SLOT(accept())); - - b &= connect(m_buttonGroup, SIGNAL(buttonClicked(int)), this, SLOT(slotUpdateFrameSourceType())); - Q_ASSERT(b); - - slotUpdateImagesInfo(); - slotUpdateVideoInfo(); - slotUpdateButtonStates(); - slotUpdateFrameSourceType(); -} - -NewProjectDialog::~NewProjectDialog() -{ - delete ui; - delete m_buttonGroup; -} - -Project_sV* NewProjectDialog::buildProject() throw(FrameSourceError) -{ - Project_sV *project = new Project_sV(ui->projectDir->text()); - AbstractFrameSource_sV *frameSource = NULL; - if (ui->radioVideo->isChecked()) { - frameSource = new VideoFrameSource_sV(project, ui->inputVideo->text()); - m_settings.setValue("directories/lastInputVideo", QFileInfo(ui->inputVideo->text()).absolutePath()); - } else { - frameSource = new ImagesFrameSource_sV(project, m_images); - m_settings.setValue("directories/lastInputImage", QFileInfo(m_images.last()).absolutePath()); - } - project->loadFrameSource(frameSource); - - m_settings.setValue("directories/lastProjectDir", ui->projectDir->text()); - m_settings.setValue("directories/lastProjectDir", ui->projectDir->text()); - - return project; -} -const QString NewProjectDialog::projectFilename() const -{ - return QString(ui->projectDir->text() + "/" + ui->projectFilename->text() + ".sVproj"); -} - -void NewProjectDialog::slotSelectVideoFile() -{ - QFileDialog dialog(this, tr("Select input video file")); - dialog.setAcceptMode(QFileDialog::AcceptOpen); - dialog.setFileMode(QFileDialog::ExistingFile); - if (ui->inputVideo->text().length() > 0) { - dialog.setDirectory(ui->inputVideo->text()); - } else { - dialog.setDirectory(m_settings.value("directories/lastInputVideo", QDir::homePath()).toString()); - } - if (dialog.exec() == QDialog::Accepted) { - ui->inputVideo->setText(dialog.selectedFiles().at(0)); - ui->txtVideoInfo->clear(); - - slotUpdateVideoInfo(); - - if (m_videoInfo.streamsCount <= 0) { - // No video stream found. Check if the path contains a non-ASCII character and warn if this is the case. - unsigned char ascii; - for (int i = 0; i < ui->inputVideo->text().length(); i++) { - ascii = ui->inputVideo->text().at(i).toAscii(); - if (ascii == 0 || ascii > 0x7f) { - ui->txtVideoInfo->appendPlainText( - tr("Character %1 is not an ASCII character. This file path will likely not work with ffmpeg.") - .arg(ui->inputVideo->text().at(i))); - break; - } - } - } - } -} - -void NewProjectDialog::slotSelectImages() -{ - QFileDialog dialog(this, tr("Select input images")); - dialog.setAcceptMode(QFileDialog::AcceptOpen); - dialog.setFileMode(QFileDialog::ExistingFiles); - if (m_images.size() > 0) { - dialog.setDirectory(QFileInfo(m_images.last()).absolutePath()); - } else { - dialog.setDirectory(m_settings.value("directories/lastInputImage", QDir::homePath()).toString()); - } - if (dialog.exec() == QDialog::Accepted) { - - m_images = dialog.selectedFiles(); - - ui->inputImages->clear(); - for (int i = 0; i < m_images.size(); i++) { - new QListWidgetItem(m_images.at(i), ui->inputImages); - } - - slotUpdateImagesInfo(); - } -} - -void NewProjectDialog::slotSelectProjectDir() -{ - QFileDialog dialog(this, tr("Select a project directory")); - dialog.setAcceptMode(QFileDialog::AcceptOpen); - dialog.setFileMode(QFileDialog::Directory); - if (ui->projectDir->text().length() > 0) { - dialog.setDirectory(ui->projectDir->text()); - } else { - dialog.setDirectory(m_settings.value("directories/lastProjectDir").toString()); - } - if (dialog.exec() == QDialog::Accepted) { - ui->projectDir->setText(dialog.selectedFiles().at(0)); - slotUpdateButtonStates(); - } -} - -void NewProjectDialog::slotUpdateVideoInfo() -{ - QFile file(ui->inputVideo->text()); - if (file.exists()) { - m_videoInfo = getInfo(ui->inputVideo->text().toStdString().c_str()); - QString text = trUtf8("Number of video streams: %1\nFrames: %2\nSize: %3×%4\n") - .arg(m_videoInfo.streamsCount).arg(m_videoInfo.framesCount) - .arg(m_videoInfo.width).arg(m_videoInfo.height); - text.append(tr("Frame rate: %1/%2").arg(m_videoInfo.frameRateNum).arg(m_videoInfo.frameRateDen)); - ui->txtVideoInfo->setPlainText(text); - } else { - m_videoInfo.streamsCount = 0; - ui->txtVideoInfo->setPlainText(tr("No video stream detected.")); - } - slotUpdateButtonStates(); -} - -void NewProjectDialog::slotUpdateImagesInfo() -{ - m_imagesMsg = ImagesFrameSource_sV::validateImages(m_images); - slotUpdateButtonStates(); -} - -void NewProjectDialog::slotUpdateButtonStates() -{ - bool ok = true; - - if (ui->projectDir->text().length() > 0) { - QDir dir(ui->projectDir->text()); - ui->cbDirectoryCreated->setChecked(!dir.exists()); - ui->projectDir->setStyleSheet(QString("QLineEdit { background-color: %1; }").arg(Colours_sV::colOk.name())); - m_projectDir = ui->projectDir->text(); - } else { - ui->projectDir->setStyleSheet(QString("QLineEdit { background-color: %1; }").arg(Colours_sV::colBad.name())); - ok = false; - } - QFile projectFile(projectFilename()); - if (ui->projectFilename->text().length() > 0 && !projectFile.exists()) { - ui->projectFilename->setStyleSheet(QString("QLineEdit { background-color: %1; }").arg(Colours_sV::colOk.name())); - } else { - ui->projectFilename->setStyleSheet(QString("QLineEdit { background-color: %1; }").arg(Colours_sV::colBad.name())); - ok = false; - } - - if (ui->radioVideo->isChecked()) { - // Validate the video file - if (m_videoInfo.streamsCount > 0 && m_videoInfo.framesCount > 0) { - ui->inputVideo->setStyleSheet(QString("QLineEdit { background-color: %1; }").arg(Colours_sV::colOk.name())); - m_inputFile = ui->inputVideo->text(); - } else { - ui->inputVideo->setStyleSheet(QString("QLineEdit { background-color: %1; }").arg(Colours_sV::colBad.name())); - ok = false; - } - } else if (ui->radioImages->isChecked()) { - // Validate the images - if (m_imagesMsg.length() == 0) { - ui->inputImages->setStyleSheet(QString("QListWidget { background-color: %1; }").arg(Colours_sV::colOk.name())); - ui->txtImageInfo->setText(tr("Image size: %1").arg(toString(QImage(m_images.at(0)).size()))); - } else { - ui->inputImages->setStyleSheet(QString("QListWidget { background-color: %1; }").arg(Colours_sV::colBad.name())); - ui->txtImageInfo->setText(m_imagesMsg); - ok = false; - } - } - - ui->bOk->setEnabled(ok); -} - -void NewProjectDialog::slotUpdateFrameSourceType() -{ - ui->groupImages->setEnabled(ui->radioImages->isChecked()); - ui->groupImages->setVisible(ui->radioImages->isChecked()); - ui->groupVideo->setEnabled(ui->radioVideo->isChecked()); - ui->groupVideo->setVisible(ui->radioVideo->isChecked()); - slotUpdateButtonStates(); - QSize prevSize = size(); - adjustSize(); - resize(prevSize.width(), size().height()); -}
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/slowmoUI/dialogues/newProjectDialog.h
Deleted
@@ -1,67 +0,0 @@ -/* -slowmoUI is a user interface for slowmoVideo. -Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. -*/ - -#ifndef NEWPROJECTDIALOG_H -#define NEWPROJECTDIALOG_H - -#include <QDialog> -#include <QtCore/QStringList> -#include <QSettings> - -#include "project/project_sV.h" - -extern "C" { - #include "lib/videoInfo_sV.h" -} - -namespace Ui { - class NewProjectDialog; -} - -class QButtonGroup; - -class NewProjectDialog : public QDialog -{ - Q_OBJECT - -public: - explicit NewProjectDialog(QWidget *parent = 0); - ~NewProjectDialog(); - - QString m_inputFile; - QString m_projectDir; - - Project_sV* buildProject() throw(FrameSourceError); - const QString projectFilename() const; - -private: - Ui::NewProjectDialog *ui; - QButtonGroup *m_buttonGroup; - - VideoInfoSV m_videoInfo; - QStringList m_images; - QString m_imagesMsg; - - QSettings m_settings; - - -private slots: - void slotSelectProjectDir(); - void slotSelectVideoFile(); - void slotSelectImages(); - - void slotUpdateVideoInfo(); - void slotUpdateImagesInfo(); - - void slotUpdateButtonStates(); - void slotUpdateFrameSourceType(); -}; - -#endif // NEWPROJECTDIALOG_H
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/slowmoUI/dialogues/preferencesDialog.cpp
Deleted
@@ -1,124 +0,0 @@ -#include "preferencesDialog.h" -#include "ui_preferencesDialog.h" - -#include "project/flowSourceV3D_sV.h" -#include "lib/defs_sV.hpp" -#include "lib/avconvInfo_sV.h" -#include "../../project/videoFrameSource_sV.h" -#include <QtCore/QProcess> -#include <QtGui/QFileDialog> - -PreferencesDialog::PreferencesDialog(QWidget *parent) : - QDialog(parent), - ui(new Ui::PreferencesDialog) -{ - ui->setupUi(this); - ui->buildFlow->setText(m_settings.value("binaries/v3dFlowBuilder", "").toString()); - ui->ffmpeg->setText(m_settings.value("binaries/ffmpeg", "ffmpeg").toString()); - -#if QT_VERSION >= 0x040700 - ui->buildFlow->setPlaceholderText(QApplication::translate("PreferencesDialog", "flowBuilder binary location", 0, QApplication::UnicodeUTF8)); -#endif - - m_flowMethodGroup.addButton(ui->methodOCV); - m_flowMethodGroup.addButton(ui->methodV3D); - m_flowMethodGroup.setExclusive(true); - - QString method = m_settings.value("preferences/flowMethod", "V3D").toString(); - if ("V3D" == method) { - ui->methodV3D->setChecked(true); - } else { - ui->methodOCV->setChecked(true); - } - - bool b = true; - b &= connect(ui->bOk, SIGNAL(clicked()), this, SLOT(accept())); - b &= connect(ui->bCancel, SIGNAL(clicked()), this, SLOT(reject())); - b &= connect(ui->bBuildFlow, SIGNAL(clicked()), this, SLOT(slotBrowseFlow())); - b &= connect(ui->buildFlow, SIGNAL(textChanged(QString)), this, SLOT(slotValidateFlowBinary())); - b &= connect(&m_flowMethodGroup, SIGNAL(buttonClicked(int)), this, SLOT(slotUpdateFlowMethod())); - b &= connect(ui->bFFmpeg, SIGNAL(clicked()), this, SLOT(slotBrowseFfmpeg())); - Q_ASSERT(b); - - if (!FlowSourceV3D_sV::validateFlowBinary(ui->buildFlow->text())) { - FlowSourceV3D_sV::correctFlowBinaryLocation(); - ui->buildFlow->setText(m_settings.value("binaries/v3dFlowBuilder", "").toString()); - } - slotValidateFlowBinary(); -} - -PreferencesDialog::~PreferencesDialog() -{ - delete ui; -} - -void PreferencesDialog::accept() -{ - // V3D binary location - if (FlowSourceV3D_sV::validateFlowBinary(ui->buildFlow->text())) { - m_settings.setValue("binaries/v3dFlowBuilder", ui->buildFlow->text()); - } - - // Flow method - QString method("OpenCV-Farnback"); - if (ui->methodV3D->isChecked()) { - method = "V3D"; - } - m_settings.setValue("preferences/flowMethod", method); - - // ffmpeg location - if (AvconvInfo::testAvconvExecutable(ui->ffmpeg->text())) { - m_settings.setValue("binaries/ffmpeg", ui->ffmpeg->text()); - } else { - qDebug() << "Not a valid ffmpeg/avconv executable: " << ui->ffmpeg->text(); - } - - // Store the values right now - m_settings.sync(); - - QDialog::accept(); -} - -void PreferencesDialog::slotUpdateFlowMethod() -{ -} -void PreferencesDialog::slotUpdateFfmpeg() -{ - m_settings.setValue("binaries/ffmpeg", ui->ffmpeg->text()); -} - -void PreferencesDialog::slotValidateFlowBinary() -{ - if (FlowSourceV3D_sV::validateFlowBinary(ui->buildFlow->text())) { - ui->buildFlow->setStyleSheet(QString("QLineEdit { background-color: %1; }").arg(Colours_sV::colOk.name())); - ui->methodV3D->setEnabled(true); - } else { - ui->buildFlow->setStyleSheet(QString("QLineEdit { background-color: %1; }").arg(Colours_sV::colBad.name())); - ui->methodV3D->setEnabled(false); - ui->methodOCV->setChecked(true); - } -} - -void PreferencesDialog::slotBrowseFlow() -{ - QFileDialog dialog; - dialog.setAcceptMode(QFileDialog::AcceptOpen); - dialog.setFileMode(QFileDialog::ExistingFile); - dialog.setDirectory(QFileInfo(ui->buildFlow->text()).absolutePath()); - if (dialog.exec() == QDialog::Accepted) { - ui->buildFlow->setText(dialog.selectedFiles().at(0)); - slotValidateFlowBinary(); - } -} - -void PreferencesDialog::slotBrowseFfmpeg() -{ - QFileDialog dialog; - dialog.setAcceptMode(QFileDialog::AcceptOpen); - dialog.setFileMode(QFileDialog::ExistingFile); - dialog.setDirectory(QFileInfo(ui->ffmpeg->text()).absolutePath()); - if (dialog.exec() == QDialog::Accepted) { - ui->ffmpeg->setText(dialog.selectedFiles().at(0)); - //slotValidateFffmpegBinary(); - } -} \ No newline at end of file
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/slowmoUI/dialogues/preferencesDialog.h
Deleted
@@ -1,36 +0,0 @@ -#ifndef PREFERENCESDIALOG_H -#define PREFERENCESDIALOG_H - -#include <QDialog> -#include <QtCore/QSettings> -#include <QtGui/QButtonGroup> - -namespace Ui { - class PreferencesDialog; -} - -class PreferencesDialog : public QDialog -{ - Q_OBJECT - -public: - explicit PreferencesDialog(QWidget *parent = 0); - ~PreferencesDialog(); - -protected slots: - void accept(); - -private: - Ui::PreferencesDialog *ui; - QButtonGroup m_flowMethodGroup; - QSettings m_settings; - -private slots: - void slotValidateFlowBinary(); - void slotUpdateFlowMethod(); - void slotUpdateFfmpeg(); - void slotBrowseFlow(); - void slotBrowseFfmpeg(); -}; - -#endif // PREFERENCESDIALOG_H
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/slowmoUI/dialogues/preferencesDialog.ui
Deleted
@@ -1,144 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>PreferencesDialog</class> - <widget class="QDialog" name="PreferencesDialog"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>536</width> - <height>220</height> - </rect> - </property> - <property name="windowTitle"> - <string>slowmoUI preferences</string> - </property> - <layout class="QVBoxLayout" name="verticalLayout_2"> - <item> - <layout class="QVBoxLayout" name="verticalLayout"> - <item> - <widget class="QGroupBox" name="groupBox"> - <property name="title"> - <string>Binary locations</string> - </property> - <layout class="QGridLayout" name="gridLayout"> - <item row="0" column="1"> - <widget class="QLineEdit" name="buildFlow"/> - </item> - <item row="0" column="2"> - <widget class="QPushButton" name="bBuildFlow"> - <property name="text"> - <string>Browse</string> - </property> - </widget> - </item> - <item row="0" column="0"> - <widget class="QLabel" name="label"> - <property name="text"> - <string notr="true">flowBuilder</string> - </property> - </widget> - </item> - <item row="1" column="0"> - <widget class="QLabel" name="label_2"> - <property name="text"> - <string notr="true">ffmpeg</string> - </property> - </widget> - </item> - <item row="1" column="1"> - <widget class="QLineEdit" name="ffmpeg"/> - </item> - <item row="1" column="2"> - <widget class="QPushButton" name="bFFmpeg"> - <property name="text"> - <string>Browse</string> - </property> - </widget> - </item> - </layout> - </widget> - </item> - </layout> - </item> - <item> - <widget class="QGroupBox" name="groupBox_2"> - <property name="title"> - <string>Flow method</string> - </property> - <layout class="QVBoxLayout" name="verticalLayout_3"> - <item> - <widget class="QRadioButton" name="methodV3D"> - <property name="text"> - <string>GPU, V3D (requires flowBuilder and a video card)</string> - </property> - </widget> - </item> - <item> - <widget class="QRadioButton" name="methodOCV"> - <property name="text"> - <string>CPU, OpenCV</string> - </property> - <property name="checked"> - <bool>true</bool> - </property> - </widget> - </item> - </layout> - </widget> - </item> - <item> - <spacer name="verticalSpacer"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>38</height> - </size> - </property> - </spacer> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout"> - <item> - <spacer name="horizontalSpacer"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QPushButton" name="bCancel"> - <property name="text"> - <string>Cancel</string> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="bOk"> - <property name="text"> - <string>Ok</string> - </property> - </widget> - </item> - </layout> - </item> - </layout> - </widget> - <tabstops> - <tabstop>buildFlow</tabstop> - <tabstop>bBuildFlow</tabstop> - <tabstop>bCancel</tabstop> - <tabstop>bOk</tabstop> - </tabstops> - <resources/> - <connections/> -</ui>
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/slowmoUI/dialogues/progressDialog.cpp
Deleted
@@ -1,78 +0,0 @@ -#include "progressDialog.h" -#include "ui_progressDialog.h" - -#include <QMessageBox> -#include <QtCore/QDebug> - -ProgressDialog::ProgressDialog(QWidget *parent) : - QDialog(parent), - ui(new Ui::ProgressDialog) -{ - ui->setupUi(this); - - bool b = true; - b &= connect(ui->bAbort, SIGNAL(clicked()), this, SLOT(slotAbortPressed())); - b &= connect(ui->bOk, SIGNAL(clicked()), this, SLOT(accept())); - Q_ASSERT(b); - - ui->bOk->setVisible(false); - ui->bOk->setEnabled(false); -} - -ProgressDialog::~ProgressDialog() -{ - delete ui; -} - -void ProgressDialog::setWorking(bool working) -{ - ui->bOk->setVisible(!working); - ui->bOk->setEnabled(!working); - ui->bAbort->setVisible(working); - ui->bAbort->setEnabled(working); -} - -void ProgressDialog::slotNextTask(const QString taskDescription, int taskSize) -{ - ui->lblTaskDesc->setText(taskDescription); - ui->progress->setMaximum(taskSize); - ui->progress->setValue(0); - if (windowTitle().startsWith(tr("(Finished) "))) { - setWindowTitle(windowTitle().remove(0, tr("(Finished) ").length())); - } - setWorking(true); -} -void ProgressDialog::slotTaskProgress(int progress) -{ - ui->progress->setValue(progress); -} -void ProgressDialog::slotTaskItemDescription(const QString desc) -{ - ui->lblTaskItemDesc->setText(desc); - repaint(); -} -void ProgressDialog::slotAbortPressed() -{ - emit signalAbortTask(); -} -void ProgressDialog::slotAborted(const QString &message) -{ - if (message.length() > 0) { - // Show message - QMessageBox box(QMessageBox::Warning, tr("Aborted"), message, QMessageBox::Ok); - box.show(); - } - reject(); -} - -void ProgressDialog::slotAllTasksFinished(const QString& timePassed) -{ - ui->progress->setValue(ui->progress->maximum()); - setWorking(false); - if (timePassed.length() > 0) { - slotTaskItemDescription(tr("Task finished in %1.").arg(timePassed)); - } else { - slotTaskItemDescription(tr("Task finished.")); - } - setWindowTitle(tr("(Finished) %1").arg(windowTitle())); -}
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/slowmoUI/dialogues/projectPreferencesDialog.cpp
Deleted
@@ -1,43 +0,0 @@ -#include "projectPreferencesDialog.h" -#include "ui_projectPreferencesDialog.h" - -#include "lib/defs_sV.hpp" - -ProjectPreferencesDialog::ProjectPreferencesDialog(ProjectPreferences_sV *prefs, QWidget *parent) : - QDialog(parent), - ui(new Ui::ProjectPreferencesDialog), - m_projectPrefs(prefs) -{ - ui->setupUi(this); - ui->canvas_xAxisFPS->setText(m_projectPrefs->canvas_xAxisFPS().toString()); - - bool b = true; - b &= connect(ui->canvas_xAxisFPS, SIGNAL(textChanged(QString)), this, SLOT(slotCheckFPS())); - Q_ASSERT(b); -} -ProjectPreferencesDialog::~ProjectPreferencesDialog() -{ - delete ui; -} - -void ProjectPreferencesDialog::accept() -{ - try { - Fps_sV fps(ui->canvas_xAxisFPS->text()); - m_projectPrefs->canvas_xAxisFPS().num = fps.num; - m_projectPrefs->canvas_xAxisFPS().den = fps.den; - } catch (Error_sV &err) {} - QDialog::accept(); -} - -void ProjectPreferencesDialog::slotCheckFPS() -{ - try { - Fps_sV fps(ui->canvas_xAxisFPS->text()); - ui->canvas_xAxisFPS->setStyleSheet(QString("QLineEdit { background-color: %1; }").arg(Colours_sV::colOk.name())); - fps.den = fps.num; // Just to hopefully avoid the fps being optimized out - } catch (Error_sV &err) { - ui->canvas_xAxisFPS->setStyleSheet(QString("QLineEdit { background-color: %1; }").arg(Colours_sV::colBad.name())); - } -} -
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/slowmoUI/dialogues/renderingDialog.cpp
Deleted
@@ -1,449 +0,0 @@ -/* -This file is part of slowmoVideo. -Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. -*/ - -#include "renderingDialog.h" -#include "ui_renderingDialog.h" - -#include "lib/defs_sV.hpp" -#include "project/motionBlur_sV.h" -#include "project/project_sV.h" -#include "project/projectPreferences_sV.h" -#include "project/renderTask_sV.h" -#include "project/imagesRenderTarget_sV.h" -#include "project/videoRenderTarget_sV.h" -#include "project/emptyFrameSource_sV.h" - -#include <QButtonGroup> -#include <QFileDialog> - -RenderingDialog::RenderingDialog(Project_sV *project, QWidget *parent) : - QDialog(parent), - ui(new Ui::RenderingDialog), - m_project(project) -{ - ui->setupUi(this); - - // Render section - m_sectionGroup = new QButtonGroup(this); - m_sectionGroup->addButton(ui->radioFullProject); - m_sectionGroup->addButton(ui->radioSection); - m_sectionGroup->addButton(ui->radioTagSection); - QString mode(m_project->preferences()->renderSectionMode()); - if (mode == "full") { - ui->radioFullProject->setChecked(true); - } else if (mode == "expr") { - ui->radioSection->setChecked(true); - } else if (mode == "tags") { - ui->radioTagSection->setChecked(true); - } else { - qDebug() << "Unknown render section mode: " << mode; - Q_ASSERT(false); - } - - // Optical flow - ui->lambda->setValue(m_project->preferences()->flowV3DLambda()); - - // Motion blur - ui->maxSamples->setValue(m_project->motionBlur()->maxSamples()); - ui->slowmoSamples->setValue(m_project->motionBlur()->slowmoSamples()); - m_blurGroup = new QButtonGroup(this); - m_blurGroup->addButton(ui->radioBlurConvolution); - m_blurGroup->addButton(ui->radioBlurStacking); - m_blurGroup->addButton(ui->radioBlurNearest); - if (m_project->preferences()->renderMotionblurType() == MotionblurType_Convolving) { - ui->radioBlurConvolution->setChecked(true); - } else if (m_project->preferences()->renderMotionblurType() == MotionblurType_Stacking) { - ui->radioBlurStacking->setChecked(true); - } else { - ui->radioBlurNearest->setChecked(true); - } - - fillTagLists(); - - // Output target type - m_targetGroup = new QButtonGroup(this); - m_targetGroup->addButton(ui->radioImages); - m_targetGroup->addButton(ui->radioVideo); - if (m_project->preferences()->renderTarget() == "images") { - ui->radioImages->setChecked(true); - } else { - ui->radioVideo->setChecked(true); - } - - // Output target files - ui->imagesOutputDir->setText(m_project->preferences()->imagesOutputDir()); - ui->imagesFilenamePattern->setText(m_project->preferences()->imagesFilenamePattern()); - ui->videoOutputFile->setText(m_project->preferences()->videoFilename()); - ui->vcodec->setText(m_project->preferences()->videoCodec()); - - // FPS - QString fps = QVariant(m_project->preferences()->renderFPS().fps()).toString(); - if (ui->cbFps->findText(fps) < 0 && fps.toFloat() > 0) { - ui->cbFps->addItem(fps); - } - ui->cbFps->setCurrentIndex(ui->cbFps->findText(fps)); - - // Output size - ui->cbSize->addItem(tr("Original size"), QVariant(FrameSize_Orig)); - ui->cbSize->addItem(tr("Small"), QVariant(FrameSize_Small)); - ui->cbSize->setCurrentIndex(ui->cbSize->findData(QVariant(m_project->preferences()->renderFrameSize()))); - - // Interpolation type - ui->cbInterpolation->addItem(toString(InterpolationType_Forward), QVariant(InterpolationType_Forward)); - ui->cbInterpolation->addItem(toString(InterpolationType_ForwardNew), QVariant(InterpolationType_ForwardNew)); - ui->cbInterpolation->addItem(toString(InterpolationType_Twoway), QVariant(InterpolationType_Twoway)); - ui->cbInterpolation->addItem(toString(InterpolationType_TwowayNew), QVariant(InterpolationType_TwowayNew)); - ui->cbInterpolation->addItem(toString(InterpolationType_Bezier), QVariant(InterpolationType_Bezier)); - if (ui->cbInterpolation->findData(QVariant(m_project->preferences()->renderInterpolationType())) >= 0) { - ui->cbInterpolation->setCurrentIndex(ui->cbInterpolation->findData(QVariant(m_project->preferences()->renderInterpolationType()))); - } - - bool b = true; - b &= connect(m_targetGroup, SIGNAL(buttonClicked(int)), this, SLOT(slotUpdateRenderTarget())); - b &= connect(m_sectionGroup, SIGNAL(buttonClicked(int)), this, SLOT(slotSectionModeChanged())); - b &= connect(ui->timeStart, SIGNAL(textChanged(QString)), this, SLOT(slotValidate())); - b &= connect(ui->timeEnd, SIGNAL(textChanged(QString)), this, SLOT(slotValidate())); - - b &= connect(ui->cbStartTag, SIGNAL(currentIndexChanged(int)), this, SLOT(slotTagIndexChanged())); - b &= connect(ui->cbEndTag, SIGNAL(currentIndexChanged(int)), this, SLOT(slotTagIndexChanged())); - - b &= connect(ui->bAbort, SIGNAL(clicked()), this, SLOT(reject())); - b &= connect(ui->bOk, SIGNAL(clicked()), this, SLOT(accept())); - b &= connect(ui->bSave, SIGNAL(clicked()), this, SLOT(slotSaveSettings())); - - b &= connect(ui->cbFps, SIGNAL(editTextChanged(QString)), this, SLOT(slotValidate())); - - b &= connect(ui->imagesOutputDir, SIGNAL(textChanged(QString)), this, SLOT(slotValidate())); - b &= connect(ui->imagesFilenamePattern, SIGNAL(textChanged(QString)), this, SLOT(slotValidate())); - b &= connect(ui->videoOutputFile, SIGNAL(textChanged(QString)), this, SLOT(slotValidate())); - b &= connect(ui->bImagesBrowseDir, SIGNAL(clicked()), this, SLOT(slotBrowseImagesDir())); - b &= connect(ui->bBrowseVideoOutputFile, SIGNAL(clicked()), this, SLOT(slotBrowseVideoFile())); - Q_ASSERT(b); - - // Restore rendering start/end - int index; - index = ui->cbStartTag->findText(m_project->preferences()->renderStartTag()); - if (index >= 0) { - ui->cbStartTag->setCurrentIndex(index); - } - index = ui->cbEndTag->findText(m_project->preferences()->renderEndTag()); - if (index >= 0) { - ui->cbEndTag->setCurrentIndex(index); - } - if (m_project->preferences()->renderStartTime().length() > 0) { - ui->timeStart->setText(m_project->preferences()->renderStartTime()); - } - if (m_project->preferences()->renderEndTime().length() > 0) { - ui->timeEnd->setText(m_project->preferences()->renderEndTime()); - } - -#if QT_VERSION >= 0x040700 - ui->timeStart->setPlaceholderText(QVariant(m_project->nodes()->startTime()).toString()); - ui->timeEnd->setPlaceholderText(QVariant(m_project->nodes()->endTime()).toString()); -#endif - - slotUpdateRenderTarget(); - slotSectionModeChanged(); -} - -RenderingDialog::~RenderingDialog() -{ - delete m_targetGroup; - delete ui; -} - -RenderTask_sV* RenderingDialog::buildTask() -{ - if (slotValidate()) { - slotSaveSettings(); - - ProjectPreferences_sV *prefs = m_project->preferences(); - - const QString imagesOutputDir = ui->imagesOutputDir->text(); - const QString imagesFilenamePattern = ui->imagesFilenamePattern->text(); - - RenderTask_sV *task = new RenderTask_sV(m_project); - task->renderPreferences().setFps(prefs->renderFPS()); - task->renderPreferences().size = prefs->renderFrameSize(); - task->renderPreferences().interpolation = prefs->renderInterpolationType(); - task->renderPreferences().motionblur = prefs->renderMotionblurType(); - - - if (ui->radioImages->isChecked()) { - ImagesRenderTarget_sV *renderTarget = new ImagesRenderTarget_sV(task); - renderTarget->setFilenamePattern(imagesFilenamePattern); - renderTarget->setTargetDir(imagesOutputDir); - task->setRenderTarget(renderTarget); - } else if (ui->radioVideo->isChecked()) { - VideoRenderTarget_sV *renderTarget = new VideoRenderTarget_sV(task); - renderTarget->setTargetFile(ui->videoOutputFile->text()); - renderTarget->setVcodec(ui->vcodec->text()); - task->setRenderTarget(renderTarget); - } else { - qDebug() << "Render target is neither images nor video. Not implemented?"; - Q_ASSERT(false); - } - - if (ui->radioTagSection->isChecked()) { - bool b; - qreal start = ui->cbStartTag->itemData(ui->cbStartTag->currentIndex()).toFloat(&b); - Q_ASSERT(b); - qreal end = ui->cbEndTag->itemData(ui->cbEndTag->currentIndex()).toFloat(&b); - Q_ASSERT(b); - qDebug() << QString("Rendering tag section from %1 (%2) to %3 (%4)") - .arg(ui->cbStartTag->currentText()) - .arg(start).arg(ui->cbEndTag->currentText()).arg(end); - Q_ASSERT(start <= end); - task->setTimeRange(start, end); - } else if (ui->radioSection->isChecked()) { - qDebug() << QString("Rendering time section from %1 to %3") - .arg(ui->cbStartTag->currentText()) - .arg(ui->cbEndTag->currentText()); - task->setTimeRange(ui->timeStart->text(), ui->timeEnd->text()); - } - - QString mode; - if (ui->radioFullProject->isChecked()) { - mode = "full"; - } else if (ui->radioSection->isChecked()) { - mode = "time"; - m_project->preferences()->renderStartTime() = ui->timeStart->text(); - m_project->preferences()->renderEndTime() = ui->timeEnd->text(); - } else if (ui->radioTagSection->isChecked()) { - mode = "tags"; - m_project->preferences()->renderStartTag() = ui->cbStartTag->currentText(); - m_project->preferences()->renderEndTag() = ui->cbEndTag->currentText(); - } else { - qDebug() << "No section mode selected?"; - Q_ASSERT(false); - } - return task; - } else { - return NULL; - } -} - -void RenderingDialog::fillTagLists() -{ - QList<Tag_sV> list; - for (int i = 0; i < m_project->tags()->size(); i++) { - if (m_project->tags()->at(i).axis() == TagAxis_Output - && m_project->tags()->at(i).time() > m_project->nodes()->startTime() - && m_project->tags()->at(i).time() < m_project->nodes()->endTime()) { - list << m_project->tags()->at(i); - } - } - qSort(list); - ui->cbStartTag->addItem(tr("<Start>"), QVariant(m_project->nodes()->startTime())); - for (int i = 0; i < list.size(); i++) { - ui->cbStartTag->addItem(list.at(i).description(), QVariant(list.at(i).time())); - ui->cbEndTag->addItem(list.at(i).description(), QVariant(list.at(i).time())); - } - ui->cbEndTag->addItem(tr("<End>"), QVariant(m_project->nodes()->endTime())); -} - -void RenderingDialog::slotSaveSettings() -{ - - const InterpolationType interpolation = (InterpolationType)ui->cbInterpolation->itemData(ui->cbInterpolation->currentIndex()).toInt(); - const FrameSize size = (FrameSize)ui->cbSize->itemData(ui->cbSize->currentIndex()).toInt(); - const QString imagesOutputDir = ui->imagesOutputDir->text(); - const QString imagesFilenamePattern = ui->imagesFilenamePattern->text(); - const float fps = ui->cbFps->currentText().toFloat(); - - m_project->motionBlur()->setMaxSamples(ui->maxSamples->value()); - m_project->motionBlur()->setSlowmoSamples(ui->slowmoSamples->value()); - m_project->preferences()->flowV3DLambda() = ui->lambda->value(); - - if (ui->radioBlurConvolution->isChecked()) { - m_project->preferences()->renderMotionblurType() = MotionblurType_Convolving; - } else if (ui->radioBlurStacking->isChecked()) { - m_project->preferences()->renderMotionblurType() = MotionblurType_Stacking; - } else { - m_project->preferences()->renderMotionblurType() = MotionblurType_Nearest; - } - - QString mode; - if (ui->radioFullProject->isChecked()) { - mode = "full"; - } else if (ui->radioSection->isChecked()) { - mode = "expr"; - m_project->preferences()->renderStartTime() = ui->timeStart->text(); - m_project->preferences()->renderEndTime() = ui->timeEnd->text(); - } else if (ui->radioTagSection->isChecked()) { - mode = "tags"; - m_project->preferences()->renderStartTag() = ui->cbStartTag->currentText(); - m_project->preferences()->renderEndTag() = ui->cbEndTag->currentText(); - } else { - qDebug() << "No section mode selected?"; - Q_ASSERT(false); - } - m_project->preferences()->renderSectionMode() = mode; - m_project->preferences()->imagesOutputDir() = imagesOutputDir; - m_project->preferences()->imagesFilenamePattern() = imagesFilenamePattern; - m_project->preferences()->videoFilename() = ui->videoOutputFile->text(); - m_project->preferences()->videoCodec() = ui->vcodec->text(); - m_project->preferences()->renderInterpolationType() = interpolation; - m_project->preferences()->renderFrameSize() = size; - m_project->preferences()->renderFPS() = fps; - m_project->preferences()->renderTarget() = ui->radioImages->isChecked() ? "images" : "video"; - - accept(); -} - -bool RenderingDialog::slotValidate() -{ - bool ok = true; - - float fps = ui->cbFps->currentText().toFloat(&ok); - ok &= fps > 0; - if (ok) { - ui->cbFps->setStyleSheet(QString("QComboBox { background-color: %1; }").arg(Colours_sV::colOk.name())); - } else { - ui->cbFps->setStyleSheet(QString("QComboBox { background-color: %1; }").arg(Colours_sV::colBad.name())); - } - - if (ui->radioImages->isChecked()) { - if (ui->imagesFilenamePattern->text().contains("%1")) { - ui->imagesFilenamePattern->setStyleSheet(QString("QLineEdit { background-color: %1; }").arg(Colours_sV::colOk.name())); - } else { - ok = false; - ui->imagesFilenamePattern->setStyleSheet(QString("QLineEdit { background-color: %1; }").arg(Colours_sV::colBad.name())); - } - - if (ui->imagesOutputDir->text().length() > 0) { - ui->imagesOutputDir->setStyleSheet(QString("QLineEdit { background-color: %1; }").arg(Colours_sV::colOk.name())); - } else { - ok = false; - ui->imagesOutputDir->setStyleSheet(QString("QLineEdit { background-color: %1; }").arg(Colours_sV::colBad.name())); - } - } else if (ui->radioVideo->isChecked()) { - if (ui->videoOutputFile->text().length() > 0) { - ui->videoOutputFile->setStyleSheet(QString("QLineEdit { background-color: %1; }").arg(Colours_sV::colOk.name())); - } else { - ok = false; - ui->videoOutputFile->setStyleSheet(QString("QLineEdit { background-color: %1; }").arg(Colours_sV::colBad.name())); - } - } else { - Q_ASSERT(false); - } - - if (ui->radioSection->isChecked()) { - bool startOk = false; - bool endOk = false; - qreal timeStart = 0; - qreal timeEnd = 0; - QStringList messages; - - Fps_sV currentFps(ui->cbFps->currentText().toFloat()); - try { - timeStart = m_project->toOutTime(ui->timeStart->text(), currentFps); - startOk = true; - } catch (Error_sV &err) { - messages << err.message(); - } - try { - timeEnd = m_project->toOutTime(ui->timeEnd->text(), currentFps); - endOk = true; - } catch (Error_sV &err) { - messages << err.message(); - } - if (timeEnd <= timeStart) { - endOk = false; - messages << tr("Start time must be < end time!"); - } - - messages << tr("Rendering from %1 s to %2 s.").arg(timeStart).arg(timeEnd); - ui->sectionMessage->setText(messages.join("\n")); - - ok &= startOk && endOk; - - if (!startOk) { - ui->timeStart->setStyleSheet(QString("QLineEdit { background-color: %1; }").arg(Colours_sV::colBad.name())); - } else { - ui->timeStart->setStyleSheet(QString("QLineEdit { background-color: %1; }").arg(Colours_sV::colOk.name())); - } - if (!endOk) { - ui->timeEnd->setStyleSheet(QString("QLineEdit { background-color: %1; }").arg(Colours_sV::colBad.name())); - } else { - ui->timeEnd->setStyleSheet(QString("QLineEdit { background-color: %1; }").arg(Colours_sV::colOk.name())); - } - } - - ok &= dynamic_cast<EmptyFrameSource_sV*>(m_project->frameSource()) == NULL; - - ok &= m_project->nodes()->size() >= 2; - - ui->bOk->setEnabled(ok); - - return ok; -} - -void RenderingDialog::slotUpdateRenderTarget() -{ - ui->groupImages->setVisible(ui->radioImages->isChecked()); - ui->groupVideo->setVisible(ui->radioVideo->isChecked()); - slotValidate(); -} - -void RenderingDialog::slotBrowseImagesDir() -{ - QFileDialog dialog(this, tr("Output directory for rendered images")); - dialog.setAcceptMode(QFileDialog::AcceptOpen); - dialog.setFileMode(QFileDialog::Directory); - dialog.setOption(QFileDialog::ShowDirsOnly, true); - dialog.setDirectory(ui->imagesOutputDir->text()); - if (dialog.exec() == QDialog::Accepted) { - ui->imagesOutputDir->setText(dialog.selectedFiles().at(0)); - } -} - -void RenderingDialog::slotBrowseVideoFile() -{ - QFileDialog dialog(this, tr("Output video file")); - dialog.setAcceptMode(QFileDialog::AcceptSave); - dialog.setFileMode(QFileDialog::AnyFile); - dialog.setDirectory(QFileInfo(ui->videoOutputFile->text()).absolutePath()); - if (dialog.exec() == QDialog::Accepted) { - ui->videoOutputFile->setText(dialog.selectedFiles().at(0)); - } -} - -void RenderingDialog::slotSectionModeChanged() -{ - ui->timeStart->setVisible(ui->radioSection->isChecked()); - ui->timeEnd->setVisible(ui->radioSection->isChecked()); - ui->sectionMessage->setVisible(ui->radioSection->isChecked()); - ui->cbStartTag->setVisible(ui->radioTagSection->isChecked()); - ui->cbEndTag->setVisible(ui->radioTagSection->isChecked()); - ui->lblcTo->setVisible(ui->radioSection->isChecked() || ui->radioTagSection->isChecked()); - slotValidate(); -} - -void RenderingDialog::slotTagIndexChanged() -{ - if (QObject::sender() == ui->cbStartTag) { - qDebug() << "Start tag"; - if (ui->cbEndTag->currentIndex() < ui->cbStartTag->currentIndex()) { - ui->cbEndTag->setCurrentIndex(ui->cbStartTag->currentIndex()); - } - } else { - qDebug() << "End tag"; - if (ui->cbStartTag->currentIndex() > ui->cbEndTag->currentIndex()) { - ui->cbStartTag->setCurrentIndex(ui->cbEndTag->currentIndex()); - } - } -} - - - - - -
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/slowmoUI/dialogues/renderingDialog.h
Deleted
@@ -1,64 +0,0 @@ -/* -This file is part of slowmoVideo. -Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. -*/ - -#ifndef RENDERINGDIALOG_H -#define RENDERINGDIALOG_H - -#include <QDialog> - -namespace Ui { - class RenderingDialog; -} - -class QButtonGroup; -class RenderTask_sV; -class Project_sV; - -/** - \brief Dialog for rendering option - */ -class RenderingDialog : public QDialog -{ - Q_OBJECT - -public: - explicit RenderingDialog(Project_sV *project, QWidget *parent = 0); - ~RenderingDialog(); - - /** \return \c NULL on invalid input, a render task for the given project otherwise */ - RenderTask_sV* buildTask(); - -public slots: - bool slotValidate(); - -private: - Ui::RenderingDialog *ui; - - Project_sV *m_project; - QButtonGroup *m_targetGroup; - QButtonGroup *m_sectionGroup; - QButtonGroup *m_blurGroup; - - void fillTagLists(); - -private slots: - void slotBrowseImagesDir(); - void slotBrowseVideoFile(); - void slotUpdateRenderTarget(); - - void slotSectionModeChanged(); - void slotTagIndexChanged(); - - void slotSaveSettings(); - - -}; - -#endif // RENDERINGDIALOG_H
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/slowmoUI/dialogues/renderingDialog.ui
Deleted
@@ -1,849 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>RenderingDialog</class> - <widget class="QDialog" name="RenderingDialog"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>718</width> - <height>495</height> - </rect> - </property> - <property name="windowTitle"> - <string>Rendering settings</string> - </property> - <layout class="QVBoxLayout" name="verticalLayout_2"> - <item> - <spacer name="verticalSpacer_2"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>10</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QTabWidget" name="tabWidget"> - <property name="currentIndex"> - <number>0</number> - </property> - <widget class="QWidget" name="tabWidgetPage1"> - <property name="accessibleName"> - <string>a</string> - </property> - <property name="accessibleDescription"> - <string>a</string> - </property> - <attribute name="title"> - <string>Rendering settings</string> - </attribute> - <layout class="QVBoxLayout" name="verticalLayout_8"> - <item> - <layout class="QHBoxLayout" name="horizontalLayout"> - <item> - <widget class="QRadioButton" name="radioFullProject"> - <property name="text"> - <string>Full Project</string> - </property> - <property name="checked"> - <bool>true</bool> - </property> - </widget> - </item> - <item> - <widget class="QRadioButton" name="radioTagSection"> - <property name="text"> - <string>Tag section</string> - </property> - </widget> - </item> - <item> - <widget class="QRadioButton" name="radioSection"> - <property name="text"> - <string>Custom section</string> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer_5"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>13</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QComboBox" name="cbStartTag"/> - </item> - <item> - <widget class="QLineEdit" name="timeStart"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="baseSize"> - <size> - <width>100</width> - <height>0</height> - </size> - </property> - <property name="maxLength"> - <number>16</number> - </property> - </widget> - </item> - <item> - <widget class="QLabel" name="lblcTo"> - <property name="text"> - <string>to</string> - </property> - </widget> - </item> - <item> - <widget class="QLineEdit" name="timeEnd"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="baseSize"> - <size> - <width>100</width> - <height>0</height> - </size> - </property> - <property name="maxLength"> - <number>16</number> - </property> - </widget> - </item> - <item> - <widget class="QComboBox" name="cbEndTag"/> - </item> - <item> - <spacer name="horizontalSpacer_2"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_8"> - <item> - <spacer name="horizontalSpacer_11"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>30</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QLabel" name="sectionMessage"> - <property name="text"> - <string/> - </property> - <property name="wordWrap"> - <bool>true</bool> - </property> - </widget> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_5"> - <item> - <widget class="QLabel" name="label_2"> - <property name="text"> - <string>Frames per second:</string> - </property> - </widget> - </item> - <item> - <widget class="QComboBox" name="cbFps"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>100</width> - <height>0</height> - </size> - </property> - <property name="baseSize"> - <size> - <width>100</width> - <height>0</height> - </size> - </property> - <property name="editable"> - <bool>true</bool> - </property> - <property name="currentIndex"> - <number>0</number> - </property> - <item> - <property name="text"> - <string notr="true">23.976</string> - </property> - </item> - <item> - <property name="text"> - <string notr="true">24</string> - </property> - </item> - <item> - <property name="text"> - <string notr="true">25</string> - </property> - </item> - <item> - <property name="text"> - <string notr="true">29.976</string> - </property> - </item> - <item> - <property name="text"> - <string notr="true">30</string> - </property> - </item> - <item> - <property name="text"> - <string notr="true">50</string> - </property> - </item> - <item> - <property name="text"> - <string notr="true">60</string> - </property> - </item> - <item> - <property name="text"> - <string notr="true">72</string> - </property> - </item> - </widget> - </item> - <item> - <spacer name="horizontalSpacer_4"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_6"> - <item> - <widget class="QLabel" name="label_3"> - <property name="text"> - <string>Size:</string> - </property> - </widget> - </item> - <item> - <widget class="QComboBox" name="cbSize"/> - </item> - <item> - <spacer name="horizontalSpacer_7"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Minimum</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>10</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QLabel" name="label_4"> - <property name="text"> - <string>Interpolation:</string> - </property> - </widget> - </item> - <item> - <widget class="QComboBox" name="cbInterpolation"/> - </item> - <item> - <spacer name="horizontalSpacer_6"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_9"> - <property name="topMargin"> - <number>8</number> - </property> - <item> - <widget class="QLabel" name="label_13"> - <property name="text"> - <string>For two frames A and B, the two-way interpolations calculate both the flows A→B and B→A, which leads to smoother transitions between them. Forward interpolations only calculate A→B; Twice as fast, but usually less smooth.</string> - </property> - <property name="wordWrap"> - <bool>true</bool> - </property> - </widget> - </item> - </layout> - </item> - <item> - <spacer name="verticalSpacer"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>40</height> - </size> - </property> - </spacer> - </item> - </layout> - </widget> - <widget class="QWidget" name="tabWidgetPage2"> - <attribute name="title"> - <string>Optical Flow</string> - </attribute> - <layout class="QVBoxLayout" name="verticalLayout_9"> - <item> - <widget class="QGroupBox" name="groupBox_3"> - <property name="title"> - <string>Optical flow</string> - </property> - <layout class="QVBoxLayout" name="verticalLayout_6"> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_7"> - <item> - <widget class="QLabel" name="label_12"> - <property name="text"> - <string>buildFlow lambda</string> - </property> - </widget> - </item> - <item> - <widget class="QDoubleSpinBox" name="lambda"> - <property name="locale"> - <locale language="English" country="UnitedStates"/> - </property> - <property name="minimum"> - <double>5.000000000000000</double> - </property> - <property name="maximum"> - <double>50.000000000000000</double> - </property> - <property name="singleStep"> - <double>1.000000000000000</double> - </property> - <property name="value"> - <double>20.000000000000000</double> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer_10"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>10</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QLabel" name="label_11"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>Use a higher value for high-quality footage and larger images.</string> - </property> - <property name="wordWrap"> - <bool>true</bool> - </property> - </widget> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_10"> - <property name="topMargin"> - <number>8</number> - </property> - <item> - <widget class="QLabel" name="label_14"> - <property name="text"> - <string>The lambda is only used with the GPU based Optical Flow algorithm. There is no general rule which value is best, so it is usually a good idea to render a short part with a low (5) and a high (50) lambda to see the differences, and then try to find the best value between.</string> - </property> - <property name="wordWrap"> - <bool>true</bool> - </property> - </widget> - </item> - </layout> - </item> - <item> - <spacer name="verticalSpacer_3"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>40</height> - </size> - </property> - </spacer> - </item> - </layout> - </widget> - </item> - </layout> - </widget> - <widget class="QWidget" name="tabWidgetPage3"> - <attribute name="title"> - <string>Motion Blur</string> - </attribute> - <layout class="QVBoxLayout" name="verticalLayout_10"> - <item> - <widget class="QGroupBox" name="groupBox_2"> - <property name="title"> - <string>Motion blur</string> - </property> - <layout class="QVBoxLayout" name="verticalLayout_5"> - <item> - <widget class="QLabel" name="label_9"> - <property name="text"> - <string>Motion blur will only be applied for segments on which it is enabled.</string> - </property> - <property name="wordWrap"> - <bool>true</bool> - </property> - </widget> - </item> - <item> - <widget class="QRadioButton" name="radioBlurStacking"> - <property name="text"> - <string>Stacking blur (Uses more disk space, but is faster for repeated rendering.)</string> - </property> - </widget> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_2"> - <item> - <widget class="QLabel" name="label_6"> - <property name="text"> - <string>Maximum samples</string> - </property> - </widget> - </item> - <item> - <widget class="QSpinBox" name="maxSamples"> - <property name="minimum"> - <number>1</number> - </property> - <property name="value"> - <number>64</number> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer_9"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>10</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QLabel" name="label_8"> - <property name="text"> - <string>Samples for slow motion</string> - </property> - </widget> - </item> - <item> - <widget class="QSpinBox" name="slowmoSamples"> - <property name="minimum"> - <number>1</number> - </property> - <property name="value"> - <number>16</number> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer_8"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - </layout> - </item> - <item> - <widget class="QRadioButton" name="radioBlurConvolution"> - <property name="text"> - <string>Convolution blur (Smoother than stacking, usually the better choice.)</string> - </property> - </widget> - </item> - <item> - <widget class="QRadioButton" name="radioBlurNearest"> - <property name="text"> - <string>Nearest (no blurring)</string> - </property> - </widget> - </item> - </layout> - </widget> - </item> - <item> - <spacer name="verticalSpacer_4"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>40</height> - </size> - </property> - </spacer> - </item> - </layout> - </widget> - <widget class="QWidget" name="tabWidgetPage4"> - <attribute name="title"> - <string>Output</string> - </attribute> - <layout class="QVBoxLayout" name="verticalLayout_11"> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_3"> - <item> - <widget class="QLabel" name="label"> - <property name="text"> - <string>Target:</string> - </property> - </widget> - </item> - <item> - <widget class="QRadioButton" name="radioVideo"> - <property name="enabled"> - <bool>true</bool> - </property> - <property name="text"> - <string>Video</string> - </property> - </widget> - </item> - <item> - <widget class="QRadioButton" name="radioImages"> - <property name="text"> - <string>Images</string> - </property> - <property name="checked"> - <bool>true</bool> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer_3"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - </layout> - </item> - <item> - <widget class="QGroupBox" name="groupImages"> - <property name="title"> - <string>Images</string> - </property> - <layout class="QVBoxLayout" name="verticalLayout"> - <item> - <widget class="QLabel" name="label_10"> - <property name="text"> - <string>The %1 in the filename pattern is mandatory and will be replaced by the frame number.</string> - </property> - </widget> - </item> - <item> - <layout class="QGridLayout" name="gridLayout"> - <item row="0" column="0"> - <widget class="QLabel" name="lblcOutputDir"> - <property name="text"> - <string>Output directory</string> - </property> - </widget> - </item> - <item row="0" column="1"> - <widget class="QLineEdit" name="imagesOutputDir"/> - </item> - <item row="0" column="2"> - <widget class="QPushButton" name="bImagesBrowseDir"> - <property name="text"> - <string>Browse</string> - </property> - </widget> - </item> - <item row="1" column="0"> - <widget class="QLabel" name="lblcFilenamePattern"> - <property name="text"> - <string>Filename pattern</string> - </property> - </widget> - </item> - <item row="1" column="1"> - <widget class="QLineEdit" name="imagesFilenamePattern"> - <property name="toolTip"> - <string extracomment="%1 for the frame number (required!)"/> - </property> - <property name="text"> - <string>rendered-%1.jpg</string> - </property> - </widget> - </item> - </layout> - </item> - </layout> - </widget> - </item> - <item> - <widget class="QGroupBox" name="groupVideo"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Minimum"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="title"> - <string>Video</string> - </property> - <layout class="QVBoxLayout" name="verticalLayout_3"> - <item> - <widget class="QLabel" name="label_7"> - <property name="text"> - <string>Videos will be encoded with ffmpeg. If additional arguments are left empty, defaults will be used. The video format is determined by ffmpeg according to the file suffix.</string> - </property> - <property name="wordWrap"> - <bool>true</bool> - </property> - </widget> - </item> - <item> - <layout class="QGridLayout" name="gridLayout_2"> - <item row="0" column="0"> - <widget class="QLabel" name="lblcOutputFile"> - <property name="text"> - <string>Output file</string> - </property> - </widget> - </item> - <item row="0" column="1"> - <widget class="QLineEdit" name="videoOutputFile"/> - </item> - <item row="0" column="2"> - <widget class="QPushButton" name="bBrowseVideoOutputFile"> - <property name="text"> - <string>Browse</string> - </property> - </widget> - </item> - <item row="1" column="0" colspan="3"> - <widget class="QGroupBox" name="groupBox"> - <property name="title"> - <string>Optional arguments</string> - </property> - <layout class="QVBoxLayout" name="verticalLayout_4"> - <item> - <layout class="QGridLayout" name="gridLayout_3"> - <item row="0" column="0"> - <widget class="QLabel" name="label_5"> - <property name="text"> - <string notr="true">vcodec</string> - </property> - </widget> - </item> - <item row="0" column="1"> - <widget class="QLineEdit" name="vcodec"/> - </item> - </layout> - </item> - </layout> - </widget> - </item> - </layout> - </item> - </layout> - </widget> - </item> - <item> - <spacer name="verticalSpacer_5"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>40</height> - </size> - </property> - </spacer> - </item> - </layout> - </widget> - </widget> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_4"> - <item> - <spacer name="horizontalSpacer"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QPushButton" name="bSave"> - <property name="toolTip"> - <string>Will *not* save the project!</string> - </property> - <property name="text"> - <string>&Save settings</string> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="bAbort"> - <property name="text"> - <string>&Abort</string> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="bOk"> - <property name="text"> - <string>&Ok</string> - </property> - </widget> - </item> - </layout> - </item> - </layout> - </widget> - <tabstops> - <tabstop>radioFullProject</tabstop> - <tabstop>cbFps</tabstop> - <tabstop>cbSize</tabstop> - <tabstop>cbInterpolation</tabstop> - <tabstop>radioVideo</tabstop> - <tabstop>radioImages</tabstop> - <tabstop>imagesOutputDir</tabstop> - <tabstop>bImagesBrowseDir</tabstop> - <tabstop>imagesFilenamePattern</tabstop> - <tabstop>videoOutputFile</tabstop> - <tabstop>bBrowseVideoOutputFile</tabstop> - <tabstop>vcodec</tabstop> - <tabstop>bAbort</tabstop> - <tabstop>bOk</tabstop> - </tabstops> - <resources/> - <connections/> -</ui>
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/slowmoUI/dialogues/shutterFunctionDialog.cpp
Deleted
@@ -1,222 +0,0 @@ -/* -This file is part of slowmoVideo. -Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. -*/ - -#include "shutterFunctionDialog.h" -#include "ui_shutterFunctionDialog.h" -#include "project/shutterFunction_sV.h" -#include "project/shutterFunctionList_sV.h" -#include "project/project_sV.h" -#include <QtGui/QPainter> - -QString ShutterFunctionDialog::emptyFunction("<None>"); - -/// \todo Icons -ShutterFunctionDialog::ShutterFunctionDialog(Project_sV *project, QWidget *parent) : - QDialog(parent), - ui(new Ui::ShutterFunctionDialog), - m_currentFunction(NULL) -{ - ui->setupUi(this); - - ui->lblcHeader->setText(ShutterFunction_sV::templateHeader); - ui->lblcFooter->setText(ShutterFunction_sV::templateFooter); - - bool b = true; - b &= connect(ui->bClose, SIGNAL(clicked()), this, SLOT(accept())); - b &= connect(ui->cbFunction, SIGNAL(currentIndexChanged(int)), this, SLOT(slotUpdateNode())); - b &= connect(ui->cbFunction, SIGNAL(currentIndexChanged(int)), this, SLOT(slotLoadSelectedFunction())); - b &= connect(ui->function, SIGNAL(textChanged()), this, SLOT(slotFunctionTextChanged())); - b &= connect(ui->bAdd, SIGNAL(clicked()), this, SLOT(slotAddFunction())); - b &= connect(ui->bRemove, SIGNAL(clicked()), this, SLOT(slotRemoveFunction())); - - b &= connect(ui->bPrevSegment, SIGNAL(clicked()), this, SLOT(slotPrevSegment())); - b &= connect(ui->bNextSegment, SIGNAL(clicked()), this, SLOT(slotNextSegment())); - Q_ASSERT(b); - - loadProject(project); - slotLoadSelectedFunction(); -} - -ShutterFunctionDialog::~ShutterFunctionDialog() -{ - delete ui; -} - -void ShutterFunctionDialog::loadProject(Project_sV *project) -{ - qDebug() << "loadProject();"; - m_project = project; - ui->cbFunction->blockSignals(true); - ui->cbFunction->clear(); - ui->cbFunction->addItem(emptyFunction); - for (int i = 0; i < project->shutterFunctions()->size(); i++) { - ui->cbFunction->addItem(m_project->shutterFunctions()->at(i)->id()); - } - ui->cbFunction->blockSignals(false); - setSegment(0); -} - -void ShutterFunctionDialog::paintEvent(QPaintEvent *e) -{ - QDialog::paintEvent(e); - QPainter p(this); - QImage img(":images/shutterFunc.png"); - p.drawImage(ui->verticalLayout_code->contentsRect().topRight() - QPoint(img.width()+10, -10), img); -} - -void ShutterFunctionDialog::closeEvent(QCloseEvent *e) -{ - m_project->nodes()->segments()->unselectAll(); - parentWidget()->repaint(); - QDialog::closeEvent(e); -} - -void ShutterFunctionDialog::slotNodesUpdated() -{ - qDebug() << "slotNodesUpdated();"; - if (m_segment+1 >= m_project->nodes()->size() && m_project->nodes()->size() >= 2) { - setSegment(m_project->nodes()->size()-2); - } else { - setSegment(m_segment); - } -} - -void ShutterFunctionDialog::setSegment(int segment) -{ - qDebug() << "setSegment(" << segment << ");"; - m_segment = segment; - ui->lblSegmentNumber->setText(tr("Segment %1 (total number: %2)") - .arg(m_segment).arg(m_project->nodes()->size()-1)); - - // Enable/disable buttons - ui->bPrevSegment->setEnabled(m_segment > 0); - ui->bNextSegment->setEnabled(m_segment+1 < m_project->nodes()->size()-1); - - - // Update the curve parameters for this segment - if (m_project->nodes()->size() >= 2) { - const Node_sV *leftNode = &m_project->nodes()->at(m_segment); - const Node_sV *rightNode = &m_project->nodes()->at(m_segment+1); - ui->shutterCurve->updateValues( - leftNode->y(), - 1.0/24 * (rightNode->y()-leftNode->y()) / (rightNode->x()-leftNode->x()) // dy = dx * /\y / /\x - ); - - Q_ASSERT(m_segment+1 < m_project->nodes()->size()); - } else { - qDebug() << "Less than 2 nodes!"; - } - - // Select function in the dropdown - if (m_project->nodes()->size() >= 2) { - const Node_sV *node = &m_project->nodes()->at(m_segment); - QString id = node->shutterFunctionID(); - qDebug() << "Shutter function ID of node " << node << " is " << id; - if (id.length() == 0) { - ui->cbFunction->setCurrentIndex(ui->cbFunction->findText(emptyFunction)); - } else { - int pos = ui->cbFunction->findText(id); - Q_ASSERT(pos >= 0); - ui->cbFunction->setCurrentIndex(pos); - } - } - - m_project->nodes()->segments()->unselectAll(); - (*m_project->nodes()->segments())m_segment.select(); - parentWidget()->repaint(); - - Q_ASSERT(m_segment >= 0); -} - -void ShutterFunctionDialog::slotUpdateNode() -{ - qDebug() << "slotUpdateNode();"; - if (m_project->nodes()->size() >= 2) { - Q_ASSERT(m_segment+1 < m_project->nodes()->size()); - QString id = ui->cbFunction->currentText(); - if (id == emptyFunction) { - id = ""; - } - Node_sV *node = &(*m_project->nodes())m_segment; - node->setShutterFunctionID(id); - qDebug() << "Shutter function ID of node " << node << "set to " << id; - } -} - -void ShutterFunctionDialog::slotFunctionTextChanged() -{ - qDebug() << "slotUpdateFunctionCode();"; - if (m_currentFunction != NULL) { - ui->function->setEnabled(true); - m_currentFunction->updateFunction(ui->function->toPlainText()); - ui->shutterCurve->slotDisplayFunction(ui->function->toPlainText()); - } - else { - ui->function->setEnabled(false); - ui->shutterCurve->slotDisplayFunction("return 0;"); - } -} - -void ShutterFunctionDialog::slotLoadSelectedFunction() -{ - QString id = ui->cbFunction->currentText(); - if (id == emptyFunction) { - id = ""; - m_currentFunction = NULL; - ui->function->setPlainText("return 0;"); - } else { - m_currentFunction = m_project->shutterFunctions()->function(id); - ui->function->setPlainText(m_currentFunction->function()); - } - int count = 0; - for (int i = 0; i < m_project->nodes()->size(); i++) { - if (m_project->nodes()->at(i).shutterFunctionID() == id) { - count++; - } - } - ui->lblUsage->setText(tr("Used: %1 times").arg(count)); - -} - -void ShutterFunctionDialog::slotAddFunction() -{ - ShutterFunction_sV *fun = m_project->shutterFunctions()->addFunction(ShutterFunction_sV(), true); - if (fun != NULL) { - ui->cbFunction->addItem(fun->id()); - ui->cbFunction->setCurrentIndex(ui->cbFunction->findText(fun->id())); - } else { - qDebug() << "Could not add new function."; - Q_ASSERT(false); - } -} - -void ShutterFunctionDialog::slotRemoveFunction() -{ - if (ui->cbFunction->currentText() != emptyFunction) { - bool ok = m_project->shutterFunctions()->removeFunction(ui->cbFunction->currentText()); - int index = ui->cbFunction->currentIndex(); - ui->cbFunction->setCurrentIndex(ui->cbFunction->findText(emptyFunction)); - ui->cbFunction->removeItem(index); - Q_ASSERT(ok); - } -} - -void ShutterFunctionDialog::slotPrevSegment() -{ - qDebug() << "slotPrevSegment();"; - setSegment(m_segment-1); -} - -void ShutterFunctionDialog::slotNextSegment() -{ - qDebug() << "slotNextSegment();"; - setSegment(m_segment+1); -} -
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/slowmoUI/dialogues/tagAddDialog.cpp
Deleted
@@ -1,84 +0,0 @@ -/* -This file is part of slowmoVideo. -Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. -*/ - -#include "tagAddDialog.h" -#include "ui_tagAddDialog.h" -#include <QtGui/QKeyEvent> - -TagAddDialog::TagAddDialog(TagAxis defaultAxis, QWidget *parent) : - QDialog(parent), - ui(new Ui::TagAddDialog), - m_axis(defaultAxis) -{ - ui->setupUi(this); - ui->bOk->setEnabled(false); - - bool b = true; - b &= connect(ui->bAbort, SIGNAL(clicked()), this, SLOT(reject())); - b &= connect(ui->bOk, SIGNAL(clicked()), this, SLOT(accept())); - b &= connect(ui->tag, SIGNAL(textChanged(QString)), this, SLOT(slotTextChanged(QString))); - b &= connect(ui->tag, SIGNAL(returnPressed()), ui->bOk, SLOT(click())); - Q_ASSERT(b); - - slotUpdateAxis(); -} - -TagAddDialog::~TagAddDialog() -{ - delete ui; -} - -Tag_sV TagAddDialog::buildTag(QPointF time) -{ - if (m_axis == TagAxis_Source) { - return Tag_sV(time.y(), ui->tag->text(), m_axis); - } else { - return Tag_sV(time.x(), ui->tag->text(), m_axis); - } -} - -void TagAddDialog::keyPressEvent(QKeyEvent *e) -{ - if (e->key() == Qt::Key_Up) { - m_axis = TagAxis_Source; - slotUpdateAxis(); - } else if (e->key() == Qt::Key_Down) { - m_axis = TagAxis_Output; - slotUpdateAxis(); - } else { - QDialog::keyPressEvent(e); - } -} - -void TagAddDialog::slotTextChanged(const QString &text) -{ - if (text.length() == 0) { - ui->bOk->setEnabled(false); - } else { - ui->bOk->setEnabled(true); - m_text = text; - } -} - -void TagAddDialog::slotUpdateAxis() -{ - QSizePolicy::Policy upperPolicy = QSizePolicy::Fixed; - QSizePolicy::Policy lowerPolicy = QSizePolicy::Expanding; - if (m_axis == TagAxis_Output) { - upperPolicy = QSizePolicy::Expanding; - lowerPolicy = QSizePolicy::Fixed; - } - ui->verticalUpperSpacer->changeSize(0, 0, QSizePolicy::Minimum, upperPolicy); - ui->verticalLowerSpacer->changeSize(0, 0, QSizePolicy::Minimum, lowerPolicy); - ui->verticalLayout_2->invalidate(); - - repaint(); - updateGeometry(); -}
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/slowmoUI/frameMonitor.cpp
Deleted
@@ -1,69 +0,0 @@ -/* -slowmoUI is a user interface for slowmoVideo. -Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. -*/ - -#include "frameMonitor.h" -#include "ui_frameMonitor.h" - -#include <QImage> -#include <QPainter> -#include <QDebug> - -FrameMonitor::FrameMonitor(QWidget *parent) : - QWidget(parent), - ui(new Ui::FrameMonitor), - m_semaphore(1) -{ - ui->setupUi(this); - m_queue0 = NULL; - m_queue1 = NULL; -} - -FrameMonitor::~FrameMonitor() -{ - delete ui; - if (m_queue0 != NULL) { delete m_queue0; } - if (m_queue1 != NULL) { delete m_queue1; } -} - -void FrameMonitor::slotLoadImage(const QString &filename) -{ - m_semaphore.acquire(); - if (m_queue0 == NULL) { - m_queue0 = new QString(filename); - } else { - if (m_queue1 != NULL) { - delete m_queue1; - m_queue1 = NULL; - } - m_queue1 = new QString(filename); - } - m_semaphore.release(); - repaint(); -} - -void FrameMonitor::paintEvent(QPaintEvent *) -{ - QString image; - m_semaphore.acquire(); - if (m_queue0 != NULL) { - image = *m_queue0; - delete m_queue0; - m_queue0 = NULL; - } - if (m_queue1 != NULL) { - m_queue0 = m_queue1; - m_queue1 = NULL; - } - m_semaphore.release(); - - if (!image.isNull()) { - ui->imageDisplay->loadImage(QImage(image)); - } -}
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/slowmoUI/frameMonitor.h
Deleted
@@ -1,47 +0,0 @@ -/* -slowmoUI is a user interface for slowmoVideo. -Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. -*/ - -#ifndef INPUTMONITOR_H -#define INPUTMONITOR_H - -#include <QWidget> -#include <QSemaphore> - -namespace Ui { - class FrameMonitor; -} -class QImage; - -/** - \brief Used for displaying input frames at the mouse position. - */ -class FrameMonitor : public QWidget -{ - Q_OBJECT - -public: - explicit FrameMonitor(QWidget *parent = 0); - ~FrameMonitor(); - -protected: - virtual void paintEvent(QPaintEvent *event); - - -public slots: - void slotLoadImage(const QString &filename); - -private: - Ui::FrameMonitor *ui; - - QSemaphore m_semaphore; - QString *m_queue2; -}; - -#endif // INPUTMONITOR_H
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/slowmoUI/main.cpp
Deleted
@@ -1,87 +0,0 @@ -/* -slowmoUI is a user interface for slowmoVideo. -Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. -*/ - -#include <QtGui/QApplication> -#include <QtCore/QTranslator> -#include <QtCore/QDebug> -#include "mainwindow.h" - -int main(int argc, char *argv) -{ - -#ifdef Q_OS_MACX - // fix for osx UI and Qt4 - if ( QSysInfo::MacintoshVersion > QSysInfo::MV_10_8 ) - { - // fix Mac OS X 10.9 (mavericks) font issue - // https://bugreports.qt-project.org/browse/QTBUG-32789 - QFont::insertSubstitution(".Lucida Grande UI", "Lucida Grande"); - } -#endif - - QApplication a(argc, argv); - - // Set up preferences for the QSettings file - QCoreApplication::setOrganizationName("Granjow"); - QCoreApplication::setOrganizationDomain("granjow.net"); - QCoreApplication::setApplicationName("slowmoUI"); - - - - QString projectPath; - qDebug() << a.arguments(); - - const int N = a.arguments().size(); - for (int n = 1; n < N; n++) { - QString arg = a.arguments().at(n); - if (arg.startsWith("--")) { - - bool langUpdated = true; - - // Changes the file loaded from the resource container - // to force a different language - if (arg == "--de") { - QLocale::setDefault(QLocale::German); - } else if (arg == "--en") { - QLocale::setDefault(QLocale::English); - } else if (arg == "--it") { - QLocale::setDefault(QLocale::Italian); - } else { - langUpdated = false; - } - - if (langUpdated) { - qDebug() << "Changed locale to " << QLocale::languageToString(QLocale().language()); - } else { - qDebug() << "Not handled: " << arg; - } - - } else { - QFileInfo info(arg); - if (info.exists() && info.isReadable() && info.isFile()) { - projectPath = info.absoluteFilePath(); - qDebug() << "Loading project: " << projectPath; - } else { - qDebug() << projectPath << " does not exist."; - } - } - } - - // Load the translation file from the resource container and use it - QTranslator translator; - translator.load(":translations"); - a.installTranslator(&translator); - - MainWindow w(projectPath); - - w.show(); - - return a.exec(); -}
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/slowmoUI/mainwindow.cpp
Deleted
@@ -1,586 +0,0 @@ -/* -slowmoUI is a user interface for slowmoVideo. -Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. -*/ - -#include "mainwindow.h" -#include "ui_mainwindow.h" - -#include "newProjectDialog.h" -#include "progressDialog.h" -#include "renderingDialog.h" -#include "projectPreferencesDialog.h" -#include "preferencesDialog.h" -#include "aboutDialog.h" - -#include "lib/defs_sV.hpp" -#include "project/renderTask_sV.h" -#include "project/xmlProjectRW_sV.h" -#include "project/abstractFrameSource_sV.h" -#include "project/projectPreferences_sV.h" - -#include <QtCore> -#include <QObject> -#include <QDockWidget> -#include <QDebug> -#include <QMessageBox> -#include <QtGui/QStatusBar> - -#include <QDir> -#include <QFileDialog> - -#include <QShortcut> -#include <QSignalMapper> -#include <QTime> -#include <QFuture> - -#include <QPainter> - -#include <functional> - -MainWindow::MainWindow(QString projectPath, QWidget *parent) : - QMainWindow(parent), - ui(new Ui::MainWindow), - m_progressDialog(NULL), - m_renderProgressDialog(NULL), - m_flowExaminer(NULL), - m_cs(this) -{ - ui->setupUi(this); - - restoreGeometry(m_settings.value("geometry").toByteArray()); - restoreState(m_settings.value("windowState").toByteArray()); - - m_project = new Project_sV(); - - m_wCanvas = new Canvas(m_project, this); - setCentralWidget(m_wCanvas); - - - m_wInputMonitor = new FrameMonitor(this); - m_wInputMonitorDock = new QDockWidget(tr("Input monitor"), this); - m_wInputMonitorDock->setWidget(m_wInputMonitor); - m_wInputMonitorDock->setObjectName("inputMonitor"); - addDockWidget(Qt::TopDockWidgetArea, m_wInputMonitorDock); - - m_wCurveMonitor = new FrameMonitor(this); - m_wCurveMonitorDock = new QDockWidget(tr("Curve monitor"), this); - m_wCurveMonitorDock->setWidget(m_wCurveMonitor); - m_wCurveMonitorDock->setObjectName("curveMonitor"); - addDockWidget(Qt::TopDockWidgetArea, m_wCurveMonitorDock); - - m_wRenderPreview = new RenderPreview(m_project, this); - m_wRenderPreviewDock = new QDockWidget(tr("Render preview"), this); - m_wRenderPreviewDock->setWidget(m_wRenderPreview); - m_wRenderPreviewDock->setObjectName("renderPreview"); - addDockWidget(Qt::TopDockWidgetArea, m_wRenderPreviewDock); - - // Fill the view menu that allows (de)activating widgets - QObjectList windowChildren = children(); - QDockWidget *w; - for (int i = 0; i < windowChildren.size(); i++) { - if ((w = dynamic_cast<QDockWidget*>(windowChildren.at(i))) != NULL) { - qDebug() << "Adding " << w->windowTitle() << " to the menu's widget list"; - - QAction *a = new QAction("&" + w->objectName(), this); - a->setCheckable(true); - bool b = true; - b &= connect(a, SIGNAL(toggled(bool)), w, SLOT(setVisible(bool))); - // This does not work since it is also emitted e.g. when the window is minimized - // (with «Show Desktop» on KDE4), therefore an event filter is required. (below.) - // Thanks ArGGu^^ for the tip! -// b &= connect(w, SIGNAL(visibilityChanged(bool)), a, SLOT(setChecked(bool))); - Q_ASSERT(b); - a->setChecked(true); - - // To uncheck the menu entry when the widget is closed via the (x) - w->installEventFilter(this); - - ui->menuView->addAction(a); - m_widgetActions << a; - - } - } - - - - - ui->actionNew->setShortcut(QKeySequence("Ctrl+N")); - ui->actionOpen->setShortcut(QKeySequence("Ctrl+O")); - ui->actionSave->setShortcut(QKeySequence("Ctrl+S")); - ui->actionSave_as->setShortcut(QKeySequence("Shift+Ctrl+S")); - ui->actionShortcuts->setShortcut(QKeySequence("Ctrl+H")); - ui->actionRender->setShortcut(QKeySequence("Ctrl+R")); - ui->actionRenderPreview->setShortcut(QKeySequence("Shift+Ctrl+R")); - ui->actionExamineFlow->setShortcut(QKeySequence("Shift+Ctrl+X")); - ui->actionPreferences->setShortcut(QKeySequence("Ctrl+,")); - ui->actionAbout->setShortcut(QKeySequence("F1")); - ui->actionQuit->setShortcut(QKeySequence("Ctrl+Q")); - ui->actionZoomIn->setShortcut(QKeySequence("+")); - ui->actionZoomOut->setShortcut(QKeySequence("-")); - - m_cs.addShortcut("h", Help, tr("Show help overlay")); - m_cs.addShortcut("q-q", Quit, tr("Quit")); - m_cs.addShortcut("n", New, tr("New project")); - m_cs.addShortcut("o", Open, tr("Open project")); - m_cs.addShortcut("s-s", Save_Same, tr("Save")); - m_cs.addShortcut("s-a", Save_As, tr("Save as ...")); - m_cs.addShortcut("a", Abort, tr("Abort move")); - m_cs.addShortcut("a-s", Abort_Selection, tr("Unselect all")); - m_cs.addShortcut("d-n", Delete_Node, tr("Delete selected nodes")); - m_cs.addShortcut("t-s", Tool_Select, tr("Selecting tool")); - m_cs.addShortcut("t-m", Tool_Move, tr("Move tool")); - m_cs.addShortcut("t-t", Tag, tr("Insert label (tag)")); - - bool b = true; - b &= connect(&m_cs, SIGNAL(signalShortcutUsed(int)), this, SLOT(slotShortcutUsed(int))); - - b &= connect(this, SIGNAL(deleteNodes()), m_wCanvas, SLOT(slotDeleteNodes())); - b &= connect(this, SIGNAL(setMode(Canvas::ToolMode)), m_wCanvas, SLOT(slotSetToolMode(Canvas::ToolMode))); - b &= connect(this, SIGNAL(abort(Canvas::Abort)), m_wCanvas, SLOT(slotAbort(Canvas::Abort))); - b &= connect(this, SIGNAL(addTag()), m_wCanvas, SLOT(slotAddTag())); - - b &= connect(ui->actionZoomIn, SIGNAL(triggered()), m_wCanvas, SLOT(slotZoomIn())); - b &= connect(ui->actionZoomOut, SIGNAL(triggered()), m_wCanvas, SLOT(slotZoomOut())); - - b &= connect(m_wCanvas, SIGNAL(signalMouseInputTimeChanged(qreal)), - this, SLOT(slotForwardInputPosition(qreal))); - b &= connect(m_wCanvas, SIGNAL(signalMouseCurveSrcTimeChanged(qreal)), - this, SLOT(slotForwardCurveSrcPosition(qreal))); - - b &= connect(ui->actionNew, SIGNAL(triggered()), this, SLOT(slotNewProject())); - b &= connect(ui->actionOpen, SIGNAL(triggered()), this, SLOT(slotLoadProjectDialog())); - b &= connect(ui->actionSave, SIGNAL(triggered()), this, SLOT(slotSaveProject())); - b &= connect(ui->actionSave_as, SIGNAL(triggered()), this, SLOT(slotSaveProjectDialog())); - b &= connect(ui->actionRender, SIGNAL(triggered()), this, SLOT(slotShowRenderDialog())); - b &= connect(ui->actionRenderPreview, SIGNAL(triggered()), this, SLOT(slotUpdateRenderPreview())); - b &= connect(ui->actionExamineFlow, SIGNAL(triggered()), this, SLOT(slotShowFlowExaminerDialog())); - b &= connect(ui->actionPreferences, SIGNAL(triggered()), this, SLOT(slotShowPreferencesDialog())); - b &= connect(ui->actionShortcuts, SIGNAL(triggered()), this, SLOT(slotToggleHelp())); - b &= connect(ui->actionAbout, SIGNAL(triggered()), this, SLOT(slotShowAboutDialog())); - b &= connect(ui->actionQuit, SIGNAL(triggered()), this, SLOT(close())); - b &= connect(ui->actionProjectPreferences, SIGNAL(triggered()), this, SLOT(slotShowProjectPreferencesDialog())); - - Q_ASSERT(b); - - updateWindowTitle(); - setWindowIcon(QIcon(":icons/slowmoIcon.png")); - - QSettings settings; - bool show = settings.value("ui/displayHelp", true).toBool(); - m_wCanvas->showHelp(show); - settings.sync(); - - - if (!projectPath.isEmpty()) { - loadProject(projectPath); - } -} - -MainWindow::~MainWindow() -{ - delete ui; - delete m_wInputMonitor; - delete m_wCurveMonitor; - delete m_wInputMonitorDock; - delete m_wCurveMonitorDock; - delete m_wRenderPreview; - delete m_wRenderPreviewDock; - - if (m_project != NULL) { - delete m_project; - } - - if (m_progressDialog != NULL) { - delete m_progressDialog; - } - if (m_renderProgressDialog != NULL) { - delete m_renderProgressDialog; - } - if (m_flowExaminer != NULL) { - delete m_flowExaminer; - } - - for (int i = 0; i < m_widgetActions.size(); i++) { - delete m_widgetActionsi; - } -} - -void MainWindow::closeEvent(QCloseEvent *e) -{ - m_settings.setValue("geometry", saveGeometry()); - m_settings.setValue("windowState", saveState()); - QMainWindow::closeEvent(e); -} - -bool MainWindow::eventFilter(QObject *obj, QEvent *e) -{ - QObjectList windowChildren = children(); - QDockWidget *w; - - if (e->type() == QEvent::Close && windowChildren.contains(obj)) { - if ((w = dynamic_cast<QDockWidget *>(obj)) != NULL) { - - QList<QAction*> actions = findChildren<QAction *>(); - for (int i = 0; i < actions.size(); i++) { - if (actions.at(i)->text() == w->objectName()) { - actions.at(i)->setChecked(false); - return true; - } - } - - } - } - - return false; -} - - - - - - -////////// Shortcuts - -void MainWindow::slotShortcutUsed(int id) -{ - if (id == Quit) { - qApp->quit(); - } else if (id == Abort_Selection) { - emit abort(Canvas::Abort_Selection); - } else if (id == Delete_Node) { - emit deleteNodes(); - } else if (id == Tool_Select) { - emit setMode(Canvas::ToolMode_Select); - } else if (id == Tool_Move) { - emit setMode(Canvas::ToolMode_Move); - } else if (id == Tag) { - emit addTag(); - } else if (id == Save_Same) { - slotSaveProject(); - } else if (id == Save_As) { - slotSaveProjectDialog(); - } else if (id == Abort) { - emit abort(Canvas::Abort_General); - } else if (id == Help) { - slotToggleHelp(); - } else if (id == New) { - slotNewProject(); - } else if (id == Open) { - slotLoadProjectDialog(); - } -} - - -////////// Project R/W - -void MainWindow::slotNewProject() -{ - NewProjectDialog npd(this); - if (npd.exec() == QDialog::Accepted) { - try { - Project_sV *project = npd.buildProject(); - - // Save project - XmlProjectRW_sV writer; - writer.saveProject(project, npd.projectFilename()); - m_projectPath = npd.projectFilename(); - - project->preferences()->viewport_secRes() = QPointF(400, 400)/project->frameSource()->framesCount()*project->frameSource()->fps()->fps(); - loadProject(project); - - m_wCanvas->showHelp(true); - - - } catch (FrameSourceError &err) { - QMessageBox(QMessageBox::Warning, "Frame source error", err.message()).exec(); - } - } -} -void MainWindow::loadProject(Project_sV *project) -{ - Q_ASSERT(project != NULL); - resetDialogs(); - - Project_sV *projTemp = NULL; - if (m_project != NULL) { - projTemp = m_project; - } - m_project = project; - m_wCanvas->load(m_project); - m_wRenderPreview->load(m_project); - updateWindowTitle(); - - if (projTemp != NULL) { - // Do not delete the old project object earlier to avoid segfaults - // (may still be used in the ShutterFunction dialog e.g.) - delete projTemp; - } - - bool b = true; - b &= connect(m_project->frameSource(), SIGNAL(signalNextTask(QString,int)), this, SLOT(slotNewFrameSourceTask(QString,int))); - b &= connect(m_project->frameSource(), SIGNAL(signalAllTasksFinished()), this, SLOT(slotFrameSourceTasksFinished())); - Q_ASSERT(b); - - m_project->frameSource()->initialize(); -} -void MainWindow::slotLoadProjectDialog() -{ - QString dir = m_settings.value("directories/lastOpenedProject", QDir::current().absolutePath()).toString(); - QString file = QFileDialog::getOpenFileName(this, tr("Load Project"), dir, tr("slowmoVideo projects (*.sVproj)")); - - if (!file.isEmpty()) { - qDebug() << file; - loadProject(QFileInfo(file).absoluteFilePath()); - } -} - -void MainWindow::loadProject(QString path) -{ - m_settings.setValue("directories/lastOpenedProject", path); - XmlProjectRW_sV reader; - try { - QString warning; - Project_sV *project = reader.loadProject(path, &warning); - if (warning.length() > 0) { - QMessageBox(QMessageBox::Warning, tr("Warning"), warning).exec(); - } - m_projectPath = path; - loadProject(project); - } catch (FrameSourceError &err) { - QMessageBox(QMessageBox::Warning, tr("Frame source error"), err.message()).exec(); - } catch (Error_sV &err) { - QMessageBox(QMessageBox::Warning, tr("Error"), err.message()).exec(); - } -} - -void MainWindow::slotSaveProject(QString filename) -{ - if (filename.length() == 0) { - filename = m_project->projectFilename(); - } - if (filename.length() == 0) { - qDebug() << "No filename given, won't save. (Perhaps an empty project?)"; - statusBar()->showMessage(tr("No filename given, won't save. (Perhaps an empty project?)"), 5000); - } else { - qDebug() << "Saving project as " << filename; - try { - XmlProjectRW_sV writer; - writer.saveProject(m_project, filename); - statusBar()->showMessage(QString(tr("Saved project as: %1")).arg(filename)); - } catch (Error_sV &err) { - QMessageBox(QMessageBox::Warning, tr("Error writing project file"), err.message()).exec(); - } - } -} -void MainWindow::slotSaveProjectDialog() -{ - QFileDialog dialog(this, tr("Save project")); - dialog.setAcceptMode(QFileDialog::AcceptSave); - dialog.setDefaultSuffix("sVproj"); - dialog.setNameFilter(tr("slowmoVideo projects (*.sVproj)")); - dialog.setFileMode(QFileDialog::AnyFile); - dialog.setDirectory(QFileInfo(m_project->projectFilename()).absolutePath()); - if (dialog.exec() == QDialog::Accepted) { - slotSaveProject(dialog.selectedFiles().at(0)); - } -} - - - -////////// UI interaction - -void MainWindow::slotToggleHelp() -{ - m_wCanvas->toggleHelp(); -} -void MainWindow::displayHelp(QPainter &davinci) const -{ - QString helpText = m_cs.shortcutList() - + tr("\nNavigation: Shift Scroll, Drag") - + tr("\nMove nodes: Ctrl Drag"); - - QRect content; - const QPoint topLeft(10, 10); - const QPoint padding(10, 10); - - // Check how big the text's bounding box will be - davinci.drawText(QRect(0,0,0,0), Qt::AlignLeft | Qt::TextExpandTabs, helpText, &content); - - // Draw the background - content.adjust(topLeft.x(), topLeft.y(), topLeft.x()+2*padding.x(), topLeft.y()+2*padding.y()); - davinci.fillRect(content, QColor(0,0,40, 200)); - - // Really draw the text now - content.translate(padding); - davinci.drawText(content, Qt::AlignLeft, helpText, &content); -} -void MainWindow::slotForwardInputPosition(qreal frame) -{ - if (0 <= frame && frame < m_project->frameSource()->framesCount()) { - m_wInputMonitor->slotLoadImage(m_project->frameSource()->framePath(qFloor(frame), FrameSize_Small)); - } -} -void MainWindow::slotForwardCurveSrcPosition(qreal frame) -{ - if (0 <= frame && frame < m_project->frameSource()->framesCount()) { - m_wCurveMonitor->slotLoadImage(m_project->frameSource()->framePath(qFloor(frame), FrameSize_Orig)); - } -} -void MainWindow::slotUpdateRenderPreview() -{ - m_wRenderPreview->slotRenderAt(m_project->snapToOutFrame( - m_wCanvas->prevMouseTime().x(), false, - m_project->preferences()->renderFPS(), NULL) - ); -} -void MainWindow::updateWindowTitle() -{ - QString project(tr("empty project")); - if (m_projectPath.length() > 0) { - project = m_projectPath; - } - setWindowTitle(QString("slowmo UI (%1)").arg(project)); -} - - - -////////// Dialogues - -void MainWindow::resetDialogs() -{ - if (m_progressDialog != NULL) { - m_progressDialog->close(); - delete m_progressDialog; - m_progressDialog = NULL; - } - if (m_renderProgressDialog != NULL) { - m_renderProgressDialog->close(); - delete m_renderProgressDialog; - m_renderProgressDialog = NULL; - } - if (m_flowExaminer != NULL) { - m_flowExaminer->close(); - delete m_flowExaminer; - m_flowExaminer = NULL; - } -} - -void MainWindow::slotShowAboutDialog() -{ - AboutDialog dialog(this); - dialog.exec(); -} - -void MainWindow::slotShowPreferencesDialog() -{ - PreferencesDialog dialog; - dialog.exec(); - - // Use the new flow method (if it has changed) - m_project->reloadFlowSource(); -} - -void MainWindow::slotShowProjectPreferencesDialog() -{ - ProjectPreferencesDialog ppd(m_project->preferences(), this); - ppd.exec(); -} - -void MainWindow::slotShowFlowExaminerDialog() -{ - if (m_flowExaminer == NULL) { - m_flowExaminer = new FlowExaminer(m_project, this); - } - - int frame = floor(m_wCanvas->prevMouseInFrame()); - if (frame+1 >= m_project->frameSource()->framesCount()) { - frame = m_project->frameSource()->framesCount()-2; - } - if (frame < 0) { frame = 0; } - - m_flowExaminer->show(); - m_flowExaminer->examine(frame); -} - -void MainWindow::slotShowRenderDialog() -{ - RenderingDialog renderingDialog(m_project, this); - if (renderingDialog.exec() == QDialog::Accepted) { - - RenderTask_sV *task = renderingDialog.buildTask(); - task->moveToThread(&m_rendererThread); - - if (m_project->renderTask() != NULL) { - bool b = true; - b &= disconnect(SIGNAL(signalRendererContinue()), m_project->renderTask()); - Q_ASSERT(b); - } - m_project->replaceRenderTask(task); - - - if (m_renderProgressDialog == NULL) { - m_renderProgressDialog = new ProgressDialog(this); - m_renderProgressDialog->setWindowTitle(tr("Rendering progress")); - } else { - m_renderProgressDialog->disconnect(); - } - - bool b = true; - b &= connect(task, SIGNAL(signalNewTask(QString,int)), m_renderProgressDialog, SLOT(slotNextTask(QString,int))); - b &= connect(task, SIGNAL(signalItemDesc(QString)), m_renderProgressDialog, SLOT(slotTaskItemDescription(QString))); - b &= connect(task, SIGNAL(signalTaskProgress(int)), m_renderProgressDialog, SLOT(slotTaskProgress(int))); - b &= connect(task, SIGNAL(signalRenderingFinished(QString)), m_renderProgressDialog, SLOT(slotAllTasksFinished(QString))); - b &= connect(task, SIGNAL(signalRenderingAborted(QString)), this, SLOT(slotRenderingAborted(QString))); - b &= connect(task, SIGNAL(signalRenderingAborted(QString)), m_renderProgressDialog, SLOT(close())); - b &= connect(task, SIGNAL(signalRenderingStopped(QString)), m_renderProgressDialog, SLOT(slotAborted(QString))); - b &= connect(m_renderProgressDialog, SIGNAL(signalAbortTask()), task, SLOT(slotStopRendering())); - b &= connect(this, SIGNAL(signalRendererContinue()), task, SLOT(slotContinueRendering()), Qt::UniqueConnection); - // TODO continue/abort - Q_ASSERT(b); - - m_renderProgressDialog->show(); - - emit signalRendererContinue(); - m_rendererThread.start(); - - } -} -void MainWindow::slotRenderingAborted(QString message) -{ - QMessageBox(QMessageBox::Warning, tr("Error"), message, QMessageBox::Ok).exec(); -} - -void MainWindow::slotNewFrameSourceTask(const QString taskDescription, int taskSize) -{ - if (m_progressDialog == NULL) { - m_progressDialog = new ProgressDialog(this); - m_progressDialog->setWindowTitle(tr("Frame extraction progress")); - bool b = true; - b &= connect(m_project->frameSource(), SIGNAL(signalNextTask(QString,int)), m_progressDialog, SLOT(slotNextTask(QString,int))); - b &= connect(m_project->frameSource(), SIGNAL(signalTaskProgress(int)), m_progressDialog, SLOT(slotTaskProgress(int))); - b &= connect(m_project->frameSource(), SIGNAL(signalTaskItemDescription(QString)), m_progressDialog, SLOT(slotTaskItemDescription(QString))); - b &= connect(m_project->frameSource(), SIGNAL(signalAllTasksFinished()), m_progressDialog, SLOT(slotAllTasksFinished())); - b &= connect(m_progressDialog, SIGNAL(signalAbortTask()), m_project->frameSource(), SLOT(slotAbortInitialization())); - Q_ASSERT(b); - } - m_progressDialog->show(); - m_progressDialog->slotNextTask(taskDescription, taskSize); -} -void MainWindow::slotFrameSourceTasksFinished() -{ - QTimer::singleShot(200, this, SLOT(slotCloseFrameSourceProgress())); -} -void MainWindow::slotCloseFrameSourceProgress() -{ - if (m_progressDialog != NULL) { - m_progressDialog->close(); - } -} - -
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/slowmoUI/mainwindow.h
Deleted
@@ -1,136 +0,0 @@ -/* -slowmoUI is a user interface for slowmoVideo. -Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. -*/ - -#ifndef MAINWINDOW_H -#define MAINWINDOW_H - -#include "canvas.h" -#include "frameMonitor.h" -#include "renderPreview.h" -#include "dialogues/flowExaminer.h" -#include "../project/project_sV.h" -#include "../libgui/combinedShortcuts.h" - -namespace Ui { - class MainWindow; -} - -#include <QtGui/QMainWindow> -#include <QtCore/QMap> -#include <QtCore/QList> -#include <QtCore/QTime> -#include <QtCore/QThread> -#include <QSettings> - -class Canvas; -class ProgressDialog; -class QShortcut; -class QSignalMapper; - -namespace Ui { - class MainWindow; -} - -/// \todo Call flow editor from here -class MainWindow : public QMainWindow -{ - Q_OBJECT - -public: - explicit MainWindow(QString projectPath = QString(), QWidget *parent = 0); - ~MainWindow(); - - void displayHelp(QPainter &davinci) const; - -protected slots: - virtual void closeEvent(QCloseEvent *e); - virtual bool eventFilter(QObject *obj, QEvent *e); - -private: - enum ShortcutCommands { - Quit, - Abort, - Abort_Selection, - Delete_Node, - Tool_Select, - Tool_Move, - Tag, - Help, - New, - Open, - Save_Same, - Save_As - }; - - Ui::MainWindow *ui; - QSettings m_settings; - - Project_sV *m_project; - QString m_projectPath; - - Canvas *m_wCanvas; - FrameMonitor *m_wInputMonitor; - FrameMonitor *m_wCurveMonitor; - QDockWidget *m_wInputMonitorDock; - QDockWidget *m_wCurveMonitorDock; - RenderPreview* m_wRenderPreview; - QDockWidget *m_wRenderPreviewDock; - QList<QAction*> m_widgetActions; - - ProgressDialog *m_progressDialog; - ProgressDialog *m_renderProgressDialog; - FlowExaminer *m_flowExaminer; - - - CombinedShortcuts m_cs; - - QThread m_rendererThread; - - - void loadProject(QString path); - void loadProject(Project_sV *project); - void resetDialogs(); - void updateWindowTitle(); - -private slots: - void slotShortcutUsed(int id); - void slotShowRenderDialog(); - void slotShowPreferencesDialog(); - void slotShowProjectPreferencesDialog(); - void slotShowFlowExaminerDialog(); - void slotForwardInputPosition(qreal frame); - void slotForwardCurveSrcPosition(qreal frame); - - void slotNewFrameSourceTask(const QString taskDescription, int taskSize); - void slotFrameSourceTasksFinished(); - void slotCloseFrameSourceProgress(); - - void slotRenderingAborted(QString message); - - void slotNewProject(); - void slotSaveProject(QString filename = ""); - void slotSaveProjectDialog(); - void slotLoadProjectDialog(); - - void slotToggleHelp(); - void slotShowAboutDialog(); - void slotUpdateRenderPreview(); - - -signals: - void deleteNodes(); - void setMode(const Canvas::ToolMode mode); - void abort(const Canvas::Abort abort); - void addTag(); - void signalRendererContinue(); - -}; - -#endif // MAINWINDOW_H
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/slowmoUI/mainwindow.ui
Deleted
@@ -1,155 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>MainWindow</class> - <widget class="QMainWindow" name="MainWindow"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>1000</width> - <height>700</height> - </rect> - </property> - <property name="windowTitle"> - <string>slowmoVideo UI</string> - </property> - <widget class="QWidget" name="centralWidget"/> - <widget class="QMenuBar" name="menuBar"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>1000</width> - <height>22</height> - </rect> - </property> - <widget class="QMenu" name="menuSlowmoVideo_UI"> - <property name="title"> - <string>&File</string> - </property> - <addaction name="actionNew"/> - <addaction name="actionOpen"/> - <addaction name="actionSave"/> - <addaction name="actionSave_as"/> - <addaction name="separator"/> - <addaction name="actionRender"/> - <addaction name="actionRenderPreview"/> - <addaction name="actionExamineFlow"/> - <addaction name="separator"/> - <addaction name="actionPreferences"/> - <addaction name="separator"/> - <addaction name="actionQuit"/> - <addaction name="separator"/> - </widget> - <widget class="QMenu" name="menuHelp"> - <property name="title"> - <string>&Help</string> - </property> - <addaction name="actionAbout"/> - <addaction name="actionShortcuts"/> - </widget> - <widget class="QMenu" name="menuView"> - <property name="title"> - <string>&View</string> - </property> - <addaction name="actionZoomIn"/> - <addaction name="actionZoomOut"/> - </widget> - <widget class="QMenu" name="menuProject"> - <property name="title"> - <string>&Project</string> - </property> - <addaction name="actionProjectPreferences"/> - </widget> - <addaction name="menuSlowmoVideo_UI"/> - <addaction name="menuProject"/> - <addaction name="menuView"/> - <addaction name="menuHelp"/> - </widget> - <widget class="QToolBar" name="mainToolBar"> - <attribute name="toolBarArea"> - <enum>TopToolBarArea</enum> - </attribute> - <attribute name="toolBarBreak"> - <bool>false</bool> - </attribute> - </widget> - <widget class="QStatusBar" name="statusBar"/> - <action name="actionRender"> - <property name="text"> - <string>&Render</string> - </property> - </action> - <action name="actionPreferences"> - <property name="text"> - <string>Preferences</string> - </property> - </action> - <action name="actionSave"> - <property name="text"> - <string>&Save</string> - </property> - </action> - <action name="actionSave_as"> - <property name="text"> - <string>Save &as …</string> - </property> - </action> - <action name="actionOpen"> - <property name="text"> - <string>&Open</string> - </property> - </action> - <action name="actionShortcuts"> - <property name="text"> - <string>&Shortcuts</string> - </property> - </action> - <action name="actionAbout"> - <property name="text"> - <string>&About</string> - </property> - </action> - <action name="actionQuit"> - <property name="text"> - <string>&Quit</string> - </property> - </action> - <action name="actionRenderPreview"> - <property name="text"> - <string>Render &preview</string> - </property> - </action> - <action name="actionExamineFlow"> - <property name="text"> - <string>E&xamine flow</string> - </property> - <property name="toolTip"> - <string>Examine flow at input frame</string> - </property> - </action> - <action name="actionNew"> - <property name="text"> - <string>&New …</string> - </property> - </action> - <action name="actionProjectPreferences"> - <property name="text"> - <string>&Preferences</string> - </property> - </action> - <action name="actionZoomIn"> - <property name="text"> - <string>Zoom &in</string> - </property> - </action> - <action name="actionZoomOut"> - <property name="text"> - <string>Zoom &out</string> - </property> - </action> - </widget> - <layoutdefault spacing="6" margin="11"/> - <resources/> - <connections/> -</ui>
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/slowmoUI/renderPreview.cpp
Deleted
@@ -1,99 +0,0 @@ -/* -slowmoUI is a user interface for slowmoVideo. -Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. -*/ - -#include "renderPreview.h" -#include "ui_renderPreview.h" -#include "project/emptyFrameSource_sV.h" -#include "project/project_sV.h" -#include "project/projectPreferences_sV.h" - -#include <QtCore> -#include <QtGui/QPainter> -#include <QtGui/QMainWindow> -#include <QtGui/QStatusBar> - -RenderPreview::RenderPreview(Project_sV *project, QWidget *parent) : - QWidget(parent), - ui(new Ui::RenderPreview), - m_project(project) -{ - ui->setupUi(this); - - m_parentMainWindow = dynamic_cast<QMainWindow*>(parentWidget()); - - ui->info->setVisible(m_parentMainWindow == NULL); - ui->info->clear(); - - - bool b = true; - b &= connect(&m_futureWatcher, SIGNAL(finished()), this, SLOT(slotUpdateImage())); -} - -RenderPreview::~RenderPreview() -{ - delete ui; -} - -void RenderPreview::load(Project_sV *project) -{ - m_project = project; -} - -void RenderPreview::notify(const QString message) -{ - if (m_parentMainWindow != NULL) { - m_parentMainWindow->statusBar()->showMessage(message, 5000); - } else { - ui->info->setText(message); - } -} - -void RenderPreview::slotRenderAt(qreal time) -{ - if (dynamic_cast<EmptyFrameSource_sV*>(m_project->frameSource()) != NULL) { - notify(tr("Cannot render preview, no frames loaded.")); - return; - } - if (m_project->nodes()->size() < 2) { - notify(tr("Cannot render preview at the curve position since no curve is available.")); - return; - } - if (time >= m_project->nodes()->startTime() && time <= m_project->nodes()->endTime()) { - notify(tr("Rendering preview at output time %1 s (might take some time) ...").arg(time)); - - if (m_future.isRunning()) { - notify(tr("Preview is still being rendered.")); - } else { - - RenderPreferences_sV prefs; - prefs.fps() = m_project->preferences()->renderFPS(); - prefs.interpolation = m_project->preferences()->renderInterpolationType(); - prefs.size = FrameSize_Orig; - - m_future = QtConcurrent::run(m_project, &Project_sV::render, time, prefs); - m_futureWatcher.setFuture(m_future); - if (m_future.isFinished()) { - qDebug() << "qFuture has already finished! Manually calling update."; - slotUpdateImage(); - } - } - } else { - notify(tr("Cannot render at output time %1 s; Not within the curve.").arg(time)); - } -} - -void RenderPreview::slotUpdateImage() -{ - qDebug() << "Updating preview image now. Saving as /tmp/renderPreview.jpg."; ///< \todo do not save anymore - ui->imageDisplay->loadImage(m_future.result()); - ui->imageDisplay->image().save("/tmp/renderPreview.jpg"); - repaint(); - notify(tr("Preview rendering finished.")); -}
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/slowmoUI/res
Deleted
-(directory)
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/test
Deleted
-(directory)
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/test/CMakeLists.txt
Deleted
@@ -1,22 +0,0 @@ -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99") -message(STATUS "CXX flags: ${CMAKE_CXX_FLAGS}") - -set(SRCS - test.cpp -) - -include_directories(${FFMPEG_INCLUDE_PATHS}) -add_executable(Test ${SRCS}) -target_link_libraries(Test sVproj ${EXTERNAL_LIBS}) - -add_executable(encodeTest encodeTest.c) -target_link_libraries(encodeTest sVencode ${EXTERNAL_LIBS}) - -add_executable(encodeFramesTest ffmpegTestEncodeFrames.cpp) -message(STATUS "Additional libraries: ${ADDITIONAL_LIBS}") -target_link_libraries(encodeFramesTest sVencode ${EXTERNAL_LIBS}) - -add_executable(AvconvInfo testAvconvInfo.cpp) -target_link_libraries(AvconvInfo sVinfo ${EXTERNAL_LIBS}) - -install(TARGETS Test DESTINATION bin)
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/test/encodeTest.c
Deleted
@@ -1,12 +0,0 @@ - -#include "../lib/ffmpegEncode_sV.h" - -int main() -{ - VideoOut_sV video; - prepareDefault(&video); - for (int i = 0; i < 50; i++) { - eatSample(&video); - } - finish(&video); -}
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/tr
Deleted
-(directory)
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/tr/slowmoVideo_fr.ts
Deleted
@@ -1,1435 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!DOCTYPE TS> -<TS version="2.0" language="fr_FR"> -<context> - <name>AboutDialog</name> - <message> - <location filename="../slowmoUI/dialogues/aboutDialog.ui" line="14"/> - <source>About</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/aboutDialog.ui" line="28"/> - <source>About slowmoVideo</source> - <translation type="unfinished"></translation> - </message> - <message utf8="true"> - <location filename="../slowmoUI/dialogues/aboutDialog.ui" line="41"/> - <source><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Bitstream Vera Sans'; font-size:10pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-style:italic;">slowmoVideo</span> is developed by Simon A. Eugster (aka. Granjow, co-author of Kdenlive) and licensed under GPLv3.</p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-style:italic;">slowmoVideo</span> allows to change the speed of a video clip based upon a curve. If the speed becomes higher than 1×, an exposure (shutter) effect simulates motion blur. For lower speed, frames are interpolated with optical flow.</p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Thanks for contributing:</p> -<ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Mirko Götze <span style=" font-style:italic;">&lt;mail@mgo80.de&gt;</span> for converting <span style=" font-weight:600;">Cg to GLSL</span> (Removing the nVidia dependency)</li> -<li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Morten Sylvest Olsen <span style=" font-style:italic;">&lt;mso@kapowsoftware.com&gt;</span> for the <span style=" font-weight:600;">V3D speedup</span> and removing the unnecessary window</li> -<li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Elias Vanderstuyft for displaying the <span style=" font-weight:600;">shutter function</span> on the canvas</li> -<li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Christian Frisson <span style=" font-style:italic;">&lt;christian.frisson@umons.ac.be&gt;</span> for<span style=" font-weight:600;"> OpenCV on MXE</span> (allowed me to compile slowmoVideo for Windows)</li> -<li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Per <span style=" font-style:italic;">&lt;per@stuffmatic.com&gt;</span> for the<span style=" font-weight:600;"> OpenCV</span> code (slowmoVideo can run on CPU only with it)</li></ul> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Visit <a href="http://slowmoVideo.granjow.net"><span style=" text-decoration: underline; color:#0057ae;">slowmoVideo.granjow.net</span></a> for more information.</p></body></html></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/aboutDialog.ui" line="133"/> - <source>(c) 2012 Simon A. Eugster</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/aboutDialog.cpp" line="23"/> - <source>Version %1, %2</source> - <translation type="unfinished"></translation> - </message> -</context> -<context> - <name>Canvas</name> - <message> - <location filename="../slowmoUI/canvas.ui" line="78"/> - <source>slowmoUI canvas</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/canvas.cpp" line="105"/> - <source>&Delete node</source> - <translation>Effacer le noeud</translation> - </message> - <message> - <location filename="../slowmoUI/canvas.cpp" line="106"/> - <source>&Snap in node</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/canvas.cpp" line="107"/> - <source>&Delete tag</source> - <translation>Effacer le tag</translation> - </message> - <message> - <location filename="../slowmoUI/canvas.cpp" line="108"/> - <source>&Rename tag</source> - <translation>Renomer le tag</translation> - </message> - <message> - <location filename="../slowmoUI/canvas.cpp" line="109"/> - <source>Set tag &time</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/canvas.cpp" line="118"/> - <source>&Linear curve</source> - <translation>Courbe Lineaire</translation> - </message> - <message utf8="true"> - <location filename="../slowmoUI/canvas.cpp" line="119"/> - <source>&Bézier curve</source> - <translation>Courbe de Bezier</translation> - </message> - <message> - <location filename="../slowmoUI/canvas.cpp" line="123"/> - <source>Set &custom speed</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/canvas.cpp" line="124"/> - <source>Set/edit shutter &function</source> - <translation type="unfinished"></translation> - </message> - <message utf8="true"> - <location filename="../slowmoUI/canvas.cpp" line="130"/> - <source>Set speed to %1×</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/canvas.cpp" line="135"/> - <source>Reset left handle</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/canvas.cpp" line="136"/> - <source>Reset right handle</source> - <translation type="unfinished"></translation> - </message> - <message utf8="true"> - <location filename="../slowmoUI/canvas.cpp" line="789"/> - <source>Segment replay &speed …</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/canvas.cpp" line="800"/> - <source>Node %1</source> - <translation>Noeud %1</translation> - </message> - <message> - <location filename="../slowmoUI/canvas.cpp" line="803"/> - <source>Handle actions</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/canvas.cpp" line="811"/> - <source>Segment between node %1 and %2</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/canvas.cpp" line="830"/> - <source>Tag %1</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/canvas.cpp" line="1078"/> - <source>New tag name</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/canvas.cpp" line="1078"/> - <source>Tag:</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/canvas.cpp" line="1087"/> - <source>New tag time</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/canvas.cpp" line="1087"/> - <source>Time:</source> - <translatorcomment>Temps</translatorcomment> - <translation></translation> - </message> - <message> - <location filename="../slowmoUI/canvas.cpp" line="1153"/> - <source>Replay speed for current segment</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/canvas.cpp" line="1153"/> - <source>Speed:</source> - <translation>Vitesse:</translation> - </message> -</context> -<context> - <name>FlowEditCanvas</name> - <message> - <location filename="../slowmoFlowEdit/flowEditCanvas.ui" line="77"/> - <source>Values at mouse position</source> - <translation>Valeurs à la position de la sourie</translation> - </message> -</context> -<context> - <name>FlowExaminer</name> - <message> - <location filename="../slowmoUI/dialogues/flowExaminer.ui" line="95"/> - <source>Close</source> - <translation>Fermer</translation> - </message> -</context> -<context> - <name>FrameMonitor</name> - <message> - <location filename="../slowmoUI/frameMonitor.ui" line="20"/> - <source>Input monitor</source> - <translation type="unfinished"></translation> - </message> -</context> -<context> - <name>ImageDisplay</name> - <message> - <location filename="../libgui/imageDisplay.cpp" line="28"/> - <source>Scale image to widget size</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../libgui/imageDisplay.cpp" line="32"/> - <source>Export image</source> - <translation>Exporter l'image</translation> - </message> - <message> - <location filename="../libgui/imageDisplay.cpp" line="241"/> - <source>Export render preview to image</source> - <translation type="unfinished"></translation> - </message> -</context> -<context> - <name>ImagesFrameSource_sV</name> - <message> - <location filename="../project/imagesFrameSource_sV.cpp" line="53"/> - <source>No images selected.</source> - <translation>Pas d'image selectionnée.</translation> - </message> - <message> - <location filename="../project/imagesFrameSource_sV.cpp" line="58"/> - <source>Image %1 is not of the same size (%2) as the first image (%3).</source> - <translation>L'image %1 n'est pas la même taile (%2) que la première image (%3).</translation> - </message> - <message> - <location filename="../project/imagesFrameSource_sV.cpp" line="94"/> - <source>Creating preview images from the input images</source> - <translation>Création des images de previsualisation à partir des images d'entrée</translation> - </message> - <message> - <location filename="../project/imagesFrameSource_sV.cpp" line="99"/> - <source>Resized image already exists for %1</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../project/imagesFrameSource_sV.cpp" line="101"/> - <source>Re-sizing image %1 to: -%2</source> - <translation type="unfinished"></translation> - </message> -</context> -<context> - <name>MainWindow</name> - <message> - <location filename="../slowmoFlowEdit/mainwindow.ui" line="14"/> - <source>slowmo Flow Editor</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoFlowEdit/mainwindow.ui" line="28"/> - <source>File</source> - <translation>Fichier</translation> - </message> - <message> - <location filename="../slowmoFlowEdit/mainwindow.ui" line="40"/> - <source>Help</source> - <translation>Aide</translation> - </message> - <message> - <location filename="../slowmoFlowEdit/mainwindow.ui" line="50"/> - <source>Open</source> - <translation>Ouvrir</translation> - </message> - <message> - <location filename="../slowmoFlowEdit/mainwindow.ui" line="55"/> - <location filename="../slowmoUI/mainwindow.cpp" line="131"/> - <source>Save</source> - <translation>Sauver</translation> - </message> - <message> - <location filename="../slowmoFlowEdit/mainwindow.ui" line="60"/> - <location filename="../slowmoUI/mainwindow.cpp" line="128"/> - <source>Quit</source> - <translation>Quitter</translation> - </message> - <message> - <location filename="../slowmoFlowEdit/mainwindow.ui" line="65"/> - <source>Next file</source> - <translation>Fichier suivant</translation> - </message> - <message> - <location filename="../slowmoFlowEdit/mainwindow.ui" line="70"/> - <source>Previous file</source> - <translation>Fichier précedent</translation> - </message> - <message> - <location filename="../slowmoFlowEdit/mainwindow.ui" line="78"/> - <source>Amplify colours</source> - <translation>Amplifier les couleurs</translation> - </message> - <message> - <location filename="../slowmoFlowEdit/mainwindow.ui" line="83"/> - <source>Shortcuts</source> - <translation>Racourcits</translation> - </message> - <message> - <location filename="../slowmoUI/mainwindow.ui" line="14"/> - <source>slowmoVideo UI</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/mainwindow.ui" line="28"/> - <source>&File</source> - <translation>&Fichier</translation> - </message> - <message> - <location filename="../slowmoUI/mainwindow.ui" line="46"/> - <source>&Help</source> - <translation>&Aide</translation> - </message> - <message> - <location filename="../slowmoUI/mainwindow.ui" line="53"/> - <source>&View</source> - <translation type="unfinished">&Vue</translation> - </message> - <message> - <location filename="../slowmoUI/mainwindow.ui" line="60"/> - <source>&Project</source> - <translation>&Projet</translation> - </message> - <message> - <location filename="../slowmoUI/mainwindow.ui" line="80"/> - <source>&Render</source> - <translation>&Rendu</translation> - </message> - <message> - <location filename="../slowmoUI/mainwindow.ui" line="85"/> - <source>Preferences</source> - <translation>Préferences</translation> - </message> - <message> - <location filename="../slowmoUI/mainwindow.ui" line="90"/> - <source>&Save</source> - <translation>&Sauver</translation> - </message> - <message utf8="true"> - <location filename="../slowmoUI/mainwindow.ui" line="95"/> - <source>Save &as …</source> - <translation>Sauver &comme</translation> - </message> - <message> - <location filename="../slowmoUI/mainwindow.ui" line="100"/> - <source>&Open</source> - <translation>&Ouvrir</translation> - </message> - <message> - <location filename="../slowmoUI/mainwindow.ui" line="105"/> - <source>&Shortcuts</source> - <translation>&Raccourcits</translation> - </message> - <message> - <location filename="../slowmoUI/mainwindow.ui" line="110"/> - <source>&About</source> - <translation>&A propos</translation> - </message> - <message> - <location filename="../slowmoUI/mainwindow.ui" line="115"/> - <source>&Quit</source> - <translation>&Quiter</translation> - </message> - <message> - <location filename="../slowmoUI/mainwindow.ui" line="120"/> - <source>Render &preview</source> - <translation>Generer une &prévisualisation</translation> - </message> - <message> - <location filename="../slowmoUI/mainwindow.ui" line="125"/> - <source>E&xamine flow</source> - <translation>E&xaminer le flux</translation> - </message> - <message> - <location filename="../slowmoUI/mainwindow.ui" line="128"/> - <source>Examine flow at input frame</source> - <translation type="unfinished"></translation> - </message> - <message utf8="true"> - <location filename="../slowmoUI/mainwindow.ui" line="133"/> - <source>&New …</source> - <translation>&Nouveau</translation> - </message> - <message> - <location filename="../slowmoUI/mainwindow.ui" line="138"/> - <source>&Preferences</source> - <translation>&Préférences</translation> - </message> - <message> - <location filename="../slowmoUI/mainwindow.ui" line="143"/> - <source>Zoom &in</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/mainwindow.ui" line="148"/> - <source>Zoom &out</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/mainwindow.cpp" line="66"/> - <source>Input monitor</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/mainwindow.cpp" line="72"/> - <source>Curve monitor</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/mainwindow.cpp" line="78"/> - <source>Render preview</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/mainwindow.cpp" line="127"/> - <source>Show help overlay</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/mainwindow.cpp" line="129"/> - <source>New project</source> - <translation>Nouveau projet</translation> - </message> - <message> - <location filename="../slowmoUI/mainwindow.cpp" line="130"/> - <source>Open project</source> - <translation>Ouvrir un projet</translation> - </message> - <message> - <location filename="../slowmoUI/mainwindow.cpp" line="132"/> - <source>Save as ...</source> - <translation>Sauver comme</translation> - </message> - <message> - <location filename="../slowmoUI/mainwindow.cpp" line="133"/> - <source>Abort move</source> - <translation>Annuler le mouvement</translation> - </message> - <message> - <location filename="../slowmoUI/mainwindow.cpp" line="134"/> - <source>Unselect all</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/mainwindow.cpp" line="135"/> - <source>Delete selected nodes</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/mainwindow.cpp" line="136"/> - <source>Selecting tool</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/mainwindow.cpp" line="137"/> - <source>Move tool</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/mainwindow.cpp" line="138"/> - <source>Insert label (tag)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/mainwindow.cpp" line="335"/> - <source>Load Project</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/mainwindow.cpp" line="335"/> - <location filename="../slowmoUI/mainwindow.cpp" line="386"/> - <source>slowmoVideo projects (*.sVproj)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/mainwindow.cpp" line="351"/> - <source>Warning</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/mainwindow.cpp" line="356"/> - <source>Frame source error</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/mainwindow.cpp" line="358"/> - <location filename="../slowmoUI/mainwindow.cpp" line="556"/> - <source>Error</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/mainwindow.cpp" line="369"/> - <source>No filename given, won't save. (Perhaps an empty project?)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/mainwindow.cpp" line="375"/> - <source>Saved project as: %1</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/mainwindow.cpp" line="377"/> - <source>Error writing project file</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/mainwindow.cpp" line="383"/> - <source>Save project</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/mainwindow.cpp" line="405"/> - <source> -Navigation: Shift Scroll, Drag</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/mainwindow.cpp" line="406"/> - <source> -Move nodes: Ctrl Drag</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/mainwindow.cpp" line="444"/> - <source>empty project</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/mainwindow.cpp" line="529"/> - <source>Rendering progress</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/mainwindow.cpp" line="563"/> - <source>Frame extraction progress</source> - <translation type="unfinished"></translation> - </message> -</context> -<context> - <name>NewProjectDialog</name> - <message> - <location filename="../slowmoUI/dialogues/newProjectDialog.ui" line="14"/> - <source>New slowmo Project</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/newProjectDialog.ui" line="23"/> - <location filename="../slowmoUI/dialogues/newProjectDialog.ui" line="92"/> - <location filename="../slowmoUI/dialogues/newProjectDialog.ui" line="157"/> - <source>Browse</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/newProjectDialog.ui" line="45"/> - <source>Abort</source> - <translation>Annuler</translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/newProjectDialog.ui" line="58"/> - <source>Ok</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/newProjectDialog.ui" line="70"/> - <source>Directory will be created</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/newProjectDialog.ui" line="83"/> - <source>Video source</source> - <translation>Source du Media</translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/newProjectDialog.ui" line="99"/> - <source>Video information:</source> - <translation>Information du Media</translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/newProjectDialog.ui" line="128"/> - <source>Input video</source> - <translation>Video en entrée</translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/newProjectDialog.ui" line="138"/> - <source>Image source</source> - <translation>Source d'image</translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/newProjectDialog.ui" line="150"/> - <source>Input images</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/newProjectDialog.ui" line="164"/> - <source>Images information:</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/newProjectDialog.ui" line="186"/> - <source>Video file</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/newProjectDialog.ui" line="193"/> - <source>Images</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/newProjectDialog.ui" line="234"/> - <source>Project Directory</source> - <translation>Répertoire du projet</translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/newProjectDialog.ui" line="247"/> - <source>Project Filename</source> - <translation>Nom du projet</translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/newProjectDialog.ui" line="257"/> - <source>.sVproj</source> - <translation></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/newProjectDialog.ui" line="264"/> - <source>You should preferredly use an empty directory here. Each project needs its own project directory.</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/newProjectDialog.ui" line="274"/> - <source>The project will be saved to this file right after confirming this dialog.</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/newProjectDialog.cpp" line="91"/> - <source>Select input video file</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/newProjectDialog.cpp" line="112"/> - <source>Character %1 is not an ASCII character. This file path will likely not work with ffmpeg.</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/newProjectDialog.cpp" line="123"/> - <source>Select input images</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/newProjectDialog.cpp" line="146"/> - <source>Select a project directory</source> - <translation type="unfinished"></translation> - </message> - <message utf8="true"> - <location filename="../slowmoUI/dialogues/newProjectDialog.cpp" line="165"/> - <source>Number of video streams: %1 -Frames: %2 -Size: %3×%4 -</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/newProjectDialog.cpp" line="168"/> - <source>Frame rate: %1/%2</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/newProjectDialog.cpp" line="172"/> - <source>No video stream detected.</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/newProjectDialog.cpp" line="217"/> - <source>Image size: %1</source> - <translation type="unfinished"></translation> - </message> -</context> -<context> - <name>PreferencesDialog</name> - <message> - <location filename="../slowmoUI/dialogues/preferencesDialog.ui" line="14"/> - <source>slowmoUI preferences</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/preferencesDialog.ui" line="22"/> - <source>Binary locations</source> - <translation>Localisation des executables</translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/preferencesDialog.ui" line="31"/> - <location filename="../slowmoUI/dialogues/preferencesDialog.ui" line="55"/> - <source>Browse</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/preferencesDialog.ui" line="67"/> - <source>Flow method</source> - <translation>Méthode d'évaluation du flux optique</translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/preferencesDialog.ui" line="73"/> - <source>GPU, V3D (requires flowBuilder and a video card)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/preferencesDialog.ui" line="80"/> - <source>CPU, OpenCV</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/preferencesDialog.ui" line="121"/> - <source>Cancel</source> - <translation>Annuler</translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/preferencesDialog.ui" line="128"/> - <source>Ok</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/preferencesDialog.cpp" line="20"/> - <source>flowBuilder binary location</source> - <translation>localisation de l'executable flowBuilder</translation> - </message> -</context> -<context> - <name>ProgressDialog</name> - <message> - <location filename="../slowmoUI/dialogues/progressDialog.ui" line="14"/> - <source>Progress</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/progressDialog.ui" line="28"/> - <source>Current Task</source> - <translation>Tache courante</translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/progressDialog.ui" line="42"/> - <source>Task Description</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/progressDialog.ui" line="82"/> - <source>Abort</source> - <translation>Annuler</translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/progressDialog.ui" line="89"/> - <source>Ok</source> - <translation>Ok</translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/progressDialog.cpp" line="40"/> - <location filename="../slowmoUI/dialogues/progressDialog.cpp" line="41"/> - <source>(Finished) </source> - <translation>(Finit)</translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/progressDialog.cpp" line="62"/> - <source>Aborted</source> - <translation>Annulé</translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/progressDialog.cpp" line="73"/> - <source>Task finished in %1.</source> - <translation>Tache terminé en %1.</translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/progressDialog.cpp" line="75"/> - <source>Task finished.</source> - <translation>Tache terminé.</translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/progressDialog.cpp" line="77"/> - <source>(Finished) %1</source> - <translation>(Fini) %1</translation> - </message> -</context> -<context> - <name>ProjectPreferencesDialog</name> - <message> - <location filename="../slowmoUI/dialogues/projectPreferencesDialog.ui" line="14"/> - <source>Dialog</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/projectPreferencesDialog.ui" line="22"/> - <source>FPS value to use for calculating the output frame (display only)</source> - <translation type="unfinished"></translation> - </message> -</context> -<context> - <name>Project_sV</name> - <message> - <location filename="../project/project_sV.cpp" line="249"/> - <source>Empty frame source; Cannot build flow.</source> - <translation type="unfinished"></translation> - </message> -</context> -<context> - <name>QObject</name> - <message> - <location filename="../lib/defs_sV.cpp" line="38"/> - <source>Orig</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../lib/defs_sV.cpp" line="40"/> - <source>Small</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../lib/defs_sV.cpp" line="43"/> - <source>Unknown size</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../lib/defs_sV.cpp" line="51"/> - <source>Forward</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../lib/defs_sV.cpp" line="53"/> - <source>Backward</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../lib/defs_sV.cpp" line="56"/> - <source>Unknown direction</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../lib/defs_sV.cpp" line="64"/> - <source>Linear</source> - <translation type="unfinished"></translation> - </message> - <message utf8="true"> - <location filename="../lib/defs_sV.cpp" line="66"/> - <source>Bézier</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../lib/defs_sV.cpp" line="69"/> - <source>Unknown curve type</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../lib/defs_sV.cpp" line="82"/> - <source>Source axis</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../lib/defs_sV.cpp" line="84"/> - <source>Output axis</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../lib/defs_sV.cpp" line="87"/> - <source>Unknown axis</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../lib/defs_sV.cpp" line="95"/> - <source>Forward interpolation (fast)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../lib/defs_sV.cpp" line="97"/> - <source>Forward interpolation (accurate)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../lib/defs_sV.cpp" line="99"/> - <source>Two-way interpolation (fast)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../lib/defs_sV.cpp" line="101"/> - <source>Two-way interpolation (accurate)</source> - <translation type="unfinished"></translation> - </message> - <message utf8="true"> - <location filename="../lib/defs_sV.cpp" line="103"/> - <source>Bézier interpolation</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../lib/defs_sV.cpp" line="106"/> - <source>Unknown interpolation</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../lib/defs_sV.cpp" line="114"/> - <source>Stacking</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../lib/defs_sV.cpp" line="116"/> - <source>Convolution</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../lib/defs_sV.cpp" line="118"/> - <source>Nearest (no blurring)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../project/interpolator_sV.cpp" line="13"/> - <source>Requested frame %1: Not within valid range. (%2 frames)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../project/motionBlur_sV.cpp" line="90"/> - <source>Range too small: Start frame is %1, end frame is %2. Using normal interpolation.</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../project/videoRenderTarget_sV.cpp" line="61"/> - <source>Video could not be prepared (error code %1). -%2</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../project/xmlProjectRW_sV.cpp" line="159"/> - <source>Cannot write to %1; please check if you have write permissions.</source> - <translation type="unfinished"></translation> - </message> - <message utf8="true"> - <location filename="../project/xmlProjectRW_sV.cpp" line="305"/> - <source>Unknown frame source “%1”. Cannot load the project.</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../project/xmlProjectRW_sV.cpp" line="314"/> - <source>Cannot read from file %1. (Opening in read-only mode failed.)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../project/xmlProjectRW_sV.cpp" line="321"/> - <source>Invalid project file: %1</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/canvasTools.cpp" line="39"/> - <source>%1 s</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/canvasTools.cpp" line="41"/> - <source>%1 min %2 s</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/canvasTools.cpp" line="45"/> - <source> -Frame %1</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/canvasTools.cpp" line="75"/> - <source>%1 %</source> - <translation type="unfinished"></translation> - </message> -</context> -<context> - <name>RenderPreview</name> - <message> - <location filename="../slowmoUI/renderPreview.ui" line="14"/> - <source>Render preview</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/renderPreview.ui" line="51"/> - <source>This is an information message.</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/renderPreview.cpp" line="61"/> - <source>Cannot render preview, no frames loaded.</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/renderPreview.cpp" line="65"/> - <source>Cannot render preview at the curve position since no curve is available.</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/renderPreview.cpp" line="69"/> - <source>Rendering preview at output time %1 s (might take some time) ...</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/renderPreview.cpp" line="72"/> - <source>Preview is still being rendered.</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/renderPreview.cpp" line="88"/> - <source>Cannot render at output time %1 s; Not within the curve.</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/renderPreview.cpp" line="98"/> - <source>Preview rendering finished.</source> - <translation type="unfinished"></translation> - </message> -</context> -<context> - <name>RenderTask_sV</name> - <message> - <location filename="../project/renderTask_sV.cpp" line="102"/> - <source>Rendering aborted.</source> - <translation type="unfinished"></translation> - </message> - <message utf8="true"> - <location filename="../project/renderTask_sV.cpp" line="110"/> - <source>Rendering Slow-Mo …</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../project/renderTask_sV.cpp" line="121"/> - <source>No rendering target given! Aborting rendering.</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../project/renderTask_sV.cpp" line="126"/> - <source>Empty frame source, cannot be rendered.</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../project/renderTask_sV.cpp" line="143"/> - <source>Rendering frame %1 @ %2 s from input position: %3 s (frame %4)</source> - <translation type="unfinished"></translation> - </message> -</context> -<context> - <name>RenderingDialog</name> - <message> - <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="14"/> - <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="46"/> - <source>Rendering settings</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="40"/> - <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="43"/> - <source>a</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="54"/> - <source>Full Project</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="64"/> - <source>Tag section</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="71"/> - <source>Custom section</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="116"/> - <source>to</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="192"/> - <source>Frames per second:</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="284"/> - <source>Size:</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="310"/> - <source>Interpolation:</source> - <translation type="unfinished"></translation> - </message> - <message utf8="true"> - <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="340"/> - <source>For two frames A and B, the two-way interpolations calculate both the flows A→B and B→A, which leads to smoother transitions between them. Forward interpolations only calculate A→B; Twice as fast, but usually less smooth.</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="366"/> - <source>Optical Flow</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="372"/> - <source>Optical flow</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="380"/> - <source>buildFlow lambda</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="428"/> - <source>Use a higher value for high-quality footage and larger images.</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="445"/> - <source>The lambda is only used with the GPU based Optical Flow algorithm. There is no general rule which value is best, so it is usually a good idea to render a short part with a low (5) and a high (50) lambda to see the differences, and then try to find the best value between.</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="474"/> - <source>Motion Blur</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="480"/> - <source>Motion blur</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="486"/> - <source>Motion blur will only be applied for segments on which it is enabled.</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="496"/> - <source>Stacking blur (Uses more disk space, but is faster for repeated rendering.)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="505"/> - <source>Maximum samples</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="538"/> - <source>Samples for slow motion</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="570"/> - <source>Convolution blur (Smoother than stacking, usually the better choice.)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="577"/> - <source>Nearest (no blurring)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="601"/> - <source>Output</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="609"/> - <source>Target:</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="619"/> - <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="711"/> - <source>Video</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="626"/> - <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="651"/> - <source>Images</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="657"/> - <source>The %1 in the filename pattern is mandatory and will be replaced by the frame number.</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="666"/> - <source>Output directory</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="676"/> - <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="739"/> - <source>Browse</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="683"/> - <source>Filename pattern</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="693"/> - <source>rendered-%1.jpg</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="717"/> - <source>Videos will be encoded with ffmpeg. If additional arguments are left empty, defaults will be used. The video format is determined by ffmpeg according to the file suffix.</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="729"/> - <source>Output file</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="746"/> - <source>Optional arguments</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="806"/> - <source>Will *not* save the project!</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="809"/> - <source>&Save settings</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="816"/> - <source>&Abort</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="823"/> - <source>&Ok</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/renderingDialog.cpp" line="94"/> - <source>Original size</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/renderingDialog.cpp" line="95"/> - <source>Small</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/renderingDialog.cpp" line="244"/> - <source><Start></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/renderingDialog.cpp" line="249"/> - <source><End></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/renderingDialog.cpp" line="360"/> - <source>Start time must be < end time!</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/renderingDialog.cpp" line="363"/> - <source>Rendering from %1 s to %2 s.</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/renderingDialog.cpp" line="398"/> - <source>Output directory for rendered images</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/renderingDialog.cpp" line="410"/> - <source>Output video file</source> - <translation type="unfinished"></translation> - </message> -</context> -<context> - <name>ShortcutListDialog</name> - <message> - <location filename="../slowmoFlowEdit/shortcutListDialog.ui" line="20"/> - <source>Flow Editor shortcuts</source> - <translation type="unfinished"></translation> - </message> -</context> -<context> - <name>ShutterFunctionDialog</name> - <message> - <location filename="../slowmoUI/dialogues/shutterFunctionDialog.ui" line="14"/> - <source>Shutter Functions</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/shutterFunctionDialog.ui" line="22"/> - <source><</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/shutterFunctionDialog.ui" line="29"/> - <source>Segment %1</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/shutterFunctionDialog.ui" line="36"/> - <source>></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/shutterFunctionDialog.ui" line="70"/> - <source>+</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/shutterFunctionDialog.ui" line="77"/> - <source>-</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/shutterFunctionDialog.ui" line="100"/> - <source>shutterFunc1</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/shutterFunctionDialog.ui" line="123"/> - <location filename="../slowmoUI/dialogues/shutterFunctionDialog.cpp" line="184"/> - <source>Used: %1 times</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/shutterFunctionDialog.ui" line="164"/> - <source>// header -(function foo(args...) {</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/shutterFunctionDialog.ui" line="202"/> - <source>return 0;</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/shutterFunctionDialog.ui" line="215"/> - <source>// footer -})</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/shutterFunctionDialog.ui" line="230"/> - <source><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Bitstream Vera Sans'; font-size:10pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Math functions are available in the Math namespace:</p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Monospace';">Math.PI, Math.cos(...), Math.pow(base. exponent) etc.</span></p> -</body></html></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/shutterFunctionDialog.ui" line="293"/> - <source>Close</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/shutterFunctionDialog.cpp" line="95"/> - <source>Segment %1 (total number: %2)</source> - <translation type="unfinished"></translation> - </message> -</context> -<context> - <name>TagAddDialog</name> - <message> - <location filename="../slowmoUI/dialogues/tagAddDialog.ui" line="14"/> - <source>Add tag</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/tagAddDialog.ui" line="20"/> - <source>Change the tag type with Arrows up/down.</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/tagAddDialog.ui" line="45"/> - <source>Source Tag</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/tagAddDialog.ui" line="65"/> - <source>Output Tag</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/tagAddDialog.ui" line="154"/> - <source>Abort</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../slowmoUI/dialogues/tagAddDialog.ui" line="161"/> - <source>Ok</source> - <translation type="unfinished"></translation> - </message> -</context> -<context> - <name>VideoFrameSource_sV</name> - <message> - <location filename="../project/videoFrameSource_sV.cpp" line="30"/> - <source>Video file %1 does not exist!</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../project/videoFrameSource_sV.cpp" line="38"/> - <source>Video is invalid, no streams found in %1</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../project/videoFrameSource_sV.cpp" line="175"/> - <source>ffmpeg/avconv executable not found! Cannot load video. -(It is also possible that it took a little long to respond due to high workload, so you might want to try again.) -Please download the 32-bit static ffmpeg build from ffmpeg.zeranoe.com and extract ffmpeg.exe in the same directory as slowmoUI.exe.</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../project/videoFrameSource_sV.cpp" line="188"/> - <source>Extracting thumbnail-sized frames from the video file</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../project/videoFrameSource_sV.cpp" line="213"/> - <source>Extracting original-sized frames from the video file</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../project/videoFrameSource_sV.cpp" line="269"/> - <source>Frame %1 of %2</source> - <translation type="unfinished"></translation> - </message> -</context> -</TS>
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/unittests
Deleted
-(directory)
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/unittests/CMakeLists.txt
Deleted
@@ -1,30 +0,0 @@ - -set(SRCS - testFlowRW_sV.cpp - testFlowField_sV.cpp - testVector_sV.cpp - testIntMatrix_sV.cpp - testXmlProjectRW_sV.cpp - testDefs_sV.cpp - testShutterFunction_sV.cpp - testProject_sV.cpp - testNodeList_sV.cpp - testAll.cpp -) -set(SRCS_MOC - testFlowRW_sV.h - testFlowField_sV.h - testVector_sV.h - testIntMatrix_sV.h - testDefs_sV.h - testShutterFunction_sV.h - testXmlProjectRW_sV.h - testNodeList_sV.h - testProject_sV.h -) - -qt4_wrap_cpp(MOC_OUT ${SRCS_MOC}) - -include_directories(${FFMPEG_INCLUDE_PATHS}) -add_executable(UnitTests ${SRCS} ${MOC_OUT}) -target_link_libraries(UnitTests sVproj ${EXTERNAL_LIBS})
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/unittests/testFlowField_sV.cpp
Deleted
@@ -1,97 +0,0 @@ -#include "testFlowField_sV.h" -#include "../lib/flowField_sV.h" -#include "../lib/flowTools_sV.h" - -#include <iostream> - -void TestFlowField_sV::slotTestConstructorOpenGL() -{ - const int width = 2; - const int height = 2; - - FlowField_sV field(width, height); - for (int i = 0; i < 2*width*height; i++) { - field.data()i = i; - } - - float *glData = new float3*width*height; - float *pData = glData; - for (int i = 0; i < width*height; i++) { - *(pData++) = field.data()2*i+0; - *(pData++) = field.data()2*i+1; - pData++; - } - - FlowField_sV *glField = new FlowField_sV(width, height, glData, FlowField_sV::GLFormat_RGB); - - QVERIFY(field == *glField); - - delete glData; - delete glField; -} - -void TestFlowField_sV::slotTestGaussKernel() -{ - Kernel_sV kernel(2,2); - kernel.gauss(); - std::cout << kernel; - QVERIFY(fabs(kernel(0,0)-1) < .001); - QVERIFY(fabs(kernel(-1,-1)-.135) < .001); - QVERIFY(kernel(-1,-1) == kernel(1,1)); - - kernel = Kernel_sV(3,1); - kernel.gauss(); - std::cout << kernel; - QVERIFY(fabs(kernel(0,0)-1) < .001); - QVERIFY(fabs(kernel(-3,-1)) < .001); - -} - -void TestFlowField_sV::slotTestMedian() -{ - int *values = new int4; - - values0 = 0; values1 = 0; - values2 = 0; values3 = 2; - FlowField_sV f1(2,2); - initFlowField(&f1, values); - - values0 = 0; values1 = 1; - values2 = 0; values3 = 1; - FlowField_sV f2(2,2); - initFlowField(&f2, values); - - values0 = 0; values1 = 2; - values2 = 1; values3 = 0; - FlowField_sV f3(2,2); - initFlowField(&f3, values); - - FlowField_sV *outField = FlowTools_sV::median(&f1, &f2, &f3); - - values0 = 0; values1 = 1; - values2 = 0; values3 = 1; - - QVERIFY(outField->x(0,0) == values0); - QVERIFY(outField->x(1,0) == values1); - QVERIFY(outField->x(0,1) == values2); - QVERIFY(outField->x(1,1) == values3); - QVERIFY(outField->y(0,0) == values0); - QVERIFY(outField->y(1,0) == values1); - QVERIFY(outField->y(0,1) == values2); - QVERIFY(outField->y(1,1) == values3); - - delete values; - delete outField; -} - -void TestFlowField_sV::initFlowField(FlowField_sV *field, int *values) -{ - int c = 0; - for (int y = 0; y < field->height(); y++) { - for (int x = 0; x < field->width(); x++) { - field->rx(x,y) = valuesc; - field->ry(x,y) = valuesc; - c++; - } - } -}
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/unittests/testFlowRW_sV.cpp
Deleted
@@ -1,57 +0,0 @@ -#include "testFlowRW_sV.h" - -#include "../lib/flowRW_sV.h" -#include "../lib/flowField_sV.h" -#include <QDebug> -#include <string> - -void TestFlowRW_sV::testWriteAndRead() -{ - const std::string filename("/tmp/unittestFlowField_sV.sVflow"); - - const int width = 3; - const int height = 2; - FlowField_sV *field = new FlowField_sV(width, height); - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - field->setX(x, y, x/float(y+1)); - field->setY(x, y, x/float(y+2)); - } - } - FlowRW_sV::save(filename, field); - - FlowField_sV *loadedField = FlowRW_sV::load(filename); - - QVERIFY(*field == *loadedField); - - delete field; - delete loadedField; -} -void TestFlowRW_sV::testWriteAndReadFail() -{ - const std::string filename("/tmp/unittestFlowField_sV.sVflow"); - - const int width = 3; - const int height = 2; - FlowField_sV *field = new FlowField_sV(width, height); - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - field->setX(x, y, x/float(y+1)); - field->setY(x, y, x/float(y+2)); - } - } - FlowRW_sV::save(filename, field); - - - - field->setX(width-1, height-1, -3.1415927); - FlowField_sV *loadedField = FlowRW_sV::load(filename); - - qDebug() << "Equal? " << (field->x(width-1, height-1) == loadedField->x(width-1, height-1)); - - QVERIFY( !( *field == *loadedField ) ); - - delete field; - delete loadedField; -} -
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/visualizeFlow
Deleted
-(directory)
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/visualizeFlow/CMakeLists.txt
Deleted
@@ -1,11 +0,0 @@ - -include_directories(..) - -set(SRCS - visualizeFlow.cpp -) - -add_executable(slowmoVisualizeFlow ${SRCS}) -target_link_libraries(slowmoVisualizeFlow sVvis ${EXTERNAL_LIBS}) - -install(TARGETS slowmoVisualizeFlow DESTINATION ${DEST})
View file
slowmoVideo-0.4.tar.gz/src/slowmoVideo/visualizeFlow/visualizeFlow.cpp
Deleted
@@ -1,123 +0,0 @@ -/* -slowmoVideo creates slow-motion videos from normal-speed videos. -Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. -*/ - - -#include "lib/flowRW_sV.h" -#include "lib/flowVisualization_sV.h" -#include "lib/flowTools_sV.h" - -#include <QImage> -#include <QtCore/QDebug> - -#include <iostream> - -char *myName; - -void printUsage() { - std::cout << "Usage: " << std::endl; - std::cout << "\t" << myName << " <flow data> <output image>" << std::endl; - std::cout << "\t" << myName << " diff <flow1> <flow2> <output image>" << std::endl; - std::cout << "\t" << myName << " ref (writes an HSV reference image)" << std::endl; -} - -QImage reference() { - const int width = 1024, height = 1024; - float cX = width/2.0; - float cY = height/2.0; - - FlowField_sV field(width, height); - - for (int x = 0; x < width; x++) { - for (int y = 0; y < height; y++) { - field.setX(x,y, x-cX); - field.setY(x,y, y-cY); - } - } - - return FlowVisualization_sV::colourizeFlow(&field, FlowVisualization_sV::HSV, 1.0); -} - -void colourizeFlow(int argc, char *argv) -{ - if (argc <= 2) { - printUsage(); - exit(-1); - } - std::string inputFile = argv1; - QString outputFile(argv2); - - FlowField_sV *flowField; - try { - flowField = FlowRW_sV::load(inputFile); - } catch (FlowRW_sV::FlowRWError &err) { - std::cout << err.message << std::endl; - exit(-2); - } - - std::cout << "Flow file loaded. Width: " << flowField->width() << ", height: " << flowField->height() << std::endl; - - /// \todo make visualization type configurable - QImage img = FlowVisualization_sV::colourizeFlow(flowField, FlowVisualization_sV::WXY); - - std::cout << "Saving " << outputFile.toStdString() << " ..." << std::endl; - img.save(outputFile); - - delete flowField; -} - -void diffFlow(int argc, char *argv) -{ - if (argc <= 4) { - printUsage(); - exit(-1); - } - FlowField_sV *leftFlow = FlowRW_sV::load(argv2); - FlowField_sV *rightFlow = FlowRW_sV::load(argv3); - FlowField_sV flowDifference(leftFlow->width(), leftFlow->height()); - - if (strcmp("diffSigned", argv1) == 0) { - FlowTools_sV::signedDifference(*leftFlow, *rightFlow, flowDifference); - } else { - FlowTools_sV::difference(*leftFlow, *rightFlow, flowDifference); - } - - int d; - QImage img(flowDifference.width(), flowDifference.height(), QImage::Format_ARGB32); - for (int y = 0; y < img.height(); y++) { - for (int x = 0; x < img.width(); x++) { - d = 128 + flowDifference.x(x,y)+flowDifference.y(x,y); - if (d > 255) { d = 255; } - if (d < 0) { d = 0; } - img.setPixel(x, y, qRgb(d,d,d)); - } - } - img.save(argv4); - - delete leftFlow; - delete rightFlow; -} - -int main(int argc, char *argv) -{ - myName = argv0; - - if (argc <= 1) { - printUsage(); - exit(-1); - } - - if (strcmp("diff", argv1) == 0 || strcmp("diffSigned", argv1) == 0) { - diffFlow(argc, argv); - } else if (strcmp("ref", argv1) == 0) { - reference().save("reference.png"); - } else { - colourizeFlow(argc, argv); - } -}
View file
slowmoVideo-0.6.tar.xz/.gitmodules
Added
@@ -0,0 +1,3 @@ +submodule "src/lib/libsvflow" + path = src/lib/libsvflow + url = ../libsvflow.git
View file
slowmoVideo-0.6.tar.xz/.travis.yml
Added
@@ -0,0 +1,37 @@ +# +# Copyright (c) 2016 +# travis CI config for slowmovideo check/test + +# for Ubuntu 14.04 Trusty +sudo: required +dist: trusty +cache: apt + +# Enable C++ support +language: cpp + +# Compiler selection +compiler: + - gcc + +env: + - OpenCV=2 + - OpenCV=3 + +before_install: + - export DISPLAY=:99.0 + - sh -e /etc/init.d/xvfb start + +#install necessary Qt files +install: + - sudo apt-get install -y qttools5-dev-tools libopencv-dev qtbase5-dev qtscript5-dev qtdeclarative5-dev + +before_script: + - mkdir build + - cd build + - cmake ../src -DENABLE_TESTS=TRUE + +# Build steps +script: + - make + - ./slowmoVideo/unittests/UnitTests
View file
slowmoVideo-0.4.tar.gz/CMakeLists.txt -> slowmoVideo-0.6.tar.xz/CMakeLists.txt
Changed
@@ -1,6 +1,255 @@ -message("==========================================================") -message("This CMake file is only here to give you this information:") -message("* To build slowmoVideo use the CMakeLists.txt file in the slowmoVideo subdirectory (inside the main directory).") -message("* To build flowBuilder (runs on nVidia GPUs) run cmake in the V3D subdirectory. (A CPU version is included in slowmoVideo and flowBuilder is not necessary anymore.)") -message("==========================================================") -message(FATAL_ERROR "Aborting therefore.") +cmake_minimum_required(VERSION 3.1) + +project(slowmoVideo) +if(CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR) + message(FATAL_ERROR "In-source builds are not allowed.") +endif() + +set(CMAKE_CXX_STANDARD 14) + +# Partly from https://doc.qt.io/qt-5/cmake-get-started.html#build-a-gui-executable +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) +set(CMAKE_AUTOUIC ON) +if(CMAKE_VERSION VERSION_LESS "3.7.0") + set(CMAKE_INCLUDE_CURRENT_DIR ON) +endif() + + +set(CMAKE_MODULE_PATH + ${slowmoVideo_SOURCE_DIR}/cmake +) + +# Make a version file containing the current version from git. +# +include(GetGitRevisionDescription) +git_describe(VERSION --dirty=-dev) + +if (VERSION MATCHES "^v(0-9+)\\.(0-9+)(\\.(0-9+))?(-a-zA-Z0-9+)?$") + string(REGEX REPLACE "^v(0-9+)\\.(0-9+)(\\.(0-9+))?(-a-zA-Z0-9+)?$" "\\1" PROJECT_VERSION_MAJOR "${VERSION}") + string(REGEX REPLACE "^v(0-9+)\\.(0-9+)(\\.(0-9+))?(-a-zA-Z0-9+)?$" "\\2" PROJECT_VERSION_MINOR "${VERSION}") + if (VERSION MATCHES "^v(0-9+)\\.(0-9+)(\\.(0-9+))(-a-zA-Z0-9+)?$") + string(REGEX REPLACE "^v(0-9+)\\.(0-9+)(\\.(0-9+))(-a-zA-Z0-9+)?$" "\\3" PROJECT_VERSION_PATCH "${VERSION}") + else () + set(PROJECT_VERSION_PATCH "0") + endif () + if (VERSION MATCHES "^v(0-9+)\\.(0-9+)(\\.(0-9+))(-a-zA-Z0-9+)$") + string(REGEX REPLACE "^v(0-9+)\\.(0-9+)(\\.(0-9+))(-a-zA-Z0-9+)$" "\\4" PROJECT_VERSION_SHA1 "${VERSION}") + else () + set(PROJECT_VERSION_SHA1 "") + endif () +else () + set(PROJECT_VERSION_MAJOR "0") + set(PROJECT_VERSION_MINOR "6") + set(PROJECT_VERSION_PATCH "0") +endif () + +set(PROJECT_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}") +message(STATUS "Building slowmoVideo ${PROJECT_VERSION}") +configure_file(src/version.h.in version.h) + +### Compiler options ### + +if (APPLE) +# To compile with clang: +#set(CMAKE_CXX_COMPILER "clang++") +#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall --verbose") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall ") +#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -O2 -mtune=corei7") + +# Set additional project information +set(COMPANY "granjow") +set(COPYRIGHT "Copyright (c) 2011 Simon A. Eugster (Granjow). All rights reserved.") +set(IDENTIFIER "net.granjow.slomoui") + +else() +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -g") +endif() + +if(CMAKE_TOOLCHAIN_FILE) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DMXE") + set(CMAKE_C_FLAGS "${CMAKE_CXX_FLAGS} -DMXE") +endif(CMAKE_TOOLCHAIN_FILE) + + +### CMake Configuration ### +option (ENABLE_TESTS "Build the unit tests" FALSE) +set(ADDITIONAL_LIBS "") +if(MSYS) + message(STATUS "MSYS system detected.") + include("${PROJECT_SOURCE_DIR}/cmake/MingwCrossEnv.cmake") +endif(MSYS) + + +### Find packages ### + + +# Check if environment variable QTDIR is set. +# needed for Qt5 +# Extra security for windows environment as well. +if (DEFINED ENV{QTDIR}) + set(CMAKE_PREFIX_PATH $ENV{QTDIR} ${CMAKE_PREFIX_PATH}) +endif () + +if (APPLE) + set(DEST "slowmoUI.app/Contents/Tools/bin") +else() + set(DEST "bin") +endif() + +include(cmake/macros.cmake) + +find_package(Qt5Core QUIET) +if (Qt5Core_FOUND) + message(STATUS "Using Qt5") + set(USE_QT TRUE) + # go on with other packages + find_package(Qt5 COMPONENTS Core Widgets Gui Xml Script REQUIRED) + if (Qt5_POSITION_INDEPENDENT_CODE) + set(CMAKE_POSITION_INDEPENDENT_CODE ON) + endif (Qt5_POSITION_INDEPENDENT_CODE) + # set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} + # ${Qt5Core_EXECUTABLE_COMPILE_FLAGS}") + + include_directories(${Qt5Core_INCLUDES}) + include_directories(${Qt5Widgets_INCLUDES}) + include_directories(${Qt5Gui_INCLUDES}) + include_directories(${Qt5Xml_INCLUDES}) + include_directories(${Qt5Script_INCLUDES}) + + # set up a mapping so that the Release configuration for the Qt imported target is + # used in the COVERAGE CMake configuration. + #set_target_properties(Qt5::Core PROPERTIES MAP_IMPORTED_CONFIG_COVERAGE "DEBUG") + +endif (Qt5Core_FOUND) + + +message("Qt libraries found at : ${Qt5Gui_LIBRARIES} / ${QT_LIBRARIES}" ) + +set (USE_QTKIT OFF CACHE BOOL "Build with the QTKit encoder") +set (USE_FFMPEG ON CACHE BOOL "Build with the FFMPEG encoder") +set (USE_DBUS OFF CACHE BOOL "Build with the DBUS notification support") + +if(NOT MSYS) + find_package(FFMPEG) +else(NOT MSYS) + # Handled by MingwCrossEnv.cmake to avoid errors like: + # libavformat.a(avisynth.o):avisynth.c:(.text+0x6b): undefined reference to `AVIStreamRelease@4' +endif(NOT MSYS) +# not here anymore +#include_directories(${FFMPEG_INCLUDE_DIR}) +#include_directories("/usr/include/ffmpeg/") +#link_directories(${FFMPEG_LIBRARY_DIR}) + +if (APPLE AND USE_QTKIT) + find_package(QTKIT) + message(STATUS "QTKIT find at ${QTKIT_LIBRARY} ") + set(ADDITIONAL_LIBS "-framework Cocoa -framework QTKit -framework QuartzCore -framework AppKit -framework OpenCL") +endif() + +# Find OpenCV, you may need to set OpenCV_DIR variable +# to the absolute path to the directory containing OpenCVConfig.cmake file +# via the command line or GUI +find_package(OpenCV REQUIRED) +# If the package has been found, several variables will +# be set, you can find the full list with descriptions +# in the OpenCVConfig.cmake file. +# Print some message showing some of them +message(STATUS "OpenCV library status:") +message(STATUS " version: ${OpenCV_VERSION}") +message(STATUS " libraries: ${OpenCV_LIBS}") +message(STATUS " include path: ${OpenCV_INCLUDE_DIRS}") + +if (${OpenCV_VERSION_MAJOR} EQUAL 3) + set(HAS_OCV_VERSION_3 ON) +else() + set(HAS_OCV_VERSION_3 OFF) +endif() + +include_directories(${OPENCV_INCLUDE_DIRS}) + +# for config.h +include_directories(${CMAKE_CURRENT_BINARY_DIR}) + + + +### Set up libraries ### +if(MSYS) + set(EXTERNAL_LIBS ${FFMPEG_LIBRARIES} ${QT_LIBRARIES} ${OpenCV_LIBS_OPT} ${OpenCV_EXTRA_LIBS_OPT} ${ADDITIONAL_LIBS}) +else(MSYS) + set(EXTERNAL_LIBS ${QT_LIBRARIES} ${OpenCV_LIBS} ${ADDITIONAL_LIBS} ${FFMPEG_LIBRARIES}) +endif(MSYS) + + +### Information output +set(BUILD_SLOWMO "NO") +#if(QT_LIBRARIES AND FFMPEG_FOUND) +if(USE_QT AND FFMPEG_FOUND) +set(BUILD_SLOWMO "YES") +#endif(QT_LIBRARIES AND FFMPEG_FOUND) +endif() +if(NOT FFMPEG_SWSCALE_FOUND) + if(CMAKE_TOOLCHAIN_FILE) + + else(CMAKE_TOOLCHAIN_FILE) + set(BUILD_SLOWMO "NO") + endif(CMAKE_TOOLCHAIN_FILE) +endif(NOT FFMPEG_SWSCALE_FOUND) + + +## Include projects to build ## + +include_directories(src/tr) +add_subdirectory(src/lib) +add_subdirectory(src/lib/libsvflow) +add_subdirectory(src/libgui) +add_subdirectory(src/project) +add_subdirectory(src/slowmoCLI) +add_subdirectory(src/slowmoUI) +add_subdirectory(src/slowmoFlowEdit) +add_subdirectory(src/slowmoRenderer) +add_subdirectory(src/visualizeFlow) +if(ENABLE_TESTS) + SET(QT_USE_QTTEST TRUE) + ## add_subdirectory(srd/test) + add_subdirectory(src/unittests) +endif(ENABLE_TESTS) + +##### SV END ##### + + + + + + +message("==================slowmoVideo========================") +message("* (info) slowmoVideo installation goes to ${CMAKE_INSTALL_PREFIX}.") +message(" (Can be adjusted with -DCMAKE_INSTALL_PREFIX=your_path. Default is ${SV_INST_DIR}.)") +#if(NOT QT_LIBRARIES) +if (NOT USE_QT) + message("Qt5 libraries could not be found.") +#endif(NOT QT_LIBRARIES) +endif(NOT USE_QT) +if(NOT FFMPEG_FOUND) + message("x ffmpeg libraries could not be found.") +else(NOT FFMPEG_FOUND) + message("* (ok) ffmpeg found at ${FFMPEG_LIBRARY_DIR}") +endif(NOT FFMPEG_FOUND) +if(NOT FFMPEG_SWSCALE_FOUND) + message("x libswscale could not be found.") +endif(NOT FFMPEG_SWSCALE_FOUND) +if(NOT OpenCV_VERSION) + message("x OpenCV could not be found.") +else(NOT OpenCV_VERSION) + message("* (ok) OpenCV ${OpenCV_VERSION} found at ${OpenCV_INCLUDE_DIRS}.") +endif(NOT OpenCV_VERSION) +message("* slowmoVideo will be built: ---${BUILD_SLOWMO}---") +message("=======================END===========================") +message("") + + +if(NOT BUILD_SLOWMO) + message(FATAL_ERROR "Cannot build slowmoVideo, please install the missing packages first.") +endif(NOT BUILD_SLOWMO) + +configure_file(src/config.h.in config.h)
View file
slowmoVideo-0.6.tar.xz/LICENSE.md
Added
@@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + <program> Copyright (C) <year> <name of author> + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +<http://www.gnu.org/licenses/>. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +<http://www.gnu.org/philosophy/why-not-lgpl.html>.
View file
slowmoVideo-0.4.tar.gz/README.md -> slowmoVideo-0.6.tar.xz/README.md
Changed
@@ -1,22 +1,82 @@ -slowmoVideo -=========== +# slowmoVideo -Hello! This is a short introduction for you if you want to: -- compile -- develop -- translate +slowmoVideo is a tool that uses optical flow for generating slow-motion videos. +See heredemos for some demo videos. -slowmoVideo. For everything else please go to the -web page(http://slowmoVideo.granjow.net) or the -Google+ group(https://plus.google.com/communities/116570263544012246711). +For the last changes, see the Changelog(docs/changelog.md). -Building --------- + +## Building + +slowmoVideo uses CMake for building. You may also want to build V3D Flow Builderv3d +for fast GPU based rendering. + +Dependencies on Ubuntu 19.10…16.04: + + build-essential cmake libopencv-dev qt5-default qttools5-dev-tools qtscript5-dev ### Building for Linux -http://slowmovideo.granjow.net/download.php + +```bash +git submodule update --init + +mkdir build +cd build + +cmake .. +make + +# Run it +src/slowmoUI/slowmoUI +``` + +### Building AppImage on Ubuntu 16.04 + +This guide shows how to build a slowmoVideo AppImage in a Docker container with linuxdeployqt releaseldq-r, +in this example version 6ldq-6. + +See Packaging native binariesai for more information on AppImage packaging. + +```bash +# Run a docker container and mount the current directory to /build in the container +docker run -it --rm -v $(pwd):/build ubuntu:16.04 + +# Install all packages that are required for building slowmoVideo +apt update +apt install wget build-essential cmake libopencv-dev qt5-default qttools5-dev-tools qtscript5-dev + +# Get linuxdeployqt and make it executable +cd +wget https://github.com/probonopd/linuxdeployqt/releases/download/6/linuxdeployqt-6-x86_64.AppImage +chmod +x linuxdeployqt-6-x86_64.AppImage + + +# Build slowmoVideo +mkdir appimage-build +cd appimage-build +cmake .. -DCMAKE_INSTALL_PREFIX=/usr +make + +# Install slowmoVideo to the AppDir directory for AppImage +make install DESTDIR=AppDir + +# Extract the linuxdeployqt AppImage when FUSE is not available in a docker container +~/linuxdeployqt-6-x86_64.AppImage --appimage-extract + +# Create the AppImage +squashfs-root/AppRun AppDir/usr/share/applications/slowmoUI.desktop -appimage +``` + +ldq-r: https://github.com/probonopd/linuxdeployqt/releases +ldq-6: https://github.com/probonopd/linuxdeployqt/releases/download/6/linuxdeployqt-6-x86_64.AppImage +ai: https://docs.appimage.org/packaging-guide/from-source/native-binaries.html + + ### Building for Windows + +*This guide is outdated.* + Compiling slowmoVideo for Windows using MXE on Linux: 1. Get mxe _not_ from http://mxe.cc/ BUT, as long as OpenCV is not in the official branch, from @@ -28,19 +88,20 @@ `cmake .. -DCMAKE_TOOLCHAIN_FILE=/PATH_TO_MXE/usr/i686-pc-mingw32/share/cmake/mxe-conf.cmake` 5. Compile! -### Building for MacOS -take a look here : http://vald70.free.fr/?p=197 - #### Notes + Additionally to slowmoVideo, ffmpeg.exe (32-bit build, static) is required. Download it from http://ffmpeg.zeranoe.com/builds/ and put it into the same directory as slowmoUI.exe. +### Building for MacOS -Translating ------------ +take a look at README.osx for more detailed instruction -For this you should be in the slowmoVideo subdirectory which contains the tr/ directory. -The tools (`linguist`, `lupdate`, `lrelease`) are available in the `qt4-dev-tools` package for Debian based systems. + +## Translating + +For this you should be in the `src` subdirectory which contains the `tr/` directory. +The tools (`linguist`, `lupdate`, `lrelease`) are available in the `qttools5-dev-tools` package for Debian based systems. ### Adding your language To add your language xx (like fr, it), run the following command to generate the respective .ts file: @@ -69,3 +130,6 @@ Now you can push your `.ts` file to git. + +demos: http://slowmovideo.granjow.net/videos.html +v3d: https://github.com/slowmoVideo/v3d-flow-builder
View file
slowmoVideo-0.6.tar.xz/README.osx.md
Added
@@ -0,0 +1,36 @@ +### Building for MacOS + +here, I will describe how to build slowmoVideo for OSX from scratch. +you will need of course *Xcode* and *command line tools*, with *cmake* +will need some dependencies : + +* glew (glew-1.10.0) +* ffmpeg (ffmpeg-2.2) +* jpeg (jpeg-9a) +* libpng (libpng-1.6.10) +* zlib (zlib-1.2.8) +* yasm (for ffmpeg) (yasm-1.2.0) +* opencv (opencv-2.4.8) +* qt4 (qt 4.8.5) +* x264 for ffmpeg + + +1- you need to specify where to find some libraries for cmake : +```export QTDIR=/Users/val/Documents/Sources/qt4 +export FFMPEGDIR=/Users/val/Documents/Sources/ffmpeg +``` + +2- run cmake : +``` +cmake ../slowmoVideo/src -DCMAKE_INSTALL_PREFIX=/Users/val/Applications/slowmoVideo -DQTDIR=/Users/val/Documents/Sources/qt4 -DQT_MAKE_EXECUTABLE=/Users/val/Documents/Sources/qt4/bin/qmake -DOpenCV_DIR=/Users/val/Documents/Sources/opencv/share/OpenCV -DGLEW_INCLUDE_DIR=/Users/val/Documents/Sources/slowlib/include -DGLEW_LIBRAIRIES=/Users/val/Documents/Sources/slowlib/lib/libGLEW.a -DJPEG_INCLUDE_DIR=/Users/val/Documents/Sources/slowlib/include -DJPEG_LIBRARY=/Users/val/Documents/Sources/slowlib/lib/libjpeg.a -DFFMPEG_LIBRARY_DIR=/Users/val/Documents/Sources/ffmpeg/lib -DFFMPEG_INCLUDE_PATHS="/Users/val/Documents/Sources/ffmpeg/include" +``` + +check if cmake find all the needed part. As in my case some library where not found, so I have to specify them in CMakeCache.txt directly … +they where : glew libraries and libswcale ! + + +* if all is ok you can run `make ; make install` + +you will have some warning during compilation… +you should now have a working GUI application bundle for MacOS in your install target directory. +
View file
slowmoVideo-0.6.tar.xz/cmake
Added
+(directory)
View file
slowmoVideo-0.6.tar.xz/cmake/DeployQt5.cmake
Added
@@ -0,0 +1,338 @@ +#.rst: +# DeployQt5 +# --------- +# +# Functions to help assemble a standalone Qt5 executable. +# +# A collection of CMake utility functions useful for deploying Qt5 +# executables. +# +# The following functions are provided by this module: +# +# :: +# +# write_qt5_conf +# resolve_qt5_paths +# fixup_qt5_executable +# install_qt5_plugin_path +# install_qt5_plugin +# install_qt5_executable +# +# Requires CMake 2.8.9 or greater because Qt 5 does. +# Also depends on BundleUtilities.cmake. +# +# :: +# +# WRITE_QT5_CONF(<qt_conf_dir> <qt_conf_contents>) +# +# Writes a qt.conf file with the <qt_conf_contents> into <qt_conf_dir>. +# +# :: +# +# RESOLVE_QT5_PATHS(<paths_var> <executable_path>) +# +# Loop through <paths_var> list and if any don't exist resolve them +# relative to the <executable_path> (if supplied) or the +# CMAKE_INSTALL_PREFIX. +# +# :: +# +# FIXUP_QT5_EXECUTABLE(<executable> <qtplugins> <libs> <dirs> <plugins_dir> <request_qt_conf>) +# +# Copies Qt plugins, writes a Qt configuration file (if needed) and +# fixes up a Qt5 executable using BundleUtilities so it is standalone +# and can be drag-and-drop copied to another machine as long as all of +# the system libraries are compatible. +# +# <executable> should point to the executable to be fixed-up. +# +# <qtplugins> should contain a list of the names or paths of any Qt +# plugins to be installed. +# +# <libs> will be passed to BundleUtilities and should be a list of any +# already installed plugins, libraries or executables to also be +# fixed-up. +# +# <dirs> will be passed to BundleUtilities and should contain and +# directories to be searched to find library dependencies. +# +# <plugins_dir> allows an custom plugins directory to be used. +# +# <request_qt_conf> will force a qt.conf file to be written even if not +# needed. +# +# :: +# +# INSTALL_QT5_PLUGIN_PATH(plugin executable copy installed_plugin_path_var <plugins_dir> <component> <configurations>) +# +# Install (or copy) a resolved <plugin> to the default plugins directory +# (or <plugins_dir>) relative to <executable> and store the result in +# <installed_plugin_path_var>. +# +# If <copy> is set to TRUE then the plugins will be copied rather than +# installed. This is to allow this module to be used at CMake time +# rather than install time. +# +# If <component> is set then anything installed will use this COMPONENT. +# +# :: +# +# INSTALL_QT5_PLUGIN(plugin executable copy installed_plugin_path_var <plugins_dir> <component>) +# +# Install (or copy) an unresolved <plugin> to the default plugins +# directory (or <plugins_dir>) relative to <executable> and store the +# result in <installed_plugin_path_var>. See documentation of +# INSTALL_QT5_PLUGIN_PATH. +# +# :: +# +# INSTALL_QT5_EXECUTABLE(<executable> <qtplugins> <libs> <dirs> <plugins_dir> <request_qt_conf> <component>) +# +# Installs Qt plugins, writes a Qt configuration file (if needed) and +# fixes up a Qt5 executable using BundleUtilities so it is standalone +# and can be drag-and-drop copied to another machine as long as all of +# the system libraries are compatible. The executable will be fixed-up +# at install time. <component> is the COMPONENT used for bundle fixup +# and plugin installation. See documentation of FIXUP_QT5_BUNDLE. + +#============================================================================= +# Copyright 2011 Mike McQuaid <mike@mikemcquaid.com> +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distribute this file outside of CMake, substitute the full +# License text for the above reference.) + +# The functions defined in this file depend on the fixup_bundle function +# (and others) found in BundleUtilities.cmake + +include(BundleUtilities) +set(DeployQt5_cmake_dir "${CMAKE_CURRENT_LIST_DIR}") +set(DeployQt5_apple_plugins_dir "PlugIns") + +function(write_qt5_conf qt_conf_dir qt_conf_contents) + set(qt_conf_path "${qt_conf_dir}/qt.conf") + message(STATUS "Writing ${qt_conf_path}") + file(WRITE "${qt_conf_path}" "${qt_conf_contents}") +endfunction() + +function(resolve_qt5_paths paths_var) + set(executable_path ${ARGV1}) + + set(paths_resolved) + foreach(path ${${paths_var}}) + if(EXISTS "${path}") + list(APPEND paths_resolved "${path}") + else() + if(${executable_path}) + list(APPEND paths_resolved "${executable_path}/${path}") + else() + list(APPEND paths_resolved "\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${path}") + endif() + endif() + endforeach() + set(${paths_var} ${paths_resolved} PARENT_SCOPE) +endfunction() + +function(fixup_qt5_executable executable) + set(qtplugins ${ARGV1}) + set(libs ${ARGV2}) + set(dirs ${ARGV3}) + set(plugins_dir ${ARGV4}) + set(request_qt_conf ${ARGV5}) + + message(STATUS "fixup_qt5_executable") + message(STATUS " executable='${executable}'") + message(STATUS " qtplugins='${qtplugins}'") + message(STATUS " libs='${libs}'") + message(STATUS " dirs='${dirs}'") + message(STATUS " plugins_dir='${plugins_dir}'") + message(STATUS " request_qt_conf='${request_qt_conf}'") + + if(QT_LIBRARY_DIR) + list(APPEND dirs "${QT_LIBRARY_DIR}") + endif() + if(QT_BINARY_DIR) + list(APPEND dirs "${QT_BINARY_DIR}") + endif() + + if(APPLE) + set(qt_conf_dir "${executable}/Contents/Resources") + set(executable_path "${executable}") + set(write_qt_conf TRUE) + if(NOT plugins_dir) + set(plugins_dir "${DeployQt5_apple_plugins_dir}") + endif() + else() + get_filename_component(executable_path "${executable}" PATH) + if(NOT executable_path) + set(executable_path ".") + endif() + set(qt_conf_dir "${executable_path}") + set(write_qt_conf ${request_qt_conf}) + endif() + + foreach(plugin ${qtplugins}) + set(installed_plugin_path "") + install_qt5_plugin("${plugin}" "${executable}" 1 installed_plugin_path) + list(APPEND libs ${installed_plugin_path}) + endforeach() + + foreach(lib ${libs}) + if(NOT EXISTS "${lib}") + message(FATAL_ERROR "Library does not exist: ${lib}") + endif() + endforeach() + + resolve_qt5_paths(libs "${executable_path}") + + if(write_qt_conf) + set(qt_conf_contents "Paths\nPlugins = ${plugins_dir}") + write_qt5_conf("${qt_conf_dir}" "${qt_conf_contents}") + endif() + + fixup_bundle("${executable}" "${libs}" "${dirs}") +endfunction() + +function(install_qt5_plugin_path plugin executable copy installed_plugin_path_var) + set(plugins_dir ${ARGV4}) + set(component ${ARGV5}) + set(configurations ${ARGV6}) + if(EXISTS "${plugin}") + if(APPLE) + if(NOT plugins_dir) + set(plugins_dir "${DeployQt5_apple_plugins_dir}") + endif() + set(plugins_path "${executable}/Contents/${plugins_dir}") + else() + get_filename_component(plugins_path "${executable}" PATH) + if(NOT plugins_path) + set(plugins_path ".") + endif() + if(plugins_dir) + set(plugins_path "${plugins_path}/${plugins_dir}") + endif() + endif() + + set(plugin_group "") + + get_filename_component(plugin_path "${plugin}" PATH) + get_filename_component(plugin_parent_path "${plugin_path}" PATH) + get_filename_component(plugin_parent_dir_name "${plugin_parent_path}" NAME) + get_filename_component(plugin_name "${plugin}" NAME) + string(TOLOWER "${plugin_parent_dir_name}" plugin_parent_dir_name) + + if("${plugin_parent_dir_name}" STREQUAL "plugins") + get_filename_component(plugin_group "${plugin_path}" NAME) + set(${plugin_group_var} "${plugin_group}") + endif() + set(plugins_path "${plugins_path}/${plugin_group}") + + if(${copy}) + file(MAKE_DIRECTORY "${plugins_path}") + file(COPY "${plugin}" DESTINATION "${plugins_path}") + else() + if(configurations AND (CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE)) + set(configurations CONFIGURATIONS ${configurations}) + else() + unset(configurations) + endif() + install(FILES "${plugin}" DESTINATION "${plugins_path}" ${configurations} ${component}) + endif() + set(${installed_plugin_path_var} "${plugins_path}/${plugin_name}" PARENT_SCOPE) + endif() +endfunction() + +function(install_qt5_plugin plugin executable copy installed_plugin_path_var) + set(plugins_dir ${ARGV4}) + set(component ${ARGV5}) + if(EXISTS "${plugin}") + install_qt5_plugin_path("${plugin}" "${executable}" "${copy}" "${installed_plugin_path_var}" "${plugins_dir}" "${component}") + else() + string(TOUPPER "QT_${plugin}_PLUGIN" plugin_var) + set(plugin_release_var "${plugin_var}_RELEASE") + set(plugin_debug_var "${plugin_var}_DEBUG") + set(plugin_release "${${plugin_release_var}}") + set(plugin_debug "${${plugin_debug_var}}") + if(DEFINED "${plugin_release_var}" AND DEFINED "${plugin_debug_var}" AND NOT EXISTS "${plugin_release}" AND NOT EXISTS "${plugin_debug}") + message(WARNING "Qt plugin \"${plugin}\" not recognized or found.") + endif() + if(NOT EXISTS "${${plugin_debug_var}}") + set(plugin_debug "${plugin_release}") + endif() + + if(CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE) + install_qt5_plugin_path("${plugin_release}" "${executable}" "${copy}" "${installed_plugin_path_var}_release" "${plugins_dir}" "${component}" "Release|RelWithDebInfo|MinSizeRel") + install_qt5_plugin_path("${plugin_debug}" "${executable}" "${copy}" "${installed_plugin_path_var}_debug" "${plugins_dir}" "${component}" "Debug") + + if(CMAKE_BUILD_TYPE MATCHES "^Debug$") + set(${installed_plugin_path_var} ${${installed_plugin_path_var}_debug}) + else() + set(${installed_plugin_path_var} ${${installed_plugin_path_var}_release}) + endif() + else() + install_qt5_plugin_path("${plugin_release}" "${executable}" "${copy}" "${installed_plugin_path_var}" "${plugins_dir}" "${component}") + endif() + endif() + set(${installed_plugin_path_var} ${${installed_plugin_path_var}} PARENT_SCOPE) +endfunction() + +function(install_qt5_executable executable) + set(qtplugins ${ARGV1}) + set(libs ${ARGV2}) + set(dirs ${ARGV3}) + set(plugins_dir ${ARGV4}) + set(request_qt_conf ${ARGV5}) + set(component ${ARGV6}) + if(QT_LIBRARY_DIR) + list(APPEND dirs "${QT_LIBRARY_DIR}") + endif() + if(QT_BINARY_DIR) + list(APPEND dirs "${QT_BINARY_DIR}") + endif() + if(component) + set(component COMPONENT ${component}) + else() + unset(component) + endif() + + get_filename_component(executable_absolute "${executable}" ABSOLUTE) + if(EXISTS "${QT_QTCORE_LIBRARY_RELEASE}") + gp_file_type("${executable_absolute}" "${QT_QTCORE_LIBRARY_RELEASE}" qtcore_type) + elseif(EXISTS "${QT_QTCORE_LIBRARY_DEBUG}") + gp_file_type("${executable_absolute}" "${QT_QTCORE_LIBRARY_DEBUG}" qtcore_type) + endif() + if(qtcore_type STREQUAL "system") + set(qt_plugins_dir "") + endif() + + if(QT_IS_STATIC) + message(WARNING "Qt built statically: not installing plugins.") + else() + if(APPLE) + get_property(loc TARGET Qt5::QCocoaIntegrationPlugin + PROPERTY LOCATION_RELEASE) + install_qt5_plugin("${loc}" "${executable}" 0 installed_plugin_paths "PlugIns" "${component}") + list(APPEND libs ${installed_plugin_paths}) + endif() + foreach(plugin ${qtplugins}) + set(installed_plugin_paths "") + install_qt5_plugin("${plugin}" "${executable}" 0 installed_plugin_paths "${plugins_dir}" "${component}") + list(APPEND libs ${installed_plugin_paths}) + endforeach() + endif() + + resolve_qt5_paths(libs "") + + install(CODE + "include(\"${DeployQt5_cmake_dir}/DeployQt5.cmake\") + set(BU_CHMOD_BUNDLE_ITEMS TRUE) + FIXUP_QT5_EXECUTABLE(\"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${executable}\" \"\" \"${libs}\" \"${dirs}\" \"${plugins_dir}\" \"${request_qt_conf}\")" + ${component} + ) +endfunction()
View file
slowmoVideo-0.6.tar.xz/cmake/FindFFMPEG.cmake
Added
@@ -0,0 +1,148 @@ +# From: http://www.openlibraries.org/browser/trunk/FindFFMPEG.cmake + +# - Try to find FFMPEG +# Once done this will define +# +# FFMPEG_FOUND - system has FFMPEG +# FFMPEG_INCLUDE_DIR - the include directories +# FFMPEG_LIBRARY_DIR - the directory containing the libraries +# FFMPEG_LIBRARIES - link these to use FFMPEG +# FFMPEG_SWSCALE_FOUND - FFMPEG also has SWSCALE +# + +#SET( FFMPEG_HEADERS avformat.h avcodec.h avutil.h avdevice.h ) +#SET( FFMPEG_PATH_SUFFIXES libavformat libavcodec libavutil libavdevice ) +SET( FFMPEG_HEADERS avformat.h avcodec.h avutil.h ) +SET( FFMPEG_PATH_SUFFIXES libavformat libavcodec libavutil ) +SET( FFMPEG_SWS_HEADERS swscale.h ) +SET( FFMPEG_SWS_PATH_SUFFIXES libswscale ) + +SET( FFMPEG_LIBRARY_DIR $ENV{FFMPEGDIR}/lib ) + +if( WIN32 ) + #SET( FFMPEG_LIBRARIES avformat.lib avcodec.lib avutil.lib avdevice.lib ) + SET( FFMPEG_LIBRARIES avformat.lib avcodec.lib avutil.lib ) + SET( FFMPEG_SWS_LIBRARIES swscale.lib ) + SET( FFMPEG_LIBRARY_DIR $ENV{FFMPEGDIR}\\lib ) + SET( FFMPEG_INCLUDE_PATHS $ENV{FFMPEGDIR}\\include ) + + # check to see if we can find swscale + SET( TMP_ TMP-NOTFOUND ) + FIND_PATH( TMP_ ${FFMPEG_SWS_LIBRARIES} + PATHS ${FFMPEG_LIBRARY_DIR} ) + IF ( TMP_ ) + SET( SWSCALE_FOUND TRUE ) + ENDIF( TMP_ ) +else( WIN32 ) + #SET( FFMPEG_LIBRARIES avformat avcodec avutil avdevice ) + SET( FFMPEG_LIBRARIES avformat avcodec avutil ) + SET( FFMPEG_SWS_LIBRARIES swscale ) + INCLUDE(FindPkgConfig) + if ( PKG_CONFIG_FOUND ) + pkg_check_modules( AVFORMAT libavformat ) + pkg_check_modules( AVCODEC libavcodec ) + pkg_check_modules( AVUTIL libavutil ) + #pkg_check_modules( AVDEVICE libavdevice ) + pkg_check_modules( SWSCALE libswscale ) + endif ( PKG_CONFIG_FOUND ) + + SET( FFMPEG_LIBRARY_DIR ${AVFORMAT_LIBRARY_DIRS} + ${AVCODEC_LIBRARY_DIRS} + ${AVUTIL_LIBRARY_DIRS} + #${AVDEVICE_LIBRARY_DIRS} + ) + SET( FFMPEG_INCLUDE_PATHS ${AVFORMAT_INCLUDE_DIRS} + ${AVCODEC_INCLUDE_DIRS} + ${AVUTIL_INCLUDE_DIRS} + #${AVDEVICE_INCLUDE_DIRS} + ) + # check to see if we can find swscale + FIND_LIBRARY(LIB_SWSCALE_ swscale ${FFMPEG_LIBRARY_DIR} ) + IF ( LIB_SWSCALE_ ) + SET( SWSCALE_FOUND TRUE ) + ENDIF( LIB_SWSCALE_ ) + +endif( WIN32 ) + + +# add in swscale if found +IF ( SWSCALE_FOUND ) + SET( FFMPEG_LIBRARY_DIR ${FFMPEG_LIBRARY_DIR} + ${SWSCALE_LIBRARY_DIRS} ) + SET( FFMPEG_INCLUDE_PATHS ${FFMPEG_INCLUDE_PATHS} + ${SWSCALE_INCLUDE_DIRS} ) + SET( FFMPEG_HEADERS ${FFMPEG_HEADERS} + ${FFMPEG_SWS_HEADERS} ) + SET( FFMPEG_PATH_SUFFIXES ${FFMPEG_PATH_SUFFIXES} + ${FFMPEG_SWS_PATH_SUFFIXES} ) + SET( FFMPEG_LIBRARIES ${FFMPEG_LIBRARIES} + ${FFMPEG_SWS_LIBRARIES} ) +ENDIF ( SWSCALE_FOUND ) + +# find includes +SET( INC_SUCCESS 0 ) +SET( TMP_ TMP-NOTFOUND ) +SET( FFMPEG_INCLUDE_DIR ${FFMPEG_INCLUDE_PATHS} ) +FOREACH( INC_ ${FFMPEG_HEADERS} ) + message(STATUS "checking: ${INC_}" ) + + FIND_PATH( TMP_ ${INC_} + PATHS ${FFMPEG_INCLUDE_PATHS} + PATH_SUFFIXES ${FFMPEG_PATH_SUFFIXES} ) + IF ( TMP_ ) + message(STATUS " ${TMP_}" ) + MATH( EXPR INC_SUCCESS ${INC_SUCCESS}+1 ) + SET( FFMPEG_INCLUDE_DIR ${FFMPEG_INCLUDE_DIR} ${TMP_} ) + ENDIF ( TMP_ ) + SET( TMP_ TMP-NOTFOUND ) +ENDFOREACH( INC_ ) + +list(LENGTH FFMPEG_INCLUDE_DIR LENGTH_INCLUDES) +list(LENGTH FFMPEG_LIBRARY_DIR LENGTH_LIBRARIES) + +# clear out duplicates +if(LENGTH_INCLUDES GREATER 0) +LIST( REMOVE_DUPLICATES FFMPEG_INCLUDE_DIR ) +endif(LENGTH_INCLUDES GREATER 0) +if(LENGTH_LIBRARIES GREATER 0) +LIST( REMOVE_DUPLICATES FFMPEG_LIBRARY_DIR ) +endif(LENGTH_LIBRARIES GREATER 0) + +# find the full paths of the libraries +SET( TMP_ TMP-NOTFOUND ) +IF ( NOT WIN32 ) + FOREACH( LIB_ ${FFMPEG_LIBRARIES} ) + FIND_LIBRARY( TMP_ NAMES ${LIB_} PATHS ${FFMPEG_LIBRARY_DIR} ) + IF ( TMP_ ) + SET( FFMPEG_LIBRARIES_FULL ${FFMPEG_LIBRARIES_FULL} ${TMP_} ) + ENDIF ( TMP_ ) + SET( TMP_ TMP-NOTFOUND ) + ENDFOREACH( LIB_ ) + SET ( FFMPEG_LIBRARIES ${FFMPEG_LIBRARIES_FULL} ) +ENDIF( NOT WIN32 ) + +LIST( LENGTH FFMPEG_HEADERS LIST_SIZE_ ) + +SET( FFMPEG_FOUND FALSE ) +SET( FFMPEG_SWSCALE_FOUND FALSE ) +IF ( ${INC_SUCCESS} EQUAL ${LIST_SIZE_} ) + SET( FFMPEG_FOUND TRUE ) + SET( FFMPEG_SWSCALE_FOUND ${SWSCALE_FOUND} ) +ENDIF ( ${INC_SUCCESS} EQUAL ${LIST_SIZE_} ) + +string(REPLACE "/usr/include/" "" FFMPEG_INCLUDE_DIR "${FFMPEG_INCLUDE_DIR}") + +# add libx264 ... +if (APPLE) +FIND_LIBRARY(LIB_X264 NAMES x264 libx264.a PATHS /usr/local/lib $ENV{LIBX264DIR}/lib DOC "x264 library" ) +#SET(FFMPEG_LIBRARIES ${FFMPEG_LIBRARIES} "/Users/val/Documents/Sources/slowlib/lib/libx264.a" ) +SET(FFMPEG_LIBRARIES ${FFMPEG_LIBRARIES} ${LIB_X264} ) +message(STATUS "x264 found in: ${LIB_X264}" ) +endif() + +# On OS X we ffmpeg libraries depend on VideoDecodeAcceleration and CoreVideo frameworks +IF (APPLE) + SET(FFMPEG_LIBRARIES ${FFMPEG_LIBRARIES} "-framework CoreFoundation -framework QuartzCore -framework VideoDecodeAcceleration -liconv -lbz2 -lz") +ENDIF() + +
View file
slowmoVideo-0.6.tar.xz/cmake/FindGLEW.cmake
Changed
(renamed from src/cmake/FindGLEW.cmake)
View file
slowmoVideo-0.6.tar.xz/cmake/FindQTKit.cmake
Added
@@ -0,0 +1,25 @@ +# Locate Apple QTKit (next-generation QuickTime) +# This module defines +# QTKIT_LIBRARY +# QTKIT_FOUND, if false, do not try to link to gdal +# QTKIT_INCLUDE_DIR, where to find the headers +# +# $QTKIT_DIR is an environment variable that would +# correspond to the ./configure --prefix=$QTKIT_DIR +# +# Created by Eric Wing. + +# QTKit on OS X looks different than QTKit for Windows, +# so I am going to case the two. + +IF(APPLE) + FIND_PATH(QTKIT_INCLUDE_DIR QTKit/QTKit.h) + FIND_LIBRARY(QTKIT_LIBRARY QTKit) +ENDIF() + + +SET(QTKIT_FOUND "NO") +IF(QTKIT_LIBRARY AND QTKIT_INCLUDE_DIR) + SET(QTKIT_FOUND "YES") +ENDIF() +
View file
slowmoVideo-0.6.tar.xz/cmake/GetGitRevisionDescription.cmake
Added
@@ -0,0 +1,130 @@ +# - Returns a version string from Git +# +# These functions force a re-configure on each git commit so that you can +# trust the values of the variables in your build system. +# +# get_git_head_revision(<refspecvar> <hashvar> <additional arguments to git describe> ...) +# +# Returns the refspec and sha hash of the current head revision +# +# git_describe(<var> <additional arguments to git describe> ...) +# +# Returns the results of git describe on the source tree, and adjusting +# the output so that it tests false if an error occurs. +# +# git_get_exact_tag(<var> <additional arguments to git describe> ...) +# +# Returns the results of git describe --exact-match on the source tree, +# and adjusting the output so that it tests false if there was no exact +# matching tag. +# +# Requires CMake 2.6 or newer (uses the 'function' command) +# +# Original Author: +# 2009-2010 Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net> +# http://academic.cleardefinition.com +# Iowa State University HCI Graduate Program/VRAC +# +# Copyright Iowa State University 2009-2010. +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +if(__get_git_revision_description) + return() +endif() +set(__get_git_revision_description YES) + +# We must run the following at "include" time, not at function call time, +# to find the path to this module rather than the path to a calling list file +get_filename_component(_gitdescmoddir ${CMAKE_CURRENT_LIST_FILE} PATH) + +function(get_git_head_revision _refspecvar _hashvar) + set(GIT_PARENT_DIR "${CMAKE_CURRENT_SOURCE_DIR}") + set(GIT_DIR "${GIT_PARENT_DIR}/.git") + while(NOT EXISTS "${GIT_DIR}") # .git dir not found, search parent directories + set(GIT_PREVIOUS_PARENT "${GIT_PARENT_DIR}") + get_filename_component(GIT_PARENT_DIR ${GIT_PARENT_DIR} PATH) + if(GIT_PARENT_DIR STREQUAL GIT_PREVIOUS_PARENT) + # We have reached the root directory, we are not in git + set(${_refspecvar} "GITDIR-NOTFOUND" PARENT_SCOPE) + set(${_hashvar} "GITDIR-NOTFOUND" PARENT_SCOPE) + return() + endif() + set(GIT_DIR "${GIT_PARENT_DIR}/.git") + endwhile() + # check if this is a submodule + if(NOT IS_DIRECTORY ${GIT_DIR}) + file(READ ${GIT_DIR} submodule) + string(REGEX REPLACE "gitdir: (.*)\n$" "\\1" GIT_DIR_RELATIVE ${submodule}) + get_filename_component(SUBMODULE_DIR ${GIT_DIR} PATH) + get_filename_component(GIT_DIR ${SUBMODULE_DIR}/${GIT_DIR_RELATIVE} ABSOLUTE) + endif() + set(GIT_DATA "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/git-data") + if(NOT EXISTS "${GIT_DATA}") + file(MAKE_DIRECTORY "${GIT_DATA}") + endif() + + if(NOT EXISTS "${GIT_DIR}/HEAD") + return() + endif() + set(HEAD_FILE "${GIT_DATA}/HEAD") + configure_file("${GIT_DIR}/HEAD" "${HEAD_FILE}" COPYONLY) + + configure_file("${_gitdescmoddir}/GetGitRevisionDescription.cmake.in" + "${GIT_DATA}/grabRef.cmake" + @ONLY) + include("${GIT_DATA}/grabRef.cmake") + + set(${_refspecvar} "${HEAD_REF}" PARENT_SCOPE) + set(${_hashvar} "${HEAD_HASH}" PARENT_SCOPE) +endfunction() + +function(git_describe _var) + if(NOT GIT_FOUND) + find_package(Git QUIET) + endif() + get_git_head_revision(refspec hash) + if(NOT GIT_FOUND) + set(${_var} "GIT-NOTFOUND" PARENT_SCOPE) + return() + endif() + if(NOT hash) + set(${_var} "HEAD-HASH-NOTFOUND" PARENT_SCOPE) + return() + endif() + + # TODO sanitize + #if((${ARGN}" MATCHES "&&") OR + # (ARGN MATCHES "||") OR + # (ARGN MATCHES "\\;")) + # message("Please report the following error to the project!") + # message(FATAL_ERROR "Looks like someone's doing something nefarious with git_describe! Passed arguments ${ARGN}") + #endif() + + #message(STATUS "Arguments to execute_process: ${ARGN}") + + execute_process(COMMAND + "${GIT_EXECUTABLE}" + describe + + ${ARGN} + WORKING_DIRECTORY + "${CMAKE_SOURCE_DIR}" + RESULT_VARIABLE + res + OUTPUT_VARIABLE + out + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + if(NOT res EQUAL 0) + set(out "${out}-${res}-NOTFOUND") + endif() + + set(${_var} "${out}" PARENT_SCOPE) +endfunction() + +function(git_get_exact_tag _var) + git_describe(out --exact-match ${ARGN}) + set(${_var} "${out}" PARENT_SCOPE) +endfunction()
View file
slowmoVideo-0.6.tar.xz/cmake/GetGitRevisionDescription.cmake.in
Added
@@ -0,0 +1,38 @@ +# +# Internal file for GetGitRevisionDescription.cmake +# +# Requires CMake 2.6 or newer (uses the 'function' command) +# +# Original Author: +# 2009-2010 Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net> +# http://academic.cleardefinition.com +# Iowa State University HCI Graduate Program/VRAC +# +# Copyright Iowa State University 2009-2010. +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +set(HEAD_HASH) + +file(READ "@HEAD_FILE@" HEAD_CONTENTS LIMIT 1024) + +string(STRIP "${HEAD_CONTENTS}" HEAD_CONTENTS) +if(HEAD_CONTENTS MATCHES "ref") + # named branch + string(REPLACE "ref: " "" HEAD_REF "${HEAD_CONTENTS}") + if(EXISTS "@GIT_DIR@/${HEAD_REF}") + configure_file("@GIT_DIR@/${HEAD_REF}" "@GIT_DATA@/head-ref" COPYONLY) + elseif(EXISTS "@GIT_DIR@/logs/${HEAD_REF}") + configure_file("@GIT_DIR@/logs/${HEAD_REF}" "@GIT_DATA@/head-ref" COPYONLY) + set(HEAD_HASH "${HEAD_REF}") + endif() +else() + # detached HEAD + configure_file("@GIT_DIR@/HEAD" "@GIT_DATA@/head-ref" COPYONLY) +endif() + +if(NOT HEAD_HASH) + file(READ "@GIT_DATA@/head-ref" HEAD_HASH LIMIT 1024) + string(STRIP "${HEAD_HASH}" HEAD_HASH) +endif()
View file
slowmoVideo-0.6.tar.xz/cmake/MingwCrossEnv.cmake
Changed
(renamed from src/cmake/MingwCrossEnv.cmake)
View file
slowmoVideo-0.6.tar.xz/cmake/macros.cmake
Changed
(renamed from src/cmake/macros.cmake)
View file
slowmoVideo-0.6.tar.xz/docs
Added
+(directory)
View file
slowmoVideo-0.6.tar.xz/docs/changelog.md
Added
@@ -0,0 +1,15 @@ +# Changelog + +## Upcoming + +This release supports OpenCV 4, which is e.g. shipped with Ubuntu 20.04. + +* Added support for OpenCV 4 +* Fixed: Do not delete directories anymore when rendering (#130) +* Changed: Log to stdout again by default unless disabled with `--no-stdout` + +## v0.6 – 2020-04-12 + +First release of slowmoVideo as AppImage. + +* Changed: Support for Qt5 has been dropped.
View file
slowmoVideo-0.4.tar.gz/slowmoVideo.spec -> slowmoVideo-0.6.tar.xz/slowmoVideo.spec
Changed
@@ -82,7 +82,6 @@ %defattr(-,root,root,-) %doc README.md todo.org %{_bindir}/slowmoFlowEdit -%{_bindir}/slowmoInfo %{_bindir}/slowmoInterpolate %{_bindir}/slowmoRenderer %{_bindir}/slowmoUI
View file
slowmoVideo-0.6.tar.xz/src/config.h.in
Added
@@ -0,0 +1,14 @@ +/* + * compile time/plateform define +*/ +#ifndef CONFIG_H +#define CONFIG_H + +#cmakedefine USE_QTKIT +#cmakedefine USE_DBUS +#cmakedefine USE_FFMPEG + +// OpenCV version in use +#cmakedefine HAS_OCV_VERSION_3 + +#endif // CONFIG_H
View file
slowmoVideo-0.6.tar.xz/src/docs
Added
+(directory)
View file
slowmoVideo-0.6.tar.xz/src/docs/src
Added
+(directory)
View file
slowmoVideo-0.6.tar.xz/src/docs/src/description.dox
Changed
(renamed from src/slowmoVideo/docs/src/description.dox)
View file
slowmoVideo-0.6.tar.xz/src/docs/src/doxygen.css
Changed
(renamed from src/slowmoVideo/docs/src/doxygen.css)
View file
slowmoVideo-0.6.tar.xz/src/docs/src/tabs.css
Changed
(renamed from src/slowmoVideo/docs/src/tabs.css)
View file
slowmoVideo-0.6.tar.xz/src/lib
Added
+(directory)
View file
slowmoVideo-0.6.tar.xz/src/lib/CMakeLists.txt
Added
@@ -0,0 +1,87 @@ +# Static libraries +# http://www.itk.org/pipermail/insight-users/2007-November/024141.html +# http://www.linux-magazin.de/Heft-Abo/Ausgaben/2007/02/Mal-ausspannen + +set(LIB_SRC_BASE + defs_sV.cpp + defs_sV.hpp + vector_sV.cpp + shutter_sV.cpp + intMatrix_sV.cpp + interpolate_sV.cpp + bezierTools_sV.cpp + sourceField_sV.cpp + libsvflow/src/flowField_sV.cpp +) + +set(LIB_SRC_VIDEO + defs_sV.h + videoInfo_sV.cpp + avconvInfo_sV.cpp +) + +set(LIB_SRC_ARGS + trivialArgsReader_sV.cpp +) + +set(LIB_SRC_FLOWTOOLS + flowTools_sV.cpp + kernel_sV.cpp +) + +set(LIB_SRC_FLOWVIS + flowVisualization_sV.cpp +) + + +set(LIB_SRC_ENCODE + macros_sV.h + video_enc.h + ffmpeg_writer.h + ffmpeg_writer.cpp + video_enc.cpp +) + +if (OLD_FFMPEG) +set(LIB_SRC_ENCODE + ${LIB_SRC_ENCODE} + ffmpegEncode_sV.c +) +endif() + +if (APPLE AND USE_QTKIT) +set(LIB_SRC_ENCODE + ${LIB_SRC_ENCODE} + qtkit.h + qtkit.mm +) +endif() + +message(STATUS "FFMPEG libraries are at ${FFMPEG_LIBRARIES}") + +include_directories(${FFMPEG_INCLUDE_PATHS}) +include_directories(libsvflow) + +add_library(sV STATIC ${LIB_SRC_BASE}) +target_link_libraries(sV ${QT_LIBRARIES} sVflow) +qt5_use_modules(sV Core) +qt5_use_modules(sV Gui) + +add_library(sVinfo STATIC ${LIB_SRC_VIDEO}) +qt5_use_modules(sVinfo Core) +qt5_use_modules(sVinfo Gui) +target_link_libraries(sVinfo ${FFMPEG_LIBRARIES}) + +add_library(sVencode STATIC ${LIB_SRC_ENCODE}) +target_link_libraries(sVencode ${FFMPEG_LIBRARIES} sVflow) +qt5_use_modules(sVencode Core) +qt5_use_modules(sVencode Gui) + +add_library(sVflowtools STATIC ${LIB_SRC_FLOWTOOLS}) +target_link_libraries(sVflowtools sVflow) + +add_library(sVvis STATIC ${LIB_SRC_FLOWVIS}) +qt5_use_modules(sVvis Core) +qt5_use_modules(sVvis Gui) +target_link_libraries(sVvis sVflow ${QT_LIBRARIES}) +
View file
slowmoVideo-0.6.tar.xz/src/lib/avconvInfo_sV.cpp
Changed
(renamed from src/slowmoVideo/lib/avconvInfo_sV.cpp)
View file
slowmoVideo-0.6.tar.xz/src/lib/avconvInfo_sV.h
Changed
(renamed from src/slowmoVideo/lib/avconvInfo_sV.h)
View file
slowmoVideo-0.6.tar.xz/src/lib/bezierTools_sV.cpp
Changed
(renamed from src/slowmoVideo/lib/bezierTools_sV.cpp)
View file
slowmoVideo-0.6.tar.xz/src/lib/bezierTools_sV.h
Changed
(renamed from src/slowmoVideo/lib/bezierTools_sV.h)
View file
slowmoVideo-0.6.tar.xz/src/lib/defs_sV.cpp
Added
@@ -0,0 +1,173 @@ +#include "defs_sV.hpp" + +Error_sV::Error_sV(QString msg) : + m_message(msg) +{ + qDebug() << msg; +} + +QString Error_sV::message() const { + return m_message; +} + +FlowBuildingError::FlowBuildingError(QString msg) : + Error_sV(msg) +{ + qDebug() << "Flow building error: " << msg; +} +FrameSourceError::FrameSourceError(QString msg) : + Error_sV(msg) +{ + qDebug() << "Frame source error: " << msg; +} +InterpolationError::InterpolationError(QString msg) : + Error_sV(msg) +{ + qDebug() << "Interpolation error : " << msg; +} + +QString toString(const QSize &size) +{ + return QString::fromUtf8("%1×%2").arg(size.width()).arg(size.height()); +} + +QString toString(const FrameSize &size) +{ + switch (size) { + case FrameSize_Orig: + return QObject::tr("Orig"); + case FrameSize_Small: + return QObject::tr("Small"); + default: + Q_ASSERT(false); + return QObject::tr("Unknown size"); + } +} + +QString toString(const FlowDirection &dir) +{ + switch (dir) { + case FlowDirection_Forward: + return QObject::tr("Forward"); + case FlowDirection_Backward: + return QObject::tr("Backward"); + default: + Q_ASSERT(false); + return QObject::tr("Unknown direction"); + } +} + +QString toString(const CurveType &curveType) +{ + switch (curveType) { + case CurveType_Linear: + return QObject::tr("Linear"); + case CurveType_Bezier: + return QObject::trUtf8("Bézier"); + default: + Q_ASSERT(false); + return QObject::tr("Unknown curve type"); + } +} + +QString toString(const QPointF &p) +{ + return QString("(%1|%2)").arg(p.x()).arg(p.y()); +} + +QString toString(const TagAxis axis) +{ + switch (axis) { + case TagAxis_Source: + return QObject::tr("Source axis"); + case TagAxis_Output: + return QObject::tr("Output axis"); + default: + Q_ASSERT(false); + return QObject::tr("Unknown axis"); + } +} + +QString toString(const InterpolationType &interpolation) +{ + switch (interpolation) { + case InterpolationType_Forward: + return QObject::tr("Forward interpolation (fast)"); + case InterpolationType_ForwardNew: + return QObject::tr("Forward interpolation (accurate)"); + case InterpolationType_Twoway: + return QObject::tr("Two-way interpolation (fast)"); + case InterpolationType_TwowayNew: + return QObject::tr("Two-way interpolation (accurate)"); + case InterpolationType_Bezier: + return QObject::trUtf8("Bézier interpolation"); + case InterpolationType_None: + return QObject::trUtf8("Linear interpolation"); + case InterpolationType_Nearest: + return QObject::trUtf8("Nearest Frame interpolation"); + default: + return QObject::tr("Unknown interpolation"); + } +} + +QString toString(const MotionblurType &type) +{ + switch (type) { + case MotionblurType_Stacking: + return QObject::tr("Stacking"); + case MotionblurType_Convolving: + return QObject::tr("Convolution"); + case MotionblurType_Nearest: + return QObject::tr("Nearest (no blurring)"); + default: + Q_ASSERT(false); + return QString("Unknown motion blur type"); + } +} + +Fps_sV::Fps_sV(int num, int den) noexcept(false) : + num(num), den(den) +{ + if (den <= 0) { + throw Error_sV("FPS denominator must be >= 0."); + } +} +Fps_sV::Fps_sV(QString fpsString) noexcept(false) +{ + QRegExp e("(\\d+)\\/(\\d+)"); + if (e.exactMatch(fpsString)) { + num = e.cap(1).toInt(); + den = e.cap(2).toInt(); + if (den <= 0) { + throw Error_sV("FPS denominator must be >= 0."); + } + } else { + throw Error_sV("Cannot create fps value from " + fpsString); + } +} +Fps_sV::Fps_sV(float fps) noexcept(false) +{ + if (fps <= 0) { + throw Error_sV(QString("FPS value must be larger than zero (is: %1)").arg(fps)); + } + // Check for 23.976 and similar numbers (24*1000/1001) + if (fabs(1000*ceil(fps)-1001*fps) < 7) { + num = 1000*ceil(fps); + den = 1001; + } else { + num = 100000*fps; + den = 100000; + // Prettify + for (int i = 10; i > 1; i--) { + while (num % i == 0 && den % i == 0) { + num /= i; + den /= i; + } + } + } +} + +QString Fps_sV::toString() const +{ + return QString("%1/%2").arg(num).arg(den); +}
View file
slowmoVideo-0.6.tar.xz/src/lib/defs_sV.h
Changed
(renamed from src/slowmoVideo/lib/defs_sV.h)
View file
slowmoVideo-0.6.tar.xz/src/lib/defs_sV.hpp
Added
@@ -0,0 +1,172 @@ +/* +slowmoVideo creates slow-motion videos from normal-speed videos. +Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +*/ + +#ifndef DEFS_SV_HPP +#define DEFS_SV_HPP + +#include "macros_sV.h" + +#if defined(WINDOWS) && !defined(MXE) +typedef __int64 int64_t; +#else +#include <inttypes.h> +#endif + +#include <QtCore/QDebug> +#include <QtCore/QString> +#include <QtCore/QSize> +#include <QtCore/QPoint> +#include <QtGui/QColor> +#include <cmath> + +#include "version.h" + + +/// Contains information about this slowmoVideo version +namespace Version_sV { + /// Major version number + static int major = SLOWMOVIDEO_VERSION_MAJOR; + /// Minor version number + static int minor = SLOWMOVIDEO_VERSION_MINOR; + /// Micro version number + static int micro = SLOWMOVIDEO_VERSION_PATCH; + /// Version number as string + static QString version_short(QString("%1.%2.%3").arg(major).arg(minor).arg(micro)); + static QString version(SLOWMOVIDEO_VERSION_FULL); + /// Architecture + static QString bits( +#ifdef BITS_64 + "64-bit" +#else + "32-bit" +#endif + ); + /// Platform + static QString platform( +#if defined LINUX + "Linux" +#elif defined OSX + "OSX" +#elif defined WINDOWS + "Windows" +#endif + ); +} + +enum FlowDirection { FlowDirection_Forward, FlowDirection_Backward }; +enum FrameSize { FrameSize_Orig = 1, FrameSize_Small = 2 }; +enum CurveType { CurveType_Linear = 1, CurveType_Bezier = 2 }; +enum TagAxis { TagAxis_Source = 1, TagAxis_Output = 2 }; +enum InterpolationType { InterpolationType_Forward = 0, InterpolationType_ForwardNew = 1, + InterpolationType_Twoway = 10, InterpolationType_TwowayNew = 11, + InterpolationType_Bezier = 20 , InterpolationType_None = 30 , + InterpolationType_Nearest = 40 }; +enum MotionblurType { MotionblurType_Stacking = 0, MotionblurType_Convolving = 10, + MotionblurType_Nearest = 20 }; + +/// Default colours used in slowmoVideo (e.g. in the user interface) +namespace Colours_sV { + static QColor colOk(158, 245, 94); ///< For checked text fields that are OK + static QColor colBad(247, 122, 48); ///< For checked text fields that are invalid +} + + +/// For general errors. +class Error_sV : virtual public std::exception { +public: + /// Creates a new error object with the given information message. + Error_sV(QString msg); + /// Returns the information message. + QString message() const; +private: + QString m_message; +}; + +/// FPS representation, can guess numerator/denominator from a float value. +struct Fps_sV { + /// numerator + int num; + /// denominator + int den; + + Fps_sV(int num, int den) noexcept(false); ///< den must be > 0. + + Fps_sV(float fps) noexcept(false); ///< Converts a float fps number to a fractional. 23.97 and 29.97 are detected. + + Fps_sV(QString fpsString) noexcept(false); ///< Accepts fps strings like 24000/1001 for 23.97 fps. + + QString toString() const; + + /// Frames per second as float. + double fps() const { + return double(num)/den; + } +}; +/// For errors related to building optical flow. +class FlowBuildingError : public Error_sV { +public: + /// Default constructor. + FlowBuildingError(QString msg); +}; +/// For errors related to the frame source. +class FrameSourceError : public Error_sV { +public: + /// Default constructor. + explicit FrameSourceError(QString msg); +}; +class InterpolationError : public Error_sV { +public: + /// Default constructor + InterpolationError(QString msg); +}; + +QString toString(const QSize& size); +QString toString(const FrameSize &size); +QString toString(const FlowDirection &dir); +QString toString(const CurveType &curveType); +QString toString(const QPointF &p); +QString toString(const TagAxis &axis); +QString toString(const InterpolationType &interpolation); +QString toString(const MotionblurType &interpolation); + +inline QDebug operator<<(QDebug qd, const FlowDirection &direction) { + switch (direction) { + case FlowDirection_Forward: + qd << "Forward"; + break; + case FlowDirection_Backward: + qd << "Backward"; + break; + default: + qd << "Unknown direction"; + Q_ASSERT(false); + break; + } + return qd; +} + +inline QDebug operator<<(QDebug qd, const FrameSize &frameSize) +{ + switch(frameSize) { + case FrameSize_Orig: + qd << "Original frame size"; + break; + case FrameSize_Small: + qd << "Small frame size"; + break; + default: + qd << "Unknown frame size"; + Q_ASSERT(false); + break; + } + return qd; +} + +#endif // DEFS_SV_HPP
View file
slowmoVideo-0.6.tar.xz/src/lib/ffmpegEncode_sV.c
Added
@@ -0,0 +1,488 @@ +/* + This code is based on http://ffmpeg.org/doxygen/trunk/encoding_8c-source.html + and http://ffmpeg.org/doxygen/trunk/muxing_8c-source.html + and has been adjusted with a lot of help from Tjoppen at irc.freenode.org#ffmpeg. (Thanks!) + Copyright (c) 2001 Fabrice Bellard + 2011 Simon A. Eugster + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + */ + +#include "ffmpegEncode_sV.h" +#include <libswscale/swscale.h> + +void setErrorMessage(VideoOut_sV *video, const char *msg) +{ + if (video->errorMessage != NULL) { + free(video->errorMessage); + } + video->errorMessage = malloc(strlen(msg)+1); + strcpy(video->errorMessage, msg); +} + +void prepareDefault(VideoOut_sV *video) +{ + prepare(video, "/tmp/ffmpegTest.avi", NULL, 352, 288, 400000, + 1, 24); +} + +int open_video(VideoOut_sV *video) +{ + AVCodec *codec; + AVCodecContext *cc; + + cc = video->streamV->codec; + + /* find the video encoder */ + codec = avcodec_find_encoder(cc->codec_id); + if (!codec) { + char s200; + sprintf(s, "Codec for ID %d could not be found.\n", cc->codec_id); + fputs(s, stderr); + setErrorMessage(video, s); + return 3; + } else { + printf("Codec used: %s\n", codec->name); + } + + /* open the codec */ +#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(53,8,0) + if (avcodec_open(cc, codec) < 0) { +#else + if (avcodec_open2(cc, codec, NULL) < 0) { +#endif + char s200; + sprintf(s, "Could not open codec %s.\n", codec->long_name); + fputs(s, stderr); + return 3; + } + + video->outbufV = NULL; + if (!(video->fc->oformat->flags & AVFMT_RAWPICTURE)) { + /* allocate output buffer */ + /* XXX: API change will be done */ + /* buffers passed into lav* can be allocated any way you prefer, + as long as they're aligned enough for the architecture, and + they're freed appropriately (such as using av_free for buffers + allocated with av_malloc) */ + // \todo av_get_picture_size? + video->outbufSizeV = 200000; + video->outbufV = av_malloc(video->outbufSizeV); + } + return 0; +} + +int prepare(VideoOut_sV *video, const char *filename, const char *vcodec, const int width, const int height, const int bitrate, + const unsigned int numerator, const unsigned int denominator) +{ +#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(53,7,1) + // Must be called before using the avcodec library. (Done automatically in more recent versions.) + avcodec_init(); +#endif + + video->frameNr = 0; + video->errorMessage = NULL; + video->filename = malloc(strlen(filename)+1); + strcpy(video->filename, filename); + + /* initialize libavcodec, and register all codecs and formats */ + av_register_all(); +#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(53,19,0) + avformat_network_init(); +#endif + + /* allocate the output media context */ +#if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(52,45,0) + video->fc = avformat_alloc_context(); + video->fc->oformat = guess_format(NULL, filename, NULL); + strncpy(video->fc->filename, filename, sizeof(video->fc->filename)); +#elif LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(53,4,0) || defined(MOST_LIKELY_LIBAV) + video->fc = avformat_alloc_context(); + video->fc->oformat = av_guess_format(NULL, filename, NULL); + strncpy(video->fc->filename, filename, sizeof(video->fc->filename)); +#else + // Actually introduced in 53.2.0 but not working in 53.3.0 packages + avformat_alloc_output_context2(&video->fc, NULL, NULL, filename); + if (!video->fc) { + printf("Could not deduce output format from file extension: using MPEG.\n"); + avformat_alloc_output_context2(&video->fc, NULL, "mpeg", filename); + } +#endif + if (!video->fc) { + const char *s = "Could allocate the output context, even MPEG is not available.\n"; + fputs(s, stderr); + setErrorMessage(video, s); + return 2; + } + video->format = video->fc->oformat; + printf("Using format %s.\n", video->format->name); + + /* Use the given vcodec if it is not NULL */ + if (vcodec != NULL) { + AVCodec *codec = avcodec_find_encoder_by_name(vcodec); + if (codec == NULL) { + char sstrlen(vcodec)+150; + sprintf(s, "No codec available for %s. Check the output of \nffmpeg -codecs\nto see a list of available codecs.\n", vcodec); + fputs(s, stderr); + setErrorMessage(video, s); + return 2; + } + printf("Found codec: %s\n", codec->long_name); + video->format->video_codec = codec->id; + } + + /* add the audio and video streams using the default format codecs + and initialize the codecs */ + video->streamV = NULL; + if (video->format->video_codec != CODEC_ID_NONE) { + +#if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(53,10,0) + video->streamV = av_new_stream(video->fc, 0); +#else + video->streamV = avformat_new_stream(video->fc, 0); +#endif + if (!video->streamV) { + const char *s = "Could not allocate the video stream.\n"; + fputs(s, stderr); + setErrorMessage(video, s); + return 2; + } + + AVCodecContext *cc = video->streamV->codec; + + cc->codec_id = video->format->video_codec; +#if LIBAVCODEC_VERSION_INT < (52<<16 | 64<<8 | 0) + cc->codec_type = CODEC_TYPE_VIDEO; +#else + cc->codec_type = AVMEDIA_TYPE_VIDEO; +#endif + + cc->bit_rate = bitrate; + + /* resolution must be a multiple of two */ + cc->width = width; + cc->height = height; + + + /* time base: this is the fundamental unit of time (in seconds) in terms + of which frame timestamps are represented. for fixed-fps content, + timebase should be 1/framerate and timestamp increments should be + identically 1. */ + cc->time_base = (AVRational){numerator, denominator}; + + cc->gop_size = 12; /* emit one intra frame every ten frames */ + + + cc->pix_fmt = PIX_FMT_YUV420P; + if (cc->codec_id == CODEC_ID_MPEG2VIDEO || cc->codec_id == CODEC_ID_MPEG4) { + /* just for testing, we also add B frames */ + cc->max_b_frames = 2; + } + if (cc->codec_id == CODEC_ID_MPEG1VIDEO){ + /* Needed to avoid using macroblocks in which some coeffs overflow. + This does not happen with normal video, it just happens here as + the motion of the chroma plane does not match the luma plane. */ + cc->mb_decision=2; + } + // some formats want stream headers to be separate + if(video->fc->oformat->flags & AVFMT_GLOBALHEADER) { + cc->flags |= CODEC_FLAG_GLOBAL_HEADER; + } + + video->rgbConversionContext = sws_getContext( + cc->width, cc->height, + PIX_FMT_BGRA, + cc->width, cc->height, + cc->pix_fmt, + SWS_BICUBIC, NULL, NULL, NULL); + + // One line size for each plane. RGB consists of one plane only. + // (YUV420p consists of 3, Y, Cb, and Cr + video->rgbLinesize0 = cc->width*4; + video->rgbLinesize1 = 0; + video->rgbLinesize2 = 0; + video->rgbLinesize3 = 0; + + if (video->rgbConversionContext == NULL) { + char s200; + sprintf(s, "Cannot initialize the RGB conversion context. Incorrect size (%dx%d)?\n", cc->width, cc->height); + fputs(s, stderr); + setErrorMessage(video, s); + return 2; + } + + + printf("Settings: %dx%d, %d bits/s (tolerance: %d), %d/%d fps\n", cc->width, cc->height, + cc->bit_rate, cc->bit_rate_tolerance, cc->time_base.den, cc->time_base.num); +// printf("Stream settings: %d/%d fps\n", video->streamV->time_base.den, video->streamV->time_base.num); + fflush(stdout); + } else { + const char *s = "No codec ID given.\n"; + fputs(s, stderr); + setErrorMessage(video, s); + return 2; + } + +#if LIBAVFORMAT_VERSION_INT <= AV_VERSION_INT(52,100,1) + dump_format(video->fc, 0, filename, 1); +#else + av_dump_format(video->fc, 0, filename, 1); +#endif + + /* now that all the parameters are set, we can open the audio and + video codecs and allocate the necessary encode buffers */ + if (video->streamV) { + int ret = open_video(video); + if (ret != 0) { + return ret; + } + } else { + const char *s = "Could not open video stream.\n"; + fputs(s, stderr); + setErrorMessage(video, s); + return 2; + } + + + + /* open the output file, if needed */ + if (!(video->format->flags & AVFMT_NOFILE)) { +#if LIBAVFORMAT_VERSION_INT <= AV_VERSION_INT(52,102,0) + if (url_fopen(&video->fc->pb, filename, URL_WRONLY) < 0) { +#else +#if LIBAVFORMAT_VERSION_INT <= AV_VERSION_INT(53,0,0) + if (avio_open(&video->fc->pb, filename, AVIO_WRONLY) < 0) { +#else + if (avio_open(&video->fc->pb, filename, AVIO_FLAG_WRITE) < 0) { +#endif +#endif + + // Check if non-ASCII characters are present in the file path + char nonAscii = 0; + int i; + for (i = 0; i < strlen(video->filename); i++) { + if ((unsigned short)video->filenamei > 0x7f) { + fprintf(stderr, "Contains non-ASCII character: %c (%d)\n", video->filenamei, (unsigned char)video->filenamei); + nonAscii = 1; + } + } + + // Build the error message + char *msg; + if (nonAscii == 1) { + msg = "Could not open file (probably due to non-ASCII characters): "; + } else { + msg = "Could not open file: "; + } + char *msgAll = malloc(sizeof(char) * (strlen(filename) + strlen(msg))); + strcpy(msgAll, msg); + strcat(msgAll, filename); + fputs(msgAll, stderr); + setErrorMessage(video, msgAll); + free(msgAll); + return 5; + } + } + + /* write the stream header, if any */ +#if LIBAVFORMAT_VERSION_INT <= AV_VERSION_INT(53,1,3) + av_write_header(video->fc); +#else + avformat_write_header(video->fc, NULL); +#endif + + + /* alloc image and output buffer */ + video->outbufSizeV = avpicture_get_size(video->streamV->codec->pix_fmt, width, height); + video->outbufV = av_malloc(video->outbufSizeV); + + video->picture = avcodec_alloc_frame(); + //TODO: replace by: av_frame_alloc(); ? + avpicture_alloc((AVPicture*)video->picture, video->streamV->codec->pix_fmt, + video->streamV->codec->width, video->streamV->codec->height); + if (!video->picture) { + const char *s = "Could not allocate AVPicture.\n"; + fputs(s, stderr); + setErrorMessage(video, s); + return 2; + } + + return 0; +} + +int eatARGB(VideoOut_sV *video, const unsigned char *data) +{ + fflush(stdout); + + int ret = 0; + AVCodecContext *cc = video->streamV->codec; + +#if LIBSWSCALE_VERSION_INT < AV_VERSION_INT(0,8,0) + sws_scale(video->rgbConversionContext, + (uint8_t**)&data, video->rgbLinesize, + 0, cc->height, + video->picture->data, video->picture->linesize + ); +#else + sws_scale(video->rgbConversionContext, + &data, video->rgbLinesize, + 0, cc->height, + video->picture->data, video->picture->linesize + ); +#endif + + + if (video->fc->oformat->flags & AVFMT_RAWPICTURE) { + /* raw video case. The API will change slightly in the near + future for that */ + AVPacket pkt; + av_init_packet(&pkt); + +#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(52,30,2) + pkt.flags |= PKT_FLAG_KEY; +#else + pkt.flags |= AV_PKT_FLAG_KEY; +#endif + pkt.stream_index = video->streamV->index; + pkt.data = (uint8_t *)video->picture; + pkt.size = sizeof(AVPicture); + + ret = av_interleaved_write_frame(video->fc, &pkt); + } else { + /* encode the image */ + video->outSize = avcodec_encode_video(cc, video->outbufV, video->outbufSizeV, video->picture); + //TODO: check usage of avcodec_encode_video2 ? + /* if zero size, it means the image was buffered */ + if (video->outSize > 0) { + AVPacket pkt; + av_init_packet(&pkt); + + if (cc->coded_frame->pts != AV_NOPTS_VALUE) { + pkt.pts = av_rescale_q(cc->coded_frame->pts, cc->time_base, video->streamV->time_base); +// printf("pkt.pts is %d.\n", pkt.pts); + } + if(cc->coded_frame->key_frame) { +#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(52,30,2) + pkt.flags |= PKT_FLAG_KEY; +#else + pkt.flags |= AV_PKT_FLAG_KEY; +#endif + } + pkt.stream_index = video->streamV->index; + pkt.data = video->outbufV; + pkt.size = video->outSize; + + /* write the compressed frame in the media file */ + ret = av_interleaved_write_frame(video->fc, &pkt); + } else { + ret = 0; + } + } + if (ret != 0) { + const char *s = "Error while writing video frame (interleaved_write).\n"; + fputs(s, stderr); + setErrorMessage(video, s); + return ret; + } + printf("Added frame %d to %s.\n", video->frameNr, video->filename); + video->frameNr++; + + return ret; +} + +void eatSample(VideoOut_sV *video) +{ + fflush(stdout); + /* prepare a dummy image */ + /* Y */ + int x, y; + for(y = 0; y < video->streamV->codec->height; y++) { + for(x = 0; x < video->streamV->codec->width; x++) { + video->picture->data0y * video->picture->linesize0 + x = x + y + video->frameNr * 3; + } + } + + /* Cb and Cr */ + for(y = 0; y < video->streamV->codec->height/2; y++) { + for(x = 0; x < video->streamV->codec->width/2; x++) { + video->picture->data1y * video->picture->linesize1 + x = 128 + y + video->frameNr * 2; + video->picture->data2y * video->picture->linesize2 + x = 64 + x + video->frameNr * 5; + } + } + + /* encode the image */ + AVCodecContext *cc = video->streamV->codec; + video->outSize = avcodec_encode_video(cc, video->outbufV, video->outbufSizeV, video->picture); + /* if zero size, it means the image was buffered */ + if (video->outSize > 0) { + AVPacket pkt; + av_init_packet(&pkt); + + if (cc->coded_frame->pts != AV_NOPTS_VALUE) { + pkt.pts = av_rescale_q(cc->coded_frame->pts, cc->time_base, video->streamV->time_base); + printf("pkt.pts is %lld.\n", pkt.pts); + } + if(cc->coded_frame->key_frame) { +#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(52,30,2) + pkt.flags |= PKT_FLAG_KEY; +#else + pkt.flags |= AV_PKT_FLAG_KEY; +#endif + } + pkt.stream_index = video->streamV->index; + pkt.data = video->outbufV; + pkt.size = video->outSize; + + /* write the compressed frame in the media file */ + av_interleaved_write_frame(video->fc, &pkt); + } + + video->frameNr++; +} + +void finish(VideoOut_sV *video) +{ + + /* write the trailer, if any. the trailer must be written + * before you close the CodecContexts open when you wrote the + * header; otherwise write_trailer may try to use memory that + * was freed on av_codec_close() */ + av_write_trailer(video->fc); + + /* close each codec */ + if (video->streamV) { + avcodec_close(video->streamV->codec); + av_free(video->picture->data0); + av_free(video->picture); + av_free(video->outbufV); + } + + /* free the streams */ + int i; + for(i = 0; i < video->fc->nb_streams; i++) { + av_freep(&video->fc->streamsi->codec); + av_freep(&video->fc->streamsi); + } + + if (!(video->format->flags & AVFMT_NOFILE)) { + /* close the output file */ +#if LIBAVFORMAT_VERSION_INT <= AV_VERSION_INT(52,106,0) + url_fclose(video->fc->pb); +#else + avio_close(video->fc->pb); +#endif + } + + /* free the stream */ + av_free(video->fc); + + sws_freeContext(video->rgbConversionContext); + printf("\nWrote to %s.\n", video->filename); + + +#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(53,13,0) + avformat_network_deinit(); +#endif +}
View file
slowmoVideo-0.6.tar.xz/src/lib/ffmpegEncode_sV.h
Added
@@ -0,0 +1,87 @@ +#ifndef FFMPEGENCODE_SV_H +#define FFMPEGENCODE_SV_H +/* + Copyright (c) 2011 Simon A. Eugster + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + */ + +#include "defs_sV.h" + +// Against the «UINT64_C not declared» message. +// See: http://code.google.com/p/ffmpegsource/issues/detail?id=11 +#ifdef __cplusplus + #ifndef __STDC_CONSTANT_MACROS + #define __STDC_CONSTANT_MACROS + #ifdef _STDINT_H + #undef _STDINT_H + #endif + # include <stdint.h> + #endif // __STDC_CONSTANT_MACROS +#endif + +#include <libavcodec/avcodec.h> +#include <libavformat/avformat.h> + +#if ((LIBAVFORMAT_VERSION_MAJOR == 53) && (LIBAVFORMAT_VERSION_MINOR >= 21) && (LIBAVFORMAT_VERSION_MICRO < 100)) +#define MOST_LIKELY_LIBAV +#endif + +/// This struct can eat frames and produces videos! +/// Variables should not be changed from the outside. +typedef struct VideoOut_sV { + + AVFrame *picture; ///< Temporary picture for the incoming frame + AVFormatContext *fc; ///< Video's format context + AVOutputFormat *format; ///< Just a shortcut to fc->format + AVStream *streamV; ///< Video output stream + + /// Current frame number that is encoded + int frameNr; + + /// Context for converting RGB frames to YUV420p + struct SwsContext* rgbConversionContext; + /// Required for converting RGB images + int rgbLinesize4; + + /// Video filename + char *filename; + + int outSize; + int outbufSizeV; + uint8_t *outbufV; + + /// Set if an error occurs (file does not exist, for example), for more accurate information. + char *errorMessage; + +} VideoOut_sV; + +/// Prepares a default VideoOut_sV struct, mainly for testing purposes with eatSample(). +void prepareDefault(VideoOut_sV *video); +/** + Prepares a VideoOut_sV struct. After preparation it is ready to eat RGB images. + \param video VideoOut_sV struct to prepare. + \param filename Target filename + \param vcodec Video codec to use (see <tt>ffmpeg -codecs</tt>). May be \c NULL, + in this case a default codec for the format will be chosen. + \param width Video width + \param height Video height + \param bitrate Bit rate. <tt>width*height*fps</tt> seems to be a good choice for high quality. + \param numerator A frame is shown for <tt>numerator/denominator s</tt>; i.e. the fps number is <tt>denominator/numerator</tt>. + \param denominator See numerator. + */ +int prepare(VideoOut_sV *video, const char *filename, const char *vcodec, const int width, const int height, const int bitrate, + const unsigned int numerator, const unsigned int denominator); + +/// Eats an RGB image and deposits it in the output frame. +int eatARGB(VideoOut_sV *video, const unsigned char *data); +/// Eats a sample image. For testing. +void eatSample(VideoOut_sV *video); + +/// Finishes the produced video file. +void finish(VideoOut_sV *video); + +#endif // FFMPEGENCODE_SV_H
View file
slowmoVideo-0.6.tar.xz/src/lib/ffmpeg_writer.cpp
Added
@@ -0,0 +1,189 @@ +/* + * class to export a movie using ffmpeg +*/ +#include <QtCore/QCoreApplication> +#include <QtCore/QProcess> +#include <QtCore/QSettings> +#include <QImage> +#include <QtCore/QRegExp> +#include <QtCore/QTimer> + +#include "video_enc.h" +#include "ffmpeg_writer.h" +//#include "ffmpegEncode_sV.h" +#include "defs_sV.hpp" +// for reporting +#include "../project/renderTask_sV.h" + +QRegExp VideoFFMPEG::regexFrameNumber("frame=\\s*(\\d+)"); + +VideoFFMPEG::VideoFFMPEG(int width,int height,double fps,const char *vcodec,const char* vquality,const char *filename) +{ + m_videoOut = (VideoOut_sV*)malloc(sizeof(VideoOut_sV)); + + m_filename = strdup(filename); + if (vcodec != 0) + m_vcodec = strdup(vcodec); + else + m_vcodec = strdup("libx264"); // -b:v 5000k + + Fps_sV m_fps(fps); + movieFPS = fps; + mHeight = height; + mWidth = width; + +#if 0 + char *pcodec = NULL; + if (m_vcodec.length() > 0) { + pcodec = (char*)malloc(m_vcodec.length()+1); + strcpy(pcodec, m_vcodec.toStdString().c_str()); + } + + int worked = + prepare(m_videoOut, m_filename, pcodec, + width, height, + fps * width * height, + m_fps.den, m_fps.num); + if (worked != 0) { + //TODO: better here + fprintf(stderr,"cannot create FFMPEG encoder\n"); + } +#endif + process = 0; +} + +VideoFFMPEG::~VideoFFMPEG() +{ + //TODO: + //m_dirFramesOrig.rmdir("."); + if (process != 0) { + if (process->state() == QProcess::Running) { + abort(); + process->waitForFinished(); + } + } + free(m_vcodec); + free(m_filename); + free(m_videoOut); +} + +#pragma mark - + +int VideoFFMPEG::writeFrame(const QImage& frame) +{ + //TODO: check this +#if 0 + return eatARGB(m_videoOut, frame.bits()); +#else + return (-1); +#endif +} + +int VideoFFMPEG::exportFrames(QString filepattern,int first,RenderTask_sV *progress) +{ + QSettings settings; + + qDebug() << "exporting frame from : " << filepattern << " to " << m_filename; + + QStringList args; + + args << "-r" << QString::number(movieFPS); + args << "-f" << "image2"; + if (first != 0) + args << "-start_number" << QString::number(first); + args << "-i" << filepattern; + args << "-vcodec" << m_vcodec; + args << "-s" << QString("%1x%2").arg(QString::number(mWidth), QString::number(mHeight)); + args << m_filename; + + qDebug() << "Arguments: " << args; + + this->progress = progress; + last = 0; + process = new QProcess; + //QObject::connect(process, SIGNAL(started()), this, SLOT(processStarted())); + QObject::connect(process, SIGNAL(finished(int)), this, SLOT(encodingFinished(int))); + QObject::connect(process,SIGNAL(readyReadStandardOutput()),this,SLOT(readOutput())); + QObject::connect(process,SIGNAL(readyReadStandardError()),this,SLOT(readOutput())); + QObject::connect(process, SIGNAL(error(QProcess::ProcessError)), + this, SLOT(ffmpegError(QProcess::ProcessError))); + + QObject::connect(process, SIGNAL(stateChanged(QProcess::ProcessState)), this, SLOT(process_state_changed())); + + process->start(settings.value("binaries/ffmpeg", "ffmpeg").toString(), args); + if (!process->waitForStarted()) { + qDebug() << "can't start encoding !"; + process->deleteLater(); + process = 0; + return 1; + } + + // warn: default timeout at 30s ! + process->waitForFinished(-1); // let time goes on ! + qDebug() << process->readAllStandardOutput(); + qDebug() << process->readAllStandardError(); + process->terminate(); + qDebug() << "exit : " << process->exitStatus(); + + delete process; + process = 0; + return 0; +} + +#pragma mark - +#pragma mark C bridge +void VideoFFMPEG::process_state_changed() +{ + if (process->state() == QProcess::Starting) { + qDebug() << "Process is starting up..."; + } + if (process->state() == QProcess::Running) { + qDebug() << "Process is now running."; + } + if (process->state() == QProcess::NotRunning) { + qDebug() << "Process is finished running."; + } +} + +void VideoFFMPEG::processStarted() +{ + qDebug() << "process started"; +} + +void VideoFFMPEG::readOutput() +{ + QRegExp regex(regexFrameNumber); + + //qDebug() << "process read"; + QString line = process->readAllStandardOutput(); + //qDebug() << "got " << line << ""; + line = process->readAllStandardError(); + + if (regex.lastIndexIn(line) >= 0) { + //emit signalTaskProgress(;); + //qDebug() << "prog update : " << regex.cap(1).toInt(); + progress->stepProgress(regex.cap(1).toInt()-last); + last = regex.cap(1).toInt(); + } + //qDebug() << "got " << line; + //TODO: may check if we need to stop/cancel here + // qprocess->kill() ? +} + +void VideoFFMPEG::ffmpegError(QProcess::ProcessError error) +{ + qDebug() << "ffmpeg finish with error : " << error; +} + +void VideoFFMPEG::encodingFinished(int error) +{ + if (error != 0) + qDebug() << "process finish with error : " << error; +} + +VideoWriter* CreateVideoWriter_FFMPEG( const char* filename, int width, int height, double fps, const char *codec) +{ + VideoFFMPEG* driver= new VideoFFMPEG (width,height,fps,codec,0,filename); + return driver; +} +
View file
slowmoVideo-0.6.tar.xz/src/lib/ffmpeg_writer.h
Added
@@ -0,0 +1,67 @@ +/* + * class to export a movie using ffmpeg +*/ + +#ifndef _FFMPEG_WRITER +#define _FFMPEG_WRITER + +#include <QtCore/QProcess> +#include <QImage> +#include <QtCore/QProcess> +#include <QtCore/QRegExp> + +#include "video_enc.h" + +// Against the «UINT64_C not declared» message. +// See: http://code.google.com/p/ffmpegsource/issues/detail?id=11 +#ifdef __cplusplus + #ifndef __STDC_CONSTANT_MACROS + #define __STDC_CONSTANT_MACROS + #ifdef _STDINT_H + #undef _STDINT_H + #endif + # include <stdint.h> + #endif // __STDC_CONSTANT_MACROS +#endif + +extern "C" { +// ffmpeg libs +#include "../lib/ffmpegEncode_sV.h" +} + +class VideoFFMPEG : public QObject, public VideoWriter { + Q_OBJECT + +private: + int mHeight; + int mWidth; + double movieFPS; + + char* m_filename; + char* m_vcodec; + VideoOut_sV *m_videoOut; + + QProcess *process; + static QRegExp regexFrameNumber; + RenderTask_sV *progress; + int last; + +public: + VideoFFMPEG(int width,int height,double fps,const char *vcodec,const char* vquality,const char *filename); + ~VideoFFMPEG(); + + int writeFrame(const QImage& frame); + int exportFrames(QString filepattern,int first, RenderTask_sV *progress); + +public slots: + void processStarted(); + void readOutput(); + void encodingFinished(int); + void ffmpegError(QProcess::ProcessError error); + + private slots: + void process_state_changed(); + +}; + +#endif // _FFMPEG_WRITER
View file
slowmoVideo-0.6.tar.xz/src/lib/flowTools_sV.cpp
Added
@@ -0,0 +1,386 @@ +#include "flowTools_sV.h" +#include <cmath> +#include <cassert> +#include <iostream> + +//#define DEBUG + +void FlowTools_sV::deleteRect(FlowField_sV &field, int top, int left, int bottom, int right) +{ + for (int y = top; y <= bottom; y++) { + for (int x = left; x <= right; x++) { + field.rx(x,y) = FlowField_sV::nullValue; + } + } +} + +void FlowTools_sV::fillRect(FlowField_sV &field, int top, int left, int bottom, int right, float vx, float vy) +{ + for (int y = top; y <= bottom; y++) { + for (int x = left; x <= right; x++) { + field.setX(x,y, vx); + field.setY(x,y, vy); + } + } +} +void FlowTools_sV::refill(FlowField_sV &field, const Kernel_sV &kernel, int top, int left, int bottom, int right) +{ + assert(top <= bottom); + assert(left <= right); + assert(top >= 0); + assert(left >= 0); + assert(bottom < field.height()); + assert(right < field.width()); + + int newTop = top; + int newLeft = left; + int newRight = right; + int newBottom = bottom; + + if (top > 0) { + refillLine(field, kernel, top, left, right-left+1, true); + newTop++; + } + if (left > 0) { + refillLine(field, kernel, top, left, bottom-top+1, false); + newLeft++; + } + if (right+1 < field.width()) { + refillLine(field, kernel, top, right, bottom-top+1, false); + newRight--; + } + if (bottom+1 < field.height()) { + refillLine(field, kernel, bottom, left, right-left+1, true); + newBottom--; + } + + if (newRight-newLeft >= 0 && newBottom-newTop >= 0) { + refill(field, kernel, newTop, newLeft, newBottom, newRight); + } +} + +void FlowTools_sV::refillLine(FlowField_sV &field, const Kernel_sV &kernel, + int startTop, int startLeft, int length, bool horizontal) +{ + int x = startLeft; + int y = startTop; + + float valX = 0; + float valY = 0; + float weight = 0; + + while (true) { + if (x >= field.width() || (horizontal && x >= startLeft+length) + || y >= field.height() || (!horizontal && y >= startTop+length)) { + break; + } + valX = 0; + valY = 0; + weight = 0; + + for (int dx = -kernel.rX(); dx <= kernel.rX(); dx++) { + for (int dy = -kernel.rY(); dy <= kernel.rY(); dy++) { + if (x+dx >= 0 && x+dx < field.width() + && y+dy >= 0 && y+dy < field.height() + && field.x(x+dx,y+dy) != FlowField_sV::nullValue) { + valX += field.x(x+dx,y+dy) * kernel(dx, dy); + valY += field.y(x+dx,y+dy) * kernel(dx, dy); + weight += kernel(dx, dy); + } + } + } + if (weight > 0) { + std::cout << "Before: " << field.rx(x,y); + field.rx(x,y) = valX/weight; + std::cout << ", Afterwards: " << field.rx(x,y) << std::endl; + field.ry(x,y) = valY/weight; + } + + if (horizontal) { + x++; + } else { + y++; + } + + } +} + +void FlowTools_sV::refill(FlowField_sV &field, int top, int left, int bottom, int right) +{ + assert(top <= bottom); + assert(left <= right); + assert(top >= 0); + assert(left >= 0); + assert(bottom < field.height()); + assert(right < field.width()); + + // Top line + if (top == bottom) { + // Only a single line left. Can be inside an image or at a border. + if (top == 0) { + refillLine(field, top, left, right-left+1, HorizontalFromBottom); + } else if (top == field.height()-1) { + refillLine(field, top, left, right-left+1, HorizontalFromTop); + } else { + refillLine(field, top, left, right-left+1, HorizontalFromBoth); + } + } else if (top > 0){ + if (bottom > top) { + // Fill from above + refillLine(field, top, left, right-left+1, HorizontalFromTop); + } else { + // Only a line left; fill from both sides + refillLine(field, top, left, right-left+1, HorizontalFromBoth); + } + } + // Left line + if (left == right) { + if (left == 0) { + refillLine(field, top, left, bottom-top+1, VerticalFromRight); + } else if (left == field.width()-1) { + refillLine(field, top, left, bottom-top+1, VerticalFromLeft); + } else { + refillLine(field, top, left, bottom-top+1, VerticalFromBoth); + } + } else if (left > 0) { + if (right > left) { + refillLine(field, top, left, bottom-top+1, VerticalFromLeft); + } else { + refillLine(field, top, left, bottom-top+1, VerticalFromBoth); + } + } + // Right line + if (right+1 < field.width() && left != right) { // left == right already handled + if (left < right) { + refillLine(field, top, right, bottom-top+1, VerticalFromRight); + } else { + refillLine(field, top, right, bottom-top+1, VerticalFromBoth); + } + } + // Bottom line + if (bottom+1 < field.height() && bottom != top) { // bottom == top already handled + if (top < bottom) { + refillLine(field, bottom, left, right-left+1, HorizontalFromBottom); + } else { + refillLine(field, bottom, left, right-left+1, HorizontalFromBoth); + } + } + refillCorner(field, top, left, TopLeft); + refillCorner(field, top, right, TopRight); + refillCorner(field, bottom, left, BottomLeft); + refillCorner(field, bottom, right, BottomRight); + + if (bottom-top-2 >= 0 && right-left-2 >= 0) { + refill(field, top+(top > 0 ? 1 : 0), left+(left > 0 ? 1 : 0), + bottom-(bottom < field.height()-1 ? 1 : 0), right-(right < field.width()-1 ? 1 : 0)); + + // Now handle special cases where one line at the border was not filled (rect was only 2 pixels wide) + } else if (bottom-top-1 == 0) { + if (top == 0) { + refill(field, top, left, top, right); + } else if (bottom == field.height()-1) { + refill(field, bottom, left, bottom, right); + } + } else if (right-left-1 == 0) { + if (left == 0) { + refill(field, top, left, bottom, left); + } else if (right == field.width()-1) { + refill(field, top, right, bottom, right); + } + } + +} + +void FlowTools_sV::difference(const FlowField_sV &left, const FlowField_sV &right, FlowField_sV &out) +{ + float dx, dy; + for (int y = 0; y < left.height(); y++) { + for (int x = 0; x < left.width(); x++) { + dx = left.x(x,y); + dy = left.y(x,y); + if (x+dx >= 0 && y+dy >= 0 + && x+dx <= left.width()-1 && y+dy <= left.height()-1) { + dx += right.x(x+dx, y+dy); + dy += right.y(x+dx, y+dy); + } + out.setX(x,y, dx); + out.setY(x,y, dy); + } + } +} +void FlowTools_sV::signedDifference(const FlowField_sV &left, const FlowField_sV &right, FlowField_sV &out) +{ + float lx, ly; + float rx, ry; + for (int y = 0; y < left.height(); y++) { + for (int x = 0; x < left.width(); x++) { + lx = left.x(x,y); + ly = left.y(x,y); + if (x+lx >= 0 && y+ly >= 0 + && x+lx <= left.width()-1 && y+ly <= left.height()-1) { + rx = right.x(x+lx, y+ly); + ry = right.y(x+lx, y+ly); + if (fabs(lx)+fabs(ly) > fabs(rx)+fabs(ry)) { + lx = fabs(lx+rx); + ly = fabs(ly+ry); + } else { + lx = -fabs(lx+rx); + ly = -fabs(ly+ry); + } + } else { + lx = fabs(lx); + rx = fabs(rx); + } + out.setX(x,y, lx); + out.setY(x,y, ly); + } + } +} + + + + +void FlowTools_sV::refillLine(FlowField_sV &field, int startTop, int startLeft, int length, LineFillMode fillMode) +{ + int x = startLeft; + int y = startTop; + + float sumX; + float sumY; + short count = 0; + if (fillMode == HorizontalFromTop || fillMode == HorizontalFromBottom || fillMode == HorizontalFromBoth) { + x++; + while (x < startLeft+length) { + sumX = 0; + sumY = 0; + count = 0; + if (fillMode == HorizontalFromTop || fillMode == HorizontalFromBoth) { + sumX += field.x(x-1, y-1) + field.x(x, y-1) + field.x(x+1, y-1); + sumY += field.y(x-1, y-1) + field.y(x, y-1) + field.y(x+1, y-1); + count += 3; + } + if (fillMode == HorizontalFromBottom || fillMode == HorizontalFromBoth) { + sumX += field.x(x-1, y+1) + field.x(x, y+1) + field.x(x+1, y+1); + sumY += field.y(x-1, y+1) + field.y(x, y+1) + field.y(x+1, y+1); + count += 3; + } +#ifdef DEBUG + sumX *= 1.2; + sumY *= 1.2; +#endif + field.rx(x,y) = sumX/count; + field.ry(x,y) = sumY/count; + x++; + } + } else { + y++; + while (y < startTop + length) { + sumX = 0; + sumY = 0; + count = 0; + if (fillMode == VerticalFromLeft || fillMode == VerticalFromBoth) { + sumX += field.x(x-1, y-1) + field.x(x-1, y) + field.x(x-1, y+1); + sumY += field.y(x-1, y-1) + field.y(x-1, y) + field.y(x-1, y+1); + count += 3; + } + if (fillMode == VerticalFromRight || fillMode == VerticalFromBoth) { + sumX += field.x(x+1, y-1) + field.x(x+1, y) + field.x(x+1, y+1); + sumY += field.y(x+1, y-1) + field.y(x+1, y) + field.y(x+1, y+1); + count += 3; + } +#ifdef DEBUG + sumX *= 1.2; + sumY *= 1.2; +#endif + field.rx(x,y) = sumX/count; + field.ry(x,y) = sumY/count; + y++; + } + } +} + +void FlowTools_sV::refillCorner(FlowField_sV &field, int top, int left, CornerPosition pos) +{ + int dx; + int dy; + if (pos == TopRight || pos == BottomRight) { + dx = 1; + } else { + dx = -1; + } + if (pos == TopRight || pos == TopLeft) { + dy = -1; + } else { + dy = 1; + } + float sumX = 0; + float sumY = 0; + int count = 0; + if (left+dx > 0 && top+dy > 0 + && left+dx < field.width() && top+dy < field.height()) { + sumX += field.x(left+dx, top+dy); + sumY += field.y(left+dx, top+dy); + count++; + } + if (left+dx > 0 && top-dy > 0 + && left+dx < field.width() && top-dy < field.height()) { + sumX += field.x(left+dx, top-dy); + sumY += field.y(left+dx, top-dy); + count++; + } + if (left-dx > 0 && top+dy > 0 + && left-dx < field.width() && top+dy < field.height()) { + sumX += field.x(left-dx, top+dy); + sumY += field.y(left-dx, top+dy); + count++; + } +#ifdef DEBUG + sumX = 100; + sumY = 100; +#endif + field.rx(left,top) = sumX/count; + field.ry(left,top) = sumY/count; +} + + +FlowField_sV* FlowTools_sV::median(const FlowField_sV *const fa, const FlowField_sV *const fb, const FlowField_sV *const fc) +{ + assert(fa != NULL); + assert(fb != NULL); + assert(fc != NULL); + assert(fa->width() == fb->width() && fa->width() == fc->width()); + assert(fa->height() == fb->height() && fa->height() == fc->height()); + + int w = fa->width(); + int h = fa->height(); + FlowField_sV *ff = new FlowField_sV(w, h); + + for (int y = 0; y < h; y++) { + for (int x = 0; x < w; x++) { + float a = fa->x(x,y)*fa->x(x,y) + fa->y(x,y)*fa->y(x,y); + float b = fb->x(x,y)*fb->x(x,y) + fb->y(x,y)*fb->y(x,y); + float c = fc->x(x,y)*fc->x(x,y) + fc->y(x,y)*fc->y(x,y); + + // Determine the median + // < a b c + // a - ? ? + // b ? - ? + // c ? ? - + // The median element has SUM == 1 for its row + char detA = (a < b) + (a < c); + char detB = (b < a) + (b < c); + + if (detA == 1) { + ff->rx(x,y) = fa->x(x,y); + ff->ry(x,y) = fa->y(x,y); + } else if (detB == 1) { + ff->rx(x,y) = fb->x(x,y); + ff->ry(x,y) = fb->y(x,y); + } else { + ff->rx(x,y) = fc->x(x,y); + ff->ry(x,y) = fc->y(x,y); + } + } + } + return ff; +}
View file
slowmoVideo-0.6.tar.xz/src/lib/flowTools_sV.h
Added
@@ -0,0 +1,40 @@ +#ifndef FLOWTOOLS_SV_H +#define FLOWTOOLS_SV_H + +#include "flowField_sV.h" +#include "kernel_sV.h" + +class FlowTools_sV +{ +public: + enum LineFillMode { HorizontalFromTop, HorizontalFromBottom, HorizontalFromBoth, + VerticalFromLeft, VerticalFromRight, VerticalFromBoth }; + + enum CornerPosition { TopLeft, TopRight, BottomLeft, BottomRight }; + + static void difference(const FlowField_sV &left, const FlowField_sV &right, FlowField_sV &out); + static void signedDifference(const FlowField_sV &left, const FlowField_sV &right, FlowField_sV &out); + + static void deleteRect(FlowField_sV &field, int top, int left, int bottom, int right); + + /** + \brief Clears the content of the given rectangle and fills it with the surrounding pixels. + + The coordinates are inclusive, so filling <code>(0,0,1,1)</code> fills four pixels. The axis origin <code>(0|0)</code> + is at top left. + */ + static void refill(FlowField_sV &field, int top, int left, int bottom, int right); + + static void refill(FlowField_sV &field, const Kernel_sV &kernel, int top, int left, int bottom, int right); + + static FlowField_sV* median(FlowField_sV const * const fa, FlowField_sV const * const fb, FlowField_sV const * const fc); + + static void fillRect(FlowField_sV &field, int top, int left, int bottom, int right, float vx, float vy); + +private: + static void refillLine(FlowField_sV &field, int startTop, int startLeft, int length, LineFillMode fillMode); + static void refillLine(FlowField_sV &field, const Kernel_sV &kernel, int startTop, int startLeft, int length, bool horizontal); + static void refillCorner(FlowField_sV &field, int top, int left, CornerPosition pos); +}; + +#endif // FLOWTOOLS_SV_H
View file
slowmoVideo-0.6.tar.xz/src/lib/flowVisualization_sV.cpp
Changed
(renamed from src/slowmoVideo/lib/flowVisualization_sV.cpp)
View file
slowmoVideo-0.6.tar.xz/src/lib/flowVisualization_sV.h
Changed
(renamed from src/slowmoVideo/lib/flowVisualization_sV.h)
View file
slowmoVideo-0.6.tar.xz/src/lib/intMatrix_sV.cpp
Changed
(renamed from src/slowmoVideo/lib/intMatrix_sV.cpp)
View file
slowmoVideo-0.6.tar.xz/src/lib/intMatrix_sV.h
Changed
(renamed from src/slowmoVideo/lib/intMatrix_sV.h)
View file
slowmoVideo-0.6.tar.xz/src/lib/interpolate_sV.cpp
Added
@@ -0,0 +1,495 @@ +/* +slowmoVideo creates slow-motion videos from normal-speed videos. +Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +*/ + +#include "interpolate_sV.h" +#include "flowField_sV.h" +#include "flowTools_sV.h" +#include "sourceField_sV.h" +#include "vector_sV.h" +#include "bezierTools_sV.h" + +#ifdef WINDOWS +#include <math.h> +#else +#include <cmath> +#endif + +#include <QDebug> +#include <QImage> +#include <QColor> + +#define CLAMP1(x) ( ((x) > 1.0) ? 1.0 : (x) ) +#define CLAMP(x,min,max) ( ((x) < (min)) ? (min) : ( ((x) > (max)) ? (max) : (x) ) ) + +#define INTERPOLATE +//#define FIX_FLOW +#define FIX_BORDERS +//#define DEBUG_I + +enum ColorComponent { CC_Red, CC_Green, CC_Blue }; + + +inline +float interpR(const QColor cols22, float x, float y) +{ + return (1-x)*(1-y) * cols00.redF() + + x*(1-y) * cols10.redF() + + y*(1-x) * cols01.redF() + + x*y * cols11.redF(); +} + +inline +float interpG(const QColor cols22, float x, float y) +{ + return (1-x)*(1-y) * cols00.greenF() + + x*(1-y) * cols10.greenF() + + y*(1-x) * cols01.greenF() + + x*y * cols11.greenF(); +} + +inline +float interpB(const QColor cols22, float x, float y) +{ + return (1-x)*(1-y) * cols00.blueF() + + x*(1-y) * cols10.blueF() + + y*(1-x) * cols01.blueF() + + x*y * cols11.blueF(); +} + +QColor Interpolate_sV::interpolate(const QImage& in, float x, float y) +{ +#ifdef DEBUG_I + if (x >= in.width()-1 || y >= in.height()-1) { + Q_ASSERT(false); + } +#endif + QColor carr22; + int floorX = floor(x); + int floorY = floor(y); + carr00 = QColor(in.pixel(floorX, floorY)); + carr01 = QColor(in.pixel(floorX, floorY+1)); + carr10 = QColor(in.pixel(floorX+1, floorY)); + carr11 = QColor(in.pixel(floorX+1, floorY+1)); + + float dx = x - floorX; + float dy = y - floorY; + QColor out = QColor::fromRgbF( + interpR(carr, dx, dy), + interpG(carr, dx, dy), + interpB(carr, dx, dy) + ); + return out; +} + +/// validated. correct. +QColor Interpolate_sV::blend(const QColor &left, const QColor &right, float pos) +{ + Q_ASSERT(pos >= 0 && pos <= 1); + + float r = (1-pos)*left.redF() + pos*right.redF(); + float g = (1-pos)*left.greenF() + pos*right.greenF(); + float b = (1-pos)*left.blueF() + pos*right.blueF(); + float a = (1-pos)*left.alphaF() + pos*right.alphaF(); + r = CLAMP(r,0.0,1.0); + g = CLAMP(g,0.0,1.0); + b = CLAMP(b,0.0,1.0); + a = CLAMP(a,0.0,1.0); + return QColor::fromRgbF(r, g, b, a); +} + +void Interpolate_sV::blend(ColorMatrix4x4 &c, const QColor &blendCol, float posX, float posY) +{ + Q_ASSERT(posX >= 0 && posX <= 1); + Q_ASSERT(posY >= 0 && posY <= 1); + + if (c.c00.alpha() == 0) { c.c00 = blendCol; } + else { c.c00 = blend(c.c00, blendCol, std::sqrt((1-posX) * (1-posY))); } + + if (c.c10.alpha() == 0) { c.c10 = blendCol; } + else { c.c10 = blend(c.c10, blendCol, std::sqrt( posX * (1-posY))); } + + if (c.c01.alpha() == 0) { c.c01 = blendCol; } + else { c.c01 = blend(c.c01, blendCol, std::sqrt((1-posX) * posY)); } + + if (c.c11.alpha() == 0) { c.c11 = blendCol; } + else {c.c11 = blend(c.c11, blendCol, std::sqrt(posX * posY)); } +} + + +void Interpolate_sV::twowayFlow(const QImage &left, const QImage &right, const FlowField_sV *flowForward, const FlowField_sV *flowBackward, float pos, QImage &output) +{ +#ifdef INTERPOLATE + const float Wmax = left.width()-1.0001; // A little less than the maximum pixel to avoid out of bounds when interpolating + const float Hmax = left.height()-1.0001; + float posX, posY; +#endif + + QColor colOut, colLeft, colRight; + float r,g,b; + Interpolate_sV::Movement forward, backward; + + for (int y = 0; y < left.height(); y++) { + for (int x = 0; x < left.width(); x++) { + forward.moveX = flowForward->x(x, y); + forward.moveY = flowForward->y(x, y); + + backward.moveX = flowBackward->x(x, y); + backward.moveY = flowBackward->y(x, y); + +#ifdef INTERPOLATE + posX = x - pos*forward.moveX; + posY = y - pos*forward.moveY; + posX = CLAMP(posX, 0, Wmax); + posY = CLAMP(posY, 0, Hmax); + colLeft = interpolate(left, posX, posY); + + posX = x - (1-pos)*backward.moveX; + posY = y - (1-pos)*backward.moveY; + posX = CLAMP(posX, 0, Wmax); + posY = CLAMP(posY, 0, Hmax); + colRight = interpolate(right, posX, posY); +#else + colLeft = QColor(left.pixel(x - pos*forward.moveX, y - pos*forward.moveY)); + colRight = QColor(right.pixel(x - (1-pos)*backward.moveX , y - (1-pos)*backward.moveY)); +#endif + r = (1-pos)*colLeft.redF() + pos*colRight.redF(); + g = (1-pos)*colLeft.greenF() + pos*colRight.greenF(); + b = (1-pos)*colLeft.blueF() + pos*colRight.blueF(); + colOut = QColor::fromRgbF( + CLAMP1(r), + CLAMP1(g), + CLAMP1(b) + ); + output.setPixel(x,y, colOut.rgb()); + } + } +} + + +void Interpolate_sV::newTwowayFlow(const QImage &left, const QImage &right, + const FlowField_sV *flowLeftRight, const FlowField_sV *flowRightLeft, + float pos, QImage &output) +{ + const int W = left.width(); + const int H = left.height(); + + + SourceField_sV leftSourcePixel(flowLeftRight, pos); + leftSourcePixel.inpaint(); + SourceField_sV rightSourcePixel(flowRightLeft, 1-pos); + rightSourcePixel.inpaint(); + + float aspect = 1 - (.5 + std::cos(M_PI*pos)/2); + +#if defined(FIX_FLOW) + FlowField_sV diffField(flowLeftRight->width(), flowLeftRight->height()); + FlowTools_sV::difference(*flowLeftRight, *flowRightLeft, diffField); + float diffSum; + float tmpAspect; +#endif + +#ifdef FIX_BORDERS + bool leftOk; + bool rightOk; +#endif + + + float fx, fy; + QColor colLeft, colRight; + for (int y = 0; y < H; y++) { + for (int x = 0; x < W; x++) { + +#ifdef FIX_BORDERS + fx = leftSourcePixel.at(x,y).fromX; + fy = leftSourcePixel.at(x,y).fromY; + if (fx >= 0 && fx < W-1 + && fy >= 0 && fy < H-1) { + colLeft = interpolate(left, fx, fy); + leftOk = true; + } else { + fx = leftSourcePixel.at(x,y).fromX; + fy = leftSourcePixel.at(x,y).fromY; + fx = CLAMP(fx, 0, W-1.01); + fy = CLAMP(fy, 0, H-1.01); + colLeft = interpolate(left, fx, fy); + leftOk = false; + } + + fx = rightSourcePixel.at(x,y).fromX; + fy = rightSourcePixel.at(x,y).fromY; + if (fx >= 0 && fx < W-1 + && fy >= 0 && fy < H-1) { + colRight = interpolate(right, fx, fy); + rightOk = true; + } else { + colRight = qRgb(0,255,0); + rightOk = false; + } + + if (leftOk && rightOk) { + output.setPixel(x,y, blend(colLeft, colRight, aspect).rgba()); + } else if (rightOk) { + output.setPixel(x,y, colRight.rgba()); +// output.setPixel(x,y, qRgb(255, 0, 0)); + } else if (leftOk) { + output.setPixel(x,y, colLeft.rgba()); +// output.setPixel(x,y, qRgb(0, 255, 0)); + } else { + output.setPixel(x,y, colLeft.rgba()); + } +#else + fx = leftSourcePixel.at(x,y).fromX; + fy = leftSourcePixel.at(x,y).fromY; + fx = CLAMP(fx, 0, W-1.01); + fy = CLAMP(fy, 0, H-1.01); + colLeft = interpolate(left, fx, fy); + +#ifdef FIX_FLOW + diffSum = diffField.x(fx, fy)+diffField.y(fx, fy); + if (diffSum > 5) { + tmpAspect = 0; + } else if (diffSum < -5) { + tmpAspect = 1; + } else { + tmpAspect = aspect; + } +#endif + + fx = rightSourcePixel.at(x,y).fromX; + fy = rightSourcePixel.at(x,y).fromY; + fx = CLAMP(fx, 0, W-1.01); + fy = CLAMP(fy, 0, H-1.01); + colRight = interpolate(right, fx, fy); + +#ifdef FIX_FLOW + diffSum = diffField.x(fx, fy)+diffField.y(fx, fy); + if (diffSum < 5) { + tmpAspect = 0; + } else if (diffSum > -5) { + tmpAspect = 1; + } +#endif + +#ifdef FIX_FLOW + output.setPixel(x,y, blend(colLeft, colRight, tmpAspect).rgba()); +#else + output.setPixel(x,y, blend(colLeft, colRight, aspect).rgba()); +#endif + +#endif + } + } +} + +void Interpolate_sV::forwardFlow(const QImage &left, const FlowField_sV *flow, float pos, QImage &output) +{ + qDebug() << "Interpolating flow at offset " << pos; +#ifdef INTERPOLATE + float posX, posY; + const float Wmax = left.width()-1.0001; + const float Hmax = left.height()-1.0001; +#endif + + QColor colOut; + Interpolate_sV::Movement forward; + + for (int y = 0; y < left.height(); y++) { + for (int x = 0; x < left.width(); x++) { + // Forward flow from the left to the right image tells for each pixel in the right image + // from which location in the left image the pixel has come from. + forward.moveX = flow->x(x, y); + forward.moveY = flow->y(x, y); + + + posX = x - pos*forward.moveX; + posY = y - pos*forward.moveY; + posX = CLAMP(posX, 0, Wmax); + posY = CLAMP(posY, 0, Hmax); +#ifdef INTERPOLATE + colOut = interpolate(left, posX, posY); +#else + colOut = QColor(left.pixel(posX, posY)); +#endif + output.setPixel(x,y, colOut.rgb()); + } + } +} + +void Interpolate_sV::newForwardFlow(const QImage &left, const FlowField_sV *flow, float pos, QImage &output) +{ + const int W = left.width(); + const int H = left.height(); + + // Calculate the source flow field + SourceField_sV field(flow, pos); + field.inpaint(); + + // Draw the pixels + float fx, fy; + for (int y = 0; y < H; y++) { + for (int x = 0; x < W; x++) { + // Since interpolate() uses the floor()+1 values, + // set the maximum to a little less than size-1 + // such that the pixel always lies inside. + fx = field.at(x,y).fromX; + fx = CLAMP(fx, 0, W-1.01); + fy = field.at(x,y).fromY; + fy = CLAMP(fy, 0, H-1.01); + output.setPixel(x,y, interpolate(left, fx, fy).rgba()); + } + } +} + + +/** + \todo fix bézier interpolation + \code + C prev + / / + / / + / / + A curr + \ + \ + B next (can be NULL) + \endcode + */ +void Interpolate_sV::bezierFlow(const QImage &prev, const QImage &right, const FlowField_sV *flowPrevCurr, const FlowField_sV *flowCurrNext, float pos, QImage &output) +{ + const float Wmax = prev.width()-1.0001; + const float Hmax = prev.height()-1.0001; + + Vector_sV a, b, c; + Vector_sV Ta, Sa; + float dist; + + QColor colOut; + + for (int y = 0; y < prev.height(); y++) { + for (int x = 0; x < prev.width(); x++) { + + a = Vector_sV(x, y); + // WHY minus? + c = a + Vector_sV(flowPrevCurr->x(x, y), flowPrevCurr->y(x, y)); + if (flowCurrNext != NULL) { + b = a + Vector_sV(flowCurrNext->x(x,y), flowCurrNext->y(x,y)); + } else { + b = a; + } + + dist = (b-a).length() + (c-a).length(); + if (dist > 0) { + Ta = b + ( (b-a).length() / dist ) * (c-b); + Sa = (Ta - a).rotate90(); + Sa = a + Sa; + + } else { + Sa = a; + } +#ifdef DEBUG_I + Sa = a; +#endif + + QPointF position = BezierTools_sV::interpolate(pos, c.toQPointF(), c.toQPointF(), Sa.toQPointF(), a.toQPointF()); + position.rx() = x - pos*flowPrevCurr->x(x,y); + position.ry() = y - pos*flowPrevCurr->y(x,y); + position.rx() = CLAMP(position.x(), 0, Wmax); + position.ry() = CLAMP(position.y(), 0, Hmax); + +#ifdef DEBUG_I +// if (x == 100 && y == 100 && false) { +// qDebug() << "Interpolated from " << toString(c.toQPointF()) << ", " << toString(a.toQPointF()) << ", " +// << toString(b.toQPointF()) << " at " << pos << ": " << toString(position); +// } + if (y % 4 == 0) { + position.rx() = x; + position.ry() = y; + } +#endif + + colOut = interpolate(prev, position.x(), position.y()); + +#ifdef DEBUG_I + if (y % 4 == 1 && x % 2 == 0) { + colOut = right.pixel(x, y); + } +#endif + output.setPixel(x,y, colOut.rgb()); + + } + } + + /* + for (int y = 0; y < prev.height(); y++) { + for (int x = 1; x < prev.width()-1; x++) { + if (qAlpha(output.pixel(x,y)) == 0 + && qAlpha(output.pixel(x-1,y)) > 0 + && qAlpha(output.pixel(x+1,y)) > 0) { + output.setPixel(x,y, qRgba( + (qRed(output.pixel(x-1,y)) + qRed(output.pixel(x+1,y)))/2, + (qGreen(output.pixel(x-1,y)) + qGreen(output.pixel(x+1,y)))/2, + (qBlue(output.pixel(x-1,y)) + qBlue(output.pixel(x+1,y)))/2, + (qAlpha(output.pixel(x-1,y)) + qAlpha(output.pixel(x+1,y)))/2 + )); + } + } + } + for (int x = 0; x < prev.width(); x++) { + for (int y = 1; y < prev.height()-1; y++) { + if (qAlpha(output.pixel(x,y)) == 0 + && qAlpha(output.pixel(x,y-1)) > 0 + && qAlpha(output.pixel(x,y+1)) > 0) { + output.setPixel(x,y, qRgba( + (qRed(output.pixel(x,y-1)) + qRed(output.pixel(x,y+1)))/2, + (qGreen(output.pixel(x,y-1)) + qGreen(output.pixel(x,y+1)))/2, + (qBlue(output.pixel(x,y-1)) + qBlue(output.pixel(x,y+1)))/2, + (qAlpha(output.pixel(x,y-1)) + qAlpha(output.pixel(x,y+1)))/2 + )); + } + } + } + */ +} + +/** + * simple linear in time itnerpolation + */ +void Interpolate_sV::simpleinterpolate(const QImage &prev, const QImage &right, float pos, QImage &output) +{ + + QColor colOut; + + for (int y = 0; y < prev.height(); y++) { + for (int x = 0; x < prev.width(); x++) { + QRgb lt = prev.pixel(x,y); + QRgb rt = right.pixel(x,y); + + int red = CLAMP((1-pos)*qRed(lt)+(pos)*qRed(rt),0,255); + int green = CLAMP((1-pos)*qGreen(lt)+(pos)*qGreen(rt),0,255); + int blue = CLAMP((1-pos)*qBlue(lt)+(pos)*qBlue(rt),0,255); + + QColor out = QColor::fromRgb(red,green,blue); + + output.setPixel(x,y, out.rgb()); + } /* for x */ + } /* for y */ +} + +/** + * simple nearest frame interoplation + */ +void Interpolate_sV::nearestinterpolate(const QImage &prev, const QImage &right, float pos, QImage &output) +{ + + if (pos<0.5) + output = prev; + else + output = right; +}
View file
slowmoVideo-0.6.tar.xz/src/lib/interpolate_sV.h
Added
@@ -0,0 +1,72 @@ +/* +slowmoVideo creates slow-motion videos from normal-speed videos. +Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +*/ + +#include <QtGui/QColor> + +class QImage; +class FlowField_sV; + +/** + \short Provides interpolation methods between frames + \todo Half resolution for optical flow + */ +class Interpolate_sV { + + public: + /** \fn forwardFlow() + Interpolates a frame using only the flow from the first to the second frame. + This algorithm is simplified and only partly correct since it assumes the flow field + to tell where a pixel came from and not where it went to, which usually leads to artifacts + like on object boundaries or like objects that do not move as far as they should, + but is much easier to interpolate. + */ + /** \fn newForwardFlow + Like forwardFlow(), but uses the forward flow correctly. This includes more work like + filling holes if an object expanded (a pixel then becomes larger, or «multiplies», which cannot + be expressed with usual optical flow (<em>where did the pixel go to?</em> cannot be answered + since it went to multiple locations). The benefit is that this algorithm works more precisely. + */ + /** \fn twowayFlow() + Interpolates a frame using optical flow from the first to the second frame, as well as from the second to the first frame. + */ + /** \fn newTwowayFlow() + Like twowayFlow(), but uses forward and backward flow correctly. See also newForwardFlow(). + */ + /** + \fn interpolate(const QImage &in, float x, float y) + \brief Interpolates the colour at position <code>(x|y)</code>. + + \c x should fulfil \f$ 0 \leq x < width-1 \f$, same with y, to avoid reading outside the image. + Not tested inside the function for efficiency reasons. + */ + static void forwardFlow(const QImage& left, const FlowField_sV *flow, float pos, QImage& output); + static void newForwardFlow(const QImage& left, const FlowField_sV *flow, float pos, QImage& output); + static void twowayFlow(const QImage& left, const QImage& right, const FlowField_sV *flowForward, const FlowField_sV *flowBackward, float pos, QImage& output); + static void newTwowayFlow(const QImage &left, const QImage &right, const FlowField_sV *flowLeftRight, const FlowField_sV *flowRightLeft, float pos, QImage &output); + static void bezierFlow(const QImage& left, const QImage& right, const FlowField_sV *flowCurrPrev, const FlowField_sV *flowCurrNext, float pos, QImage &output); + static QColor interpolate(const QImage& in, float x, float y); + + + static void simpleinterpolate(const QImage& left, const QImage& right, float pos, QImage &output); + static void nearestinterpolate(const QImage& left, const QImage& right, float pos, QImage &output); + +private: + struct Movement { + float moveX; + float moveY; + }; + struct ColorMatrix4x4 { + QColor c00, c10, c01, c11; + }; + + static void blend(ColorMatrix4x4& colors, const QColor &blendCol, float posX, float posY); + static QColor blend(const QColor& left, const QColor& right, float pos); + +};
View file
slowmoVideo-0.6.tar.xz/src/lib/kernel_sV.cpp
Changed
(renamed from src/slowmoVideo/lib/kernel_sV.cpp)
View file
slowmoVideo-0.6.tar.xz/src/lib/kernel_sV.h
Changed
(renamed from src/slowmoVideo/lib/kernel_sV.h)
View file
slowmoVideo-0.6.tar.xz/src/lib/libsvflow
Added
+(directory)
View file
slowmoVideo-0.6.tar.xz/src/lib/libsvflow/.github
Added
+(directory)
View file
slowmoVideo-0.6.tar.xz/src/lib/libsvflow/.github/workflows
Added
+(directory)
View file
slowmoVideo-0.6.tar.xz/src/lib/libsvflow/.github/workflows/main.yml
Added
@@ -0,0 +1,31 @@ +# This is a basic workflow to help you get started with Actions + +name: Build + +# Controls when the action will run. Triggers the workflow on push or pull request +# events but only for the master branch +on: + push: + branches: master + pull_request: + branches: master + +# A workflow run is made up of one or more jobs that can run sequentially or in parallel +jobs: + # This workflow contains a single job called "build" + build: + # The type of runner that the job will run on + runs-on: ubuntu-latest + + # Steps represent a sequence of tasks that will be executed as part of the job + steps: + # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it + - uses: actions/checkout@v2 + + - name: Build CMake + uses: ashutoshvarma/action-cmake-build@v1 + with: + # CMake build type (Release, Debug, MinSizeRel, RelWithDebInfo) + build-type: Debug + # Update git submodules + submodule-update: true
View file
slowmoVideo-0.6.tar.xz/src/lib/libsvflow/CMakeLists.txt
Added
@@ -0,0 +1,26 @@ +# Follows this post: https://stackoverflow.com/a/45843676/271961 + +cmake_minimum_required(VERSION 3.0) + +set(CMAKE_CXX_STANDARD 14) + +if (CMAKE_VERSION VERSION_LESS 3.9) + project(libsvflow VERSION 1.0.0) +else () + project(libsvflow VERSION 1.0.0 DESCRIPTION "Library for optical flow files") +endif () + +set(LIB_SRC_FLOW + src/flowRW_sV.cpp + src/flowField_sV.cpp + ) +set(HEADERS + include/flowRW_sV.h + include/flowField_sV.h + ) + + +add_library(sVflow STATIC ${LIB_SRC_FLOW}) +set_target_properties(sVflow PROPERTIES VERSION ${PROJECT_VERSION}) +target_include_directories(sVflow PUBLIC src) +target_include_directories(sVflow PUBLIC include)
View file
slowmoVideo-0.6.tar.xz/src/lib/libsvflow/README.md
Added
@@ -0,0 +1,3 @@ +# libsvflow + +This repository contains some basic libraries for optical flow. \ No newline at end of file
View file
slowmoVideo-0.6.tar.xz/src/lib/libsvflow/include
Added
+(directory)
View file
slowmoVideo-0.6.tar.xz/src/lib/libsvflow/include/flowField_sV.h
Changed
(renamed from src/slowmoVideo/lib/flowField_sV.h)
View file
slowmoVideo-0.6.tar.xz/src/lib/libsvflow/include/flowRW_sV.h
Added
@@ -0,0 +1,79 @@ +/* +slowmoVideo creates slow-motion videos from normal-speed videos. +Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +*/ + +#ifndef FLOWRW_SV_H +#define FLOWRW_SV_H + +#include <string> +#include <stdexcept> + +class FlowField_sV; + +/** + \brief Reads and writes Optical Flow fields. + + Binary format description: + \code + "flow_sV" 0x1(char) width(int) height(int) + x0(float) y0(float) x1 y1 x2 y2 ... xwidth*height-1 ywidth*height-1 + \endcode + The number after \c flow_sV describes the file version, this allows to e.g. add compression + in future. Width and height should match the image resolution. The following flow data + describes the movement of each pixel in x and y direction. + \see FlowField_sV + */ +class FlowRW_sV +{ +public: + + /// Holds information about a flow file + struct FlowInfo_sV { + /// Flow field width + int width; + /// Flow field height + int height; + /// Flow field version for future changes in the file format + char version; + /// Magic number (first few bytes) + std::string magic; + /// Should be set to true if the flow is valid (valid magic number, valid version etc.) + bool valid; + /// Initially set to invalid. + FlowInfo_sV() { + magic = "flow_sV"; + version = '1'; + valid = false; + } + }; + + struct FlowRWError : virtual public std::runtime_error { + explicit FlowRWError(const std::string &msg) : runtime_error(msg) {} + }; + + /** \fn load(std::string) + \return \c NULL, if the file could not be loaded, and the flow field otherwise. + */ + /** \fn save(std::string, FlowField_sV*); + \see FlowField_sV::FlowField_sV(int, int, float*, FlowField_sV::GLFormat) + */ + /** \fn readInfo(std::string) + \return Information about the flow file (like dimension); Does not read the whole file and is therefore faster than load(std::string). + */ + static void save(std::string filename, FlowField_sV *flowField); + static FlowField_sV* load(std::string filename) noexcept(false); + + static FlowInfo_sV readInfo(std::string filename); + +private: + static const std::string m_magicNumber; + static const char m_version; +}; + +#endif // FLOWRW_SV_H
View file
slowmoVideo-0.6.tar.xz/src/lib/libsvflow/src
Added
+(directory)
View file
slowmoVideo-0.6.tar.xz/src/lib/libsvflow/src/flowField_sV.cpp
Added
@@ -0,0 +1,111 @@ +/* +slowmoVideo creates slow-motion videos from normal-speed videos. +Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +*/ + +#include "../include/flowField_sV.h" +#include "string.h" +#include <iostream> + +float FlowField_sV::nullValue = 65535; + +FlowField_sV::FlowField_sV(int width, int height) : + m_width(width), + m_height(height) +{ + m_data = new float2*m_width*m_height; +} + +FlowField_sV::FlowField_sV(int width, int height, float *data, FlowField_sV::GLFormat format) : + m_width(width), + m_height(height) +{ + m_data = new float2*m_width*m_height; + + switch (format) { + case GLFormat_RG: + memcpy(m_data, data, width*height*2*sizeof(float)); + break; + case GLFormat_RGB: + default: + float *fieldData = m_data; + int pos = 0; + for (int i = 0; i < width*height; i++) { + *(fieldData++) = datapos++; + *(fieldData++) = datapos++; + pos++; + } + } +} + +FlowField_sV::~FlowField_sV() +{ + delete m_data; +} + +float FlowField_sV::x(int x, int y) const +{ + return m_data2*(y*m_width+x)+0; +} +float FlowField_sV::y(int x, int y) const +{ + return m_data2*(y*m_width+x)+1; +} + +float& FlowField_sV::rx(int x, int y) +{ + return m_data2*(y*m_width+x)+0; +} +float& FlowField_sV::ry(int x, int y) +{ + return m_data2*(y*m_width+x)+1; +} + +void FlowField_sV::setX(int x, int y, float value) +{ + m_data2*(y*m_width+x)+0 = value; +} +void FlowField_sV::setY(int x, int y, float value) +{ + m_data2*(y*m_width+x)+1 = value; +} + +float* FlowField_sV::data() +{ + return m_data; +} + +bool FlowField_sV::operator ==(const FlowField_sV& other) const +{ + + if (m_width != other.m_width) { + std::cout << "Width differs: " << m_width << " vs. " << other.m_width << "." << std::endl; + return false; + } + if (m_height != other.m_height) { + std::cout << "Height differs. " << m_height << " vs. " << other.m_height << "" << std::endl; + return false; + } + + for (int y = 0; y < m_height; y++) { + for (int x = 0; x < m_width; x++) { + if (this->x(x,y) != other.x(x,y)) { + std::cout << "x Value differs at " << x << "," << y << ": " + << this->x(x,y) << "/" << other.x(x,y) << std::endl; + return false; + } + if (this->y(x,y) != other.y(x,y)) { + std::cout << "y Value differs at " << x << "," << y << ": " + << this->y(x,y) << "/" << other.y(x,y) << std::endl; + return false; + } + } + } + + return true; +}
View file
slowmoVideo-0.6.tar.xz/src/lib/libsvflow/src/flowRW_sV.cpp
Added
@@ -0,0 +1,104 @@ +/* +slowmoVideo creates slow-motion videos from normal-speed videos. +Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +*/ + +#include "../include/flowRW_sV.h" +#include "../include/flowField_sV.h" + +#include <iostream> +#include <fstream> + +const std::string FlowRW_sV::m_magicNumber = "flow_sV"; +const char FlowRW_sV::m_version = 1; + +void FlowRW_sV::save(std::string filename, FlowField_sV *flowField) +{ + int width = flowField->width(); + int height = flowField->height(); + std::cout << "Writing flow file " << filename << ": " << width << "x" << height + << ", version " << (int)m_version << ", magic number " << m_magicNumber << std::endl; + + float *data = flowField->data(); + std::ofstream file(filename.c_str(), std::ios_base::out | std::ios_base::binary); + file.write((char*) m_magicNumber.c_str(), m_magicNumber.length()*sizeof(char)); + file.write((char*) &m_version, sizeof(char)); + file.write((char*) &width, sizeof(int)); + file.write((char*) &height, sizeof(int)); + + file.write((char*) data, sizeof(float)*flowField->dataSize()); + file.close(); +} + +FlowRW_sV::FlowInfo_sV FlowRW_sV::readInfo(std::string filename) +{ + FlowInfo_sV info; + + std::ifstream file(filename.c_str(), std::ios_base::in | std::ios_base::binary); + + char *magic = new charm_magicNumber.size()+1; + magicm_magicNumber.size() = 0; + file.read(magic, sizeof(char)*m_magicNumber.size()); + file.read(&info.version, sizeof(char)); + info.magic = std::string(magic); + delete magic; + + + file.read((char*) &info.width, sizeof(int)); + file.read((char*) &info.height, sizeof(int)); + if (file.rdstate() == std::ios::goodbit) { + if (info.magic.compare(m_magicNumber) == 0) { + info.valid = true; + } + std::cout << "Magic number: " << info.magic << ", version: " << (int)info.version + << ", size: " << info.width << "x" << info.height << std::endl; + } else { + std::cerr << "Failed to read width/height from " << filename << "." << std::endl; + } + file.close(); + + return info; +} + +FlowField_sV* FlowRW_sV::load(std::string filename) +{ + std::ifstream file(filename.c_str(), std::ios_base::in | std::ios_base::binary); + + char *magic = new charm_magicNumber.size()+1; + magicm_magicNumber.size() = 0; + char version; + + file.read(magic, sizeof(char)*m_magicNumber.size()); + file.read((char*) &version, sizeof(char)); + + int width, height; + file.read((char*) &width, sizeof(int)); + file.read((char*) &height, sizeof(int)); + if (file.rdstate() != std::ios::goodbit) { + file.close(); + throw FlowRWError("Failed to read width/height from file " + filename); + } + + FlowField_sV *field = new FlowField_sV(width, height); + + file.read((char*) field->data(), sizeof(float)*field->dataSize()); + if (file.rdstate() != std::ios::goodbit) { + delete field; + file.close(); + throw FlowRWError("Failed to read data from file " + filename); + } + file.close(); + + std::cout << "Read flow file of size " << field->width() + << "×" << field->height() + << ". Magic number: " << magic + << ", version: " << (int)version << std::endl; + + delete magic; + return field; +}
View file
slowmoVideo-0.6.tar.xz/src/lib/macros_sV.h
Changed
(renamed from src/slowmoVideo/lib/macros_sV.h)
View file
slowmoVideo-0.6.tar.xz/src/lib/qtkit.h
Added
@@ -0,0 +1,30 @@ +/* + * class to export a movie using QuickTime under OSX +*/ + +#include <QImage> +#import <QTKit/QTKit.h> + +#include "video_enc.h" + +class VideoQT : public VideoWriter{ + int mHeight; + int mWidth; + double movieFPS; + NSString *codecSpec; + NSString *qualitySpec; + NSString *destPath; + + QTMovie* mMovie; + NSDictionary *imageAttributes; + QTTime duration; + +public: + VideoQT(int width,int height,double fps,const char *vcodec,const char* vquality,const char *filename); + ~VideoQT(); + + int writeFrame(const QImage& frame); + int exportFrames(QString filepattern,int first,RenderTask_sV *progress); +}; + +
View file
slowmoVideo-0.6.tar.xz/src/lib/qtkit.mm
Added
@@ -0,0 +1,342 @@ +/* + * class to export a movie using QuickTime + */ +#include <QtCore/QCoreApplication> +#include <QDebug> +#include <QtCore/QSettings> +#include <QImage> + +#include "qtkit.h" +#include "video_enc.h" + + +#include "../project/renderTask_sV.h" + +#pragma mark - +#pragma mark cocoa bridge + +// tools for qt 4.8 +// convert pixamp <-> nsimage +static void drawImageReleaseData (void *info, const void *, size_t) +{ + delete static_cast<QImage *>(info); +} + +CGImageRef qt_mac_image_to_cgimage(const QImage&img) +{ + QImage *image; + if (img.depth() != 32) + image = new QImage(img.convertToFormat(QImage::Format_ARGB32_Premultiplied)); + else + image = new QImage(img); + + uint cgflags = kCGImageAlphaNone; + switch (image->format()) { + case QImage::Format_ARGB32_Premultiplied: + cgflags = kCGImageAlphaPremultipliedFirst; + break; + case QImage::Format_ARGB32: + cgflags = kCGImageAlphaFirst; + break; + case QImage::Format_RGB32: + cgflags = kCGImageAlphaNoneSkipFirst; + default: + break; + } + cgflags |= kCGBitmapByteOrder32Host; + CGDataProviderRef dataProvider = CGDataProviderCreateWithData(image, + static_cast<const QImage *>(image)->bits(), + image->byteCount(), + drawImageReleaseData); + CGColorSpaceRef colorspace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); + + + CGImageRef cgImage = CGImageCreate(image->width(), image->height(), 8, 32, + image->bytesPerLine(), + colorspace, + cgflags, dataProvider, 0, false, kCGRenderingIntentDefault); + + CFRelease(dataProvider); + CFRelease(colorspace); + return cgImage; +} + +NSImage *toNSImage(const QImage& InImage) +{ + NSBitmapImageRep *bitmapRep = NSBitmapImageRep alloc initWithCGImage: qt_mac_image_to_cgimage(InImage); + NSImage *image = NSImage alloc init; + image addRepresentation:bitmapRep; + bitmapRep release; + return image; +} + +// end of tools + + +#pragma mark - + +/* TODO : + "-fps: Frames per second for final movie can be anywhere between 0.1 and 60.0.\n" + "-height: If specified images are resized proportionally to height given.\n" + "-codec: Codec to use to encode can be 'h264' 'photojpeg' 'raw' or 'mpv4'.\n" + "-quality: Quality to encode with can be 'high' 'normal' 'low'.\n" + "-quiet: Set to 'yes' to suppress output during encoding.\n" + "-reverse: Set to 'yes' to reverse the order that images are displayed in the movie.\n" + + "DEFAULTS\n" + "fps = 30\n" + "height = original image size\n" + "codec = h264\n" + "quality = high\n\n" + + + */ + +VideoQT::VideoQT(int width,int height,double fps,const char *vcodec,const char* vquality,const char *filename) +{ + NSAutoreleasePool* localpool = NSAutoreleasePool alloc init; + movieFPS = fps; + mMovie = nil; + mHeight = height; + mWidth = width; + codecSpec = nil; + qualitySpec = nil; + + + NSDictionary *codec = NSDictionary dictionaryWithObjectsAndKeys: + @"avc1", @"h264", + @"mpv4", @"mpv4", + @"jpeg", @"photojpeg", + @"raw ", @"raw", nil; + + NSDictionary *quality = NSDictionary dictionaryWithObjectsAndKeys: + NSNumber numberWithLong:codecLowQuality, @"low", + NSNumber numberWithLong:codecNormalQuality, @"normal", + NSNumber numberWithLong:codecMaxQuality, @"high", nil; + + if (codecSpec == nil) { + codecSpec = @"h264"; + } + + /* + codecLosslessQuality = 0x00000400, + codecMaxQuality = 0x000003FF, + codecMinQuality = 0x00000000, + codecLowQuality = 0x00000100, + codecNormalQuality = 0x00000200, + codecHighQuality = 0x00000300 + */ + + if (qualitySpec == nil) { + qualitySpec = @"high"; + } + + imageAttributes = NSDictionary dictionaryWithObjectsAndKeys: + codec objectForKey:codecSpec, QTAddImageCodecType, + quality objectForKey:qualitySpec, QTAddImageCodecQuality, + NSNumber numberWithLong:100000, QTTrackTimeScaleAttribute, + nil retain; + long timeScale = 100000; + long long timeValue = (long long) ceil((double) timeScale / fps); + duration = QTMakeTime(timeValue, timeScale); + + NSFileManager *fileManager = NSFileManager defaultManager; + destPath = NSURL fileURLWithPath:NSString stringWithUTF8String:filename + stringByExpandingTildeInPath path; + + if (!destPath hasSuffix:@".mov") { + fprintf(stderr, "Error: Output filename must be of type '.mov'\n"); + //return 1; + } + + if (fileManager fileExistsAtPath:destPath) { + fprintf(stderr, "Error: Output file already exists.\n"); + //return 1; + } + + mMovie = QTMovie alloc initToWritableFile:destPath error:NULL; + if (mMovie == nil) { + fprintf(stderr, "%s","Error: Unable to initialize QT object.\n"); + //return 1; + } + mMovie setAttribute:NSNumber numberWithBool:YES forKey:QTMovieEditableAttribute; + localpool drain; +} + +// +// add one frame to the movie +int VideoQT::writeFrame(const QImage& frame) +{ + NSAutoreleasePool* localpool = NSAutoreleasePool alloc init; +#if 1 + NSImage* nsimage =toNSImage(frame); +#else + NSBitmapImageRep* imageRep = NSBitmapImageRep alloc initWithBitmapDataPlanes:&imagedata + pixelsWide:width + pixelsHigh:height + bitsPerSample:8 + samplesPerPixel:4 + hasAlpha:YES + isPlanar:NO + colorSpaceName:NSDeviceRGBColorSpace + bitmapFormat:NSAlphaFirstBitmapFormat + bytesPerRow:argbimage->widthStep + bitsPerPixel:32 ; + NSImage* nsimage = NSImage alloc init; + nsimage addRepresentation:imageRep; +#endif + // maybe should resize here ? + + mMovie addImage:nsimage + forDuration:duration + withAttributes:imageAttributes; + + if (!mMovie updateMovieFile) { + fprintf(stderr, "Didn't successfully update movie file. \n" ); + return 1; + } + + + //imageRep release; + nsimage release; + localpool drain; + return 0; +} + +#pragma mark - + +int VideoQT::exportFrames(QString filepattern,int first,RenderTask_sV *progress) +{ + NSAutoreleasePool* localpool = NSAutoreleasePool alloc init; + NSString *inputPath; + NSArray *imageFiles; + NSError *err; + NSImage *image; + + NSString *fullFilename; + + qDebug() << "exporting frame from : " << filepattern << " to " << destPath; + NSLog(@"export to @%", destPath); + + NSFileManager *fileManager = NSFileManager defaultManager; + NSString* inputdir = NSURL fileURLWithPath:NSString stringWithUTF8String:filepattern.toStdString().c_str() + stringByExpandingTildeInPath path; + inputPath = inputdir stringByDeletingLastPathComponent; + + imageFiles = fileManager contentsOfDirectoryAtPath:inputPath error:&err; + imageFiles = imageFiles sortedArrayUsingSelector:@selector(localizedStandardCompare:); + + for (NSString *file in imageFiles) { + fullFilename = inputPath stringByAppendingPathComponent:file; + if (fullFilename pathExtension caseInsensitiveCompare:@"jpeg" == NSOrderedSame || + fullFilename pathExtension caseInsensitiveCompare:@"png" == NSOrderedSame || + fullFilename pathExtension caseInsensitiveCompare:@"jpg" == NSOrderedSame) { + NSAutoreleasePool *innerPool = NSAutoreleasePool alloc init; + image = NSImage alloc initWithContentsOfFile:fullFilename; + + //NSLog(@"adding %@",fullFilename); + + mMovie addImage:image + forDuration:duration + withAttributes:imageAttributes; + + if (!mMovie updateMovieFile) { + fprintf(stderr, "Didn't successfully update movie file. \n" ); + return 1; + } + + // TODO: + progress->stepProgress(); + image release; + innerPool release; + } + } + + localpool drain; + return 0; +} + +// +// close the movie file +VideoQT::~VideoQT() +{ + NSAutoreleasePool* localpool = NSAutoreleasePool alloc init; + mMovie updateMovieFile; + + mMovie release; + qualitySpec release; + codecSpec release; + // TODO: destPath release; + localpool drain; +} + +#pragma mark - +#pragma mark C/C++ bridge + +VideoWriter* CreateVideoWriter_QT ( const char* filename, int width, int height, double fps,const char* codec) +{ + VideoQT* driver= new VideoQT(width,height,fps,0,0,filename); + return driver; +} + +#if 0 +CGImageRef qt_mac_image_to_cgimage(const QImage &image) +{ + int bitsPerColor = 8; + int bitsPerPixel = 32; + if (image.depth() == 1) { + bitsPerColor = 1; + bitsPerPixel = 1; + } + QCFType<CGDataProviderRef> provider = + CGDataProviderCreateWithData(0, image.bits(), image.bytesPerLine() * image.height(), + 0); + + uint cgflags = kCGImageAlphaPremultipliedFirst; +#ifdef kCGBitmapByteOrder32Host //only needed because CGImage.h added symbols in the minor version + cgflags |= kCGBitmapByteOrder32Host; +#endif + + CGImageRef cgImage = CGImageCreate(image.width(), image.height(), bitsPerColor, bitsPerPixel, + image.bytesPerLine(), + QCoreGraphicsPaintEngine::macGenericColorSpace(), + cgflags, provider, + 0, + 0, + kCGRenderingIntentDefault); + + return cgImage; +} + +void * /*NSImage */qt_mac_create_nsimage(const QPixmap &pm) +{ + QMacCocoaAutoReleasePool pool; + if(QCFType<CGImageRef> image = pm.toMacCGImageRef()) { + NSImage *newImage = 0; + NSRect imageRect = NSMakeRect(0.0, 0.0, CGImageGetWidth(image), CGImageGetHeight(image)); + newImage = NSImage alloc initWithSize:imageRect.size; + newImage lockFocus; + { + CGContextRef imageContext = (CGContextRef)NSGraphicsContext currentContext graphicsPort; + CGContextDrawImage(imageContext, *(CGRect*)&imageRect, image); + } + newImage unlockFocus; + return newImage; + } + return 0; +} + +QPixmap pixmap = icon.pixmap(size); +CGImageRef cgImage = pixmap.toMacCGImageRef();//compile errors here +image = NSImage alloc initWithCGImage:cgImage size:NSZeroSize; +CFRelease(cgImage); + +Creates a CGImageRef equivalent to the QPixmap. Returns the CGImageRef handle. + +It is the caller's responsibility to release the CGImageRef data after use. + +Warning: This function is only available on Mac OS X. + +This function was introduced in Qt 4.2. + +#endif
View file
slowmoVideo-0.6.tar.xz/src/lib/shutter_sV.cpp
Added
@@ -0,0 +1,172 @@ +/* +slowmoVideo creates slow-motion videos from normal-speed videos. +Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +*/ + +#include "flowField_sV.h" +#include "sourceField_sV.h" +#include "interpolate_sV.h" +#include "intMatrix_sV.h" +#include "shutter_sV.h" + +#include <QtCore/QStringList> +#include <QtCore/QDebug> + +#include <algorithm> +#include <cmath> + + +#define CLAMP(x,min,max) ( ((x) < (min)) ? (min) : ( ((x) > (max)) ? (max) : (x) ) ) + +#define MIN_DIST 0.01 + + +QImage Shutter_sV::combine(const QStringList images) +{ + Q_ASSERT(images.size() > 0); + + QImage img(images.at(0)); + IntMatrix_sV matrix(img.width(), img.height(), 4); + for (int i = 0; i < images.size(); i++) { + img = QImage(images.at(i)); + matrix += img.bits(); + } + matrix /= images.size(); + + unsigned char *bytes = matrix.toBytesArray(); + QImage result(matrix.width(), matrix.height(), QImage::Format_ARGB32); + std::copy(bytes, bytes+matrix.width()*matrix.height()*matrix.channels()+1, result.bits()); + delete bytes; + + return result; +} + +QImage Shutter_sV::combine(const QList<QImage> images) +{ + Q_ASSERT(images.size() > 0); + + IntMatrix_sV matrix(images.at(0).width(), images.at(0).height(), 4); + for (int i = 0; i < images.size(); i++) { + matrix += images.at(i).bits(); + } + matrix /= images.size(); + + unsigned char *bytes = matrix.toBytesArray(); + QImage result(matrix.width(), matrix.height(), QImage::Format_ARGB32); + std::copy(bytes, bytes+matrix.width()*matrix.height()*matrix.channels()+1, result.bits()); + delete bytes; + + return result; +} + +QImage Shutter_sV::convolutionBlur(const QImage source, const FlowField_sV *flow, float length) +{ + Q_ASSERT(source.width() == flow->width()); + Q_ASSERT(source.height() == flow->height()); + + const float Wmax = source.width()-1.001; + const float Hmax = source.height()-1.001; + + QImage blurred(source.size(), source.format()); + ColorStack stack; + float dx, dy; + float xf, yf; + int samples, inc; + for (int y = 0; y < source.height(); y++) { + for (int x = 0; x < source.width(); x++) { + stack = ColorStack(); + dx = length * flow->x(x,y); + dy = length * flow->y(x,y); + dx = CLAMP(x+dx, 0.0, Wmax)-x; + dy = CLAMP(y+dy, 0.0, Hmax)-y; + + samples = ceil(std::sqrt(dx*dx + dy*dy)); + if (samples < 1) { + samples = 1; + } + inc = std::max(1, samples/20); // Lower inc value leads to a smoother result + + xf = CLAMP(x, 0.0, Wmax); + yf = CLAMP(y, 0.0, Hmax); + stack.add(source.pixel(x,y)); // Avoids interpolation error, and interpolation for (x,y) is not necessary anyway + for (int i = 1; i <= samples; i += inc) { + // \todo adjust increment + stack.add(Interpolate_sV::interpolate(source, xf+float(i)/samples * dx, yf+float(i)/samples * dy)); + } + blurred.setPixel(x, y, stack.col().rgba()); + } + } + return blurred; +} + +QImage Shutter_sV::convolutionBlur(const QImage interpolatedAtOffset, const FlowField_sV *flow, float length, float offset) +{ + Q_ASSERT(interpolatedAtOffset.width() == flow->width()); + Q_ASSERT(interpolatedAtOffset.height() == flow->height()); + // could be equal to 0, in case of integer ! + //Q_ASSERT(offset > 0); + Q_ASSERT(offset < 1); + + SourceField_sV source(flow, offset); + source.inpaint(); + + const float Wmax = interpolatedAtOffset.width()-1.01; + const float Hmax = interpolatedAtOffset.height()-1.01; + + QImage blurred(interpolatedAtOffset.size(), interpolatedAtOffset.format()); + ColorStack stack; + float dx, dy; + float xf, yf; + int samples, inc; + for (int y = 0; y < interpolatedAtOffset.height(); y++) { + for (int x = 0; x < interpolatedAtOffset.width(); x++) { + stack = ColorStack(); + dx = -(source.at(x,y).fromX - x); // Get the optical flow vector back from the source field + dy = -(source.at(x,y).fromY - y); + dx = dx/offset * length; // First normalize to one frame, then adjust the length + dy = dy/offset * length; + dx = CLAMP(x+dx, 0.0, Wmax)-x; + dy = CLAMP(y+dy, 0.0, Hmax)-y; + + samples = ceil(std::sqrt(dx*dx + dy*dy)); + if (samples < 1) { + samples = 1; + } + inc = std::max(1, samples/20); + + xf = CLAMP(x, 0.0, Wmax); + yf = CLAMP(y, 0.0, Hmax); + stack.add(interpolatedAtOffset.pixel(x,y)); // Avoids interpolation error, and interpolation for (x,y) is not necessary anyway + for (int i = 1; i <= samples; i += inc) { + // \todo adjust increment + stack.add(Interpolate_sV::interpolate(interpolatedAtOffset, xf+float(i)/samples * dx, yf+float(i)/samples * dy)); + } + blurred.setPixel(x, y, stack.col().rgba()); + } + } + return blurred; + +} + +Shutter_sV::ColorStack::ColorStack() : + r(0), g(0), b(0), a(0), count(0) +{} + +void Shutter_sV::ColorStack::add(QColor col) +{ + r += col.redF(); + g += col.greenF(); + b += col.blueF(); + a += col.alphaF(); + ++count; +} + +QColor Shutter_sV::ColorStack::col() +{ + return QColor::fromRgbF(r/count, g/count, b/count, a/count); +}
View file
slowmoVideo-0.6.tar.xz/src/lib/shutter_sV.h
Changed
(renamed from src/slowmoVideo/lib/shutter_sV.h)
View file
slowmoVideo-0.6.tar.xz/src/lib/sourceField_sV.cpp
Changed
(renamed from src/slowmoVideo/lib/sourceField_sV.cpp)
View file
slowmoVideo-0.6.tar.xz/src/lib/sourceField_sV.h
Changed
(renamed from src/slowmoVideo/lib/sourceField_sV.h)
View file
slowmoVideo-0.6.tar.xz/src/lib/vector_sV.cpp
Changed
(renamed from src/slowmoVideo/lib/vector_sV.cpp)
View file
slowmoVideo-0.6.tar.xz/src/lib/vector_sV.h
Changed
(renamed from src/slowmoVideo/lib/vector_sV.h)
View file
slowmoVideo-0.6.tar.xz/src/lib/videoInfo_sV.cpp
Added
@@ -0,0 +1,125 @@ +/* +slowmoVideo creates slow-motion videos from normal-speed videos. +Copyright (C) 2014 Valery brasseur <vbrasseur@gmail.com> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +*/ + + +#include "videoInfo_sV.h" +#include "defs_sV.hpp" +#include <QtCore> +#include <QtCore/QSettings> +#include <QObject> + + +/** + * get information from video file + */ +VideoInfoSV getInfo(const char filename) +{ + VideoInfoSV info; + info.frameRateNum = 0; + info.frameRateDen = 0; + info.streamsCount = -1; + info.framesCount = 0; + + qDebug() << "Reading info for file " << filename; + //flush(stdout); + + double videorate; + double duration; + QString output; + + QProcess ffmpeg; + QSettings settings; + QString prog = settings.value("binaries/ffmpeg", "ffmpeg").toString(); + QStringList args; + args << "-i" << filename; + args << "-f" << "null"; + args << "/dev/null"; + + ffmpeg.start(prog, args); + ffmpeg.waitForFinished(-1); + QString videoInfo = ffmpeg.readAllStandardError(); + ffmpeg.close(); + + // Example of output from 0.7 and up releases + // Stream #0:0: Video: mpeg4 (Simple Profile) (DX50 / 0x30355844), yuv420p, 400x240 SAR 1:1 DAR 5:3, 23 tbr, 23 tbn, 23 tbc + // Duration: 00:00:11.13, start: 0.000000, bitrate: 6338 kb/s + // Stream #0.0(eng): Video: mpeg4 (Main Profile), yuv420p, 1280x720 PAR 1:1 DAR 16:9, 6309 kb/s, 30.69 fps, 90k tbn, 300 tbc + /* prefer use of : + avconv -i ~/Videos/MOV_0010.MP4 -f null /dev/nul + frame= 336 fps= 0 q=0.0 Lsize= 0kB time=10.92 bitrate= 0.0kbits/s + video:0kB audio:696kB global headers:0kB muxing overhead -100.000000% + use frame= for fnum + use time= divide by frame for fps + */ + + qDebug() << "output : " << videoInfo; + + // find the source resolution + //QRegExp rx("Stream.*Video:.*((0-9{2,5})x(0-9{2,5}))"); + QRegExp rx("Stream.*Video:.*(1-90-9*)x(1-90-9*).*"); + //QRegExp rx("Stream.*Video:.*(\\d{2,})x(\\d{2,}).*"); + //rx.setMinimal(true); + if (-1 == rx.indexIn(videoInfo)) { + qDebug() << "Could not find size."; + return info; + } + + info.width = rx.cap(1).toInt(); + info.height = rx.cap(2).toInt(); + + // find the duration + //rx.setPattern("Duration: ((0-9+):(0-9{2}):(0-9{2}).(0-9+))"); + rx.setPattern("Duration: (0-9*):(0-9*):(0-9*\\.0-9*)"); + if (-1 == rx.indexIn(videoInfo)) { + qDebug() << "Could not find duration of stream."; + return info; + } + + int hours = rx.cap(1).toInt(); + int minutes = rx.cap(2).toInt(); + double seconds = rx.cap(3).toDouble(); + + duration = 3600*hours + 60*minutes + seconds; + + // container rate + rx = QRegExp("(0-9\\.+) fps"); + rx.setMinimal(true); + if (rx.indexIn(videoInfo) !=-1) { + videorate = rx.cap(1).toDouble(); + } else { + rx = QRegExp("Video:.*, (0-9*\\.?0-9+) tbn"); + rx.setMinimal(true); + if (rx.indexIn(videoInfo) !=-1) { + videorate = rx.cap(1).toDouble(); + } else { + videorate = 0; + } + } + + info.framesCount = duration * videorate; + qDebug() << "calculated framesCount : " << info.framesCount << "with :" << duration << " and " << videorate; + + // TODO: correct time + rx = QRegExp("frame=\\s*(\\d+).*time=(\\d+)"); + rx.setMinimal(true); + + // beeter use of pos/offset ? + rx.lastIndexIn (videoInfo); + qDebug() << "frame" << rx.cap(1) << "time " << rx.cap(2); + info.framesCount = rx.cap(1).toLong(); + + Fps_sV fps(videorate); + + info.frameRateNum = fps.num; + info.frameRateDen = fps.den; + + info.streamsCount = 1; + return info; +}
View file
slowmoVideo-0.6.tar.xz/src/lib/videoInfo_sV.h
Changed
(renamed from src/slowmoVideo/lib/videoInfo_sV.h)
View file
slowmoVideo-0.6.tar.xz/src/lib/video_enc.cpp
Added
@@ -0,0 +1,36 @@ +#include "config.h" + +#include "video_enc.h" + +VideoWriter* CreateVideoWriter( const char* filename, int width, int height,double fps,int use_qt,const char* codec) +{ + VideoWriter* driver; + +#ifdef USE_QTKIT + if (use_qt) + driver= CreateVideoWriter_QT(filename,width, height,fps,codec); + else +#endif +#ifdef USE_FFMPEG + driver= CreateVideoWriter_FFMPEG(filename,width, height,fps,codec); +#endif + return driver; +} + +int WriteFrame( VideoWriter* writer, const QImage& frame) +{ + return writer ? writer->writeFrame(frame) : 0; +} + +int exportFrames(VideoWriter* writer,QString filepattern,int first,RenderTask_sV *progress) +{ + return writer ? writer->exportFrames(filepattern,first,progress) : 0; +} + +void ReleaseVideoWriter( VideoWriter** pwriter ) +{ + if( pwriter && *pwriter ) { + delete *pwriter; + *pwriter = 0; + } +}
View file
slowmoVideo-0.6.tar.xz/src/lib/video_enc.h
Added
@@ -0,0 +1,33 @@ +/* + * global abstract file + */ + +#ifndef _VID_W_H +#define _VID_W_H + +#include <QImage> + +class RenderTask_sV; + +class VideoWriter +{ +public: + virtual ~VideoWriter() {}; + virtual int writeFrame(const QImage& frame) = 0; + virtual int exportFrames(QString filepattern,int first,RenderTask_sV* progress) = 0; +}; + +VideoWriter* CreateVideoWriter( const char* filename, int width,int height,double fps,int use_qt,const char* codec); +void ReleaseVideoWriter( VideoWriter** pwriter ); +int WriteFrame( VideoWriter* writer, const QImage& frame); +int exportFrames(VideoWriter* pwriter,QString filepattern,int first,RenderTask_sV* progress); + +/* lib dependant ... */ + + +VideoWriter* CreateVideoWriter_FFMPEG(const char* filename, int width,int height,double fps,const char* codec); + +VideoWriter* CreateVideoWriter_QT ( const char* filename, int width,int height,double fps,const char* codec); + +#endif /* _VID_W_H */ +
View file
slowmoVideo-0.6.tar.xz/src/libgui
Added
+(directory)
View file
slowmoVideo-0.6.tar.xz/src/libgui/CMakeLists.txt
Added
@@ -0,0 +1,19 @@ +set(SRCS + imageDisplay.cpp + combinedShortcuts.cpp +) + + +include_directories( + ${CMAKE_BINARY_DIR}/libgui + ../lib/libsvflow +) + +add_library(sVgui STATIC ${SRCS}) +qt5_use_modules(sVgui Core) +qt5_use_modules(sVgui Gui) +qt5_use_modules(sVgui Widgets) +target_link_libraries(sVgui ${EXTERNAL_LIBS}) + +# If the library is used in a different project, cmake requires: +#include_directories(${slowmoVideo_SOURCE_DIR}/libgui)
View file
slowmoVideo-0.6.tar.xz/src/libgui/combinedShortcuts.cpp
Added
@@ -0,0 +1,140 @@ +/* +This file is part of slowmoVideo. +Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +*/ + +#include "combinedShortcuts.h" + +#include <QShortcut> + +#define DEBUG +#include <QDebug> + +CombinedShortcuts::CombinedShortcuts(QWidget *parent) : + m_parent(parent), + m_signalMapper(parent) +{ + connect(&m_signalMapper, SIGNAL(mapped(QString)), this, SLOT(slotShortcutUsed(QString))); +} +CombinedShortcuts::~CombinedShortcuts() +{ + for (int i = 0; i < m_qShortcuts.size(); i++) { + delete m_qShortcuts.at(i); + } +} + +QString CombinedShortcuts::shortcutList() const +{ + QStringList shortcuts; + for (int i = 0; i < m_shortcuts.size(); i++) { + shortcuts << m_shortcuts.at(i).shortcut + + "\t" + + m_shortcuts.at(i).desc; + } + return shortcuts.join("\n"); +} + +void CombinedShortcuts::addShortcut(QString shortcut, int id, QString description) +{ + for (int i = 0; i < m_shortcuts.size(); i++) { + if (m_shortcuts.at(i).shortcut == shortcut) { + qDebug() << "Shortcut " << shortcut << " is not unique, used for " + << description << " and " << m_shortcuts.at(i).desc; + Q_ASSERT(false); + return; + } + } + if (shortcut.length() == 1) { + addShortcutKey(shortcut); + m_shortcuts << ShortcutItem(id, shortcut, description); + + } else if (shortcut.length() == 3 && shortcut.at(1) == '-') { + addShortcutKey(shortcut.at(0)); + addShortcutKey(shortcut.at(2)); + m_shortcuts << ShortcutItem(id, shortcut, description); + + } else { + qDebug() << "Cannot add shortcut " << shortcut << ", format not supported."; + Q_ASSERT(false); + } +} + +void CombinedShortcuts::addShortcutKey(QString key) +{ + if (!m_uniqueKeys.contains(key)) { +#ifdef DEBUG + qDebug() << "Adding unique key " << key; +#endif + m_uniqueKeys << key; + + // Create a new shortcut for each unique key + QShortcut *qshortcut = new QShortcut(QKeySequence(key), m_parent); + m_qShortcuts << qshortcut; + + m_signalMapper.setMapping(qshortcut, key); + + // Connect shortcut to the signal mapper + connect(qshortcut, SIGNAL(activated()), &m_signalMapper, SLOT(map())); + } +} + +void CombinedShortcuts::slotShortcutUsed(QString key) +{ + + TimedShortcut ts; + ts.shortcut = key; + ts.start = QTime::currentTime(); + +#ifdef DEBUG + qDebug() << key << " pressed. Last shortcut: " << m_previousKey.start.elapsed() << " ms ago."; +#endif + +// QString at = QString(" @ %1.%2::%3") +// .arg(ts.start.minute()) +// .arg(ts.start.second()) +// .arg(ts.start.msec()); + + bool handled = false; + + // Use a timeout. Otherwise pressing a key may lead to unpredictable results + // since it may depend on the key you pressed several minutes ago. + if (m_previousKey.start.elapsed() < 600) { + + QString combinedShortcut = QString("%1-%2").arg(m_previousKey.shortcut).arg(key); + + for (int i = 0; i < m_shortcuts.size(); i++) { + if (m_shortcuts.at(i).shortcut == combinedShortcut) { +#ifdef DEBUG + qDebug() << QString("Shortcut %1 (%2) has been triggered!") + .arg(m_shortcuts.at(i).shortcut) + .arg(m_shortcuts.at(i).desc); +#endif + emit signalShortcutUsed(m_shortcuts.at(i).id); + handled = true; + break; + } + } + + } + if (!handled) { + // The key pressed did not belong to a combined shortcut. + // Check if there is a shortcut with a single key for it. + + for (int i = 0; i < m_shortcuts.size(); i++) { + if (m_shortcuts.at(i).shortcut == key) { + emit signalShortcutUsed(m_shortcuts.at(i).id); + handled = true; + break; + } + } + } + + if (!handled) { + m_previousKey = ts; + } +}
View file
slowmoVideo-0.6.tar.xz/src/libgui/combinedShortcuts.h
Added
@@ -0,0 +1,76 @@ +/* +This file is part of slowmoVideo. +Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +*/ + +#ifndef COMBINEDSHORTCUTS_H +#define COMBINEDSHORTCUTS_H + +#include <QtCore/QList> +#include <QtCore/QMap> +#include <QtCore/QSignalMapper> +#include <QtCore/QTime> +//#include <QtWidgets> + +class QShortcut; + +/** + \brief Manager for combined shortcuts (known from GMail) + + Combined shortcuts are for example <code>s-a</code> or \c q; the former one + is triggered when the user presses \c s and within a limited amount of time \c a. + */ +class CombinedShortcuts : public QObject +{ + Q_OBJECT +public: + CombinedShortcuts(QWidget *parent); + ~CombinedShortcuts(); + + /// Adds the given shortcut if it does not exist yet + void addShortcut(QString shortcut, int id, QString description); + + /// Returns a list of the available shortcuts that have been added + QString shortcutList() const; + + +signals: + /// Emitted when the shortcut has been used + void signalShortcutUsed(int id); + +private: + struct ShortcutItem { + ShortcutItem(int id, QString shortcut, QString desc) : + id(id), + shortcut(shortcut), + desc(desc) {} + int id; + QString shortcut; + QString desc; + }; + struct TimedShortcut { + QTime start; + QString shortcut; + }; + + QList<ShortcutItem> m_shortcuts; + QList<QString> m_uniqueKeys; + QList<QShortcut*> m_qShortcuts; + TimedShortcut m_previousKey; + + QWidget *m_parent; + QSignalMapper m_signalMapper; + + void addShortcutKey(QString key); + + +private slots: + void slotShortcutUsed(QString key); +}; + +#endif // COMBINEDSHORTCUTS_H
View file
slowmoVideo-0.6.tar.xz/src/libgui/imageDisplay.cpp
Added
@@ -0,0 +1,288 @@ +/* +This file is part of slowmoVideo. +Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +*/ + +#include "imageDisplay.h" +#include <QtCore/QDebug> +#include <QtGui/QPainter> +#include <QMenu> +#include <QFileDialog> +#include <QContextMenuEvent> + +#include <QAction> +#include <QApplication> +#include <QtCore/QSettings> +#include <QtCore/QFileInfo> + +#include <cmath> + +ImageDisplay::ImageDisplay(QWidget *parent, Qt::WindowFlags f) : + QFrame(parent, f), + m_scale(1) +{ + m_aScaling = new QAction(tr("Scale image to widget size"), this); + m_aScaling->setCheckable(true); + m_aScaling->setChecked(true); + + m_aExportImage = new QAction(tr("Export image"), this); + + connect(m_aScaling, SIGNAL(triggered()), this, SLOT(repaint())); + connect(m_aExportImage, SIGNAL(triggered()), this, SLOT(slotExportImage())); + + setContentsMargins(5, 5, 5, 5); + + m_states.mouseInitialImagePos = QPointF(0.0,0.0); + m_states.mousePrevPos = QPoint(0,0); + m_states.manhattan = 0; +} +ImageDisplay::~ImageDisplay() +{ + delete m_aScaling; +} + +void ImageDisplay::trackMouse(bool track) +{ + setMouseTracking(track); +} + +void ImageDisplay::loadImage(const QImage img) +{ + if (!img.isNull()) { + m_image = img; + } +} +const QImage& ImageDisplay::image() const +{ + return m_image; +} + +bool ImageDisplay::loadOverlay(const QImage img) +{ + if (img.size() != m_image.size()) { + return false; + } + m_overlay = img; + return true; +} +void ImageDisplay::clearOverlay() +{ + m_overlay = QImage(); +} + +void ImageDisplay::contextMenuEvent(QContextMenuEvent *e) +{ + QMenu menu; + menu.addAction(m_aScaling); + menu.addAction(m_aExportImage); + m_aExportImage->setEnabled(!m_image.isNull()); + menu.exec(e->globalPos()); +} + + +QPointF ImageDisplay::convertCanvasToPixel(QPoint p) const +{ + float scale = m_scale; + if (m_aScaling->isChecked()) { + scale = m_scaledImageSize.width()/float(m_image.width()); + } + return (p - contentsRect().topLeft())/scale; +} +QPointF ImageDisplay::convertCanvasToImage(QPoint p) const +{ + if (!m_aScaling->isChecked()) { + return m_imageOffset + convertCanvasToPixel(p); + } else { + return convertCanvasToPixel(p); + } +} +QPoint ImageDisplay::convertImageToPixel(QPointF p) const +{ + float scale = m_scale; + if (m_aScaling->isChecked()) { + scale = m_scaledImageSize.width()/float(m_image.width()); + } + return (p*scale + QPointF(contentsRect().topLeft())).toPoint(); +} +QPoint ImageDisplay::convertImageToCanvas(QPointF p) const +{ + if (!m_aScaling->isChecked()) { + return convertImageToPixel(p - m_imageOffset); + } else { + return convertImageToPixel(p); + } + +} + +void ImageDisplay::mousePressEvent(QMouseEvent *e) +{ + m_states.mouseInitialImagePos = convertCanvasToImage(e->pos()); + m_states.mousePrevPos = e->pos(); + m_states.manhattan = 0; + + QPointF pos = convertCanvasToImage(e->pos()); + emit signalMousePressed(pos.x(), pos.y()); +} + +void ImageDisplay::mouseMoveEvent(QMouseEvent *e) +{ + + if (e->buttons().testFlag(Qt::LeftButton)) { + m_states.manhattan += (e->pos()-m_states.mousePrevPos).manhattanLength(); + } + m_states.mousePrevPos = e->pos(); + + if (!m_aScaling->isChecked()) { + if (e->buttons().testFlag(Qt::MiddleButton)) { + // Move the viewport + QPointF offset = m_states.mouseInitialImagePos - convertCanvasToPixel(e->pos()); + m_imageOffset = offset; + repaint(); + } + } + + if (hasMouseTracking() && !m_image.isNull()) { + int x = e->pos().x() - contentsRect().x(); + int y = e->pos().y() - contentsRect().y(); + if (x < 0 || y < 0 || x >= contentsRect().width() || y >= contentsRect().height()) { +// qDebug() << "Not inside drawing boundaries."; + return; + } + QPointF pos = convertCanvasToImage(e->pos()); + emit signalMouseMoved(pos.x(), pos.y()); + } + repaint(); +} +void ImageDisplay::mouseReleaseEvent(QMouseEvent *e) +{ + QPointF p0 = m_states.mouseInitialImagePos; + QPointF releasePos = convertCanvasToImage(e->pos()); + + QPointF minPoint = min(p0, releasePos, true); + QPointF maxPoint = max(p0, releasePos, true); + + qDebug() << p0 << releasePos << minPoint << maxPoint; + QRectF mouseRect(minPoint, maxPoint); + + + if (m_states.countsAsMove()) { + emit signalRectDrawn(mouseRect); + } +} + +void ImageDisplay::wheelEvent(QWheelEvent *e) +{ + if (!m_aScaling->isChecked()) { + QPointF mouseOffset = convertCanvasToImage(e->pos()); + if (e->delta() > 0) { + if (m_scale < 20) { + m_scale *= 1.4; + } + } else { + if (m_scale > float(contentsRect().width())/(2*m_image.width())) { + m_scale /= 1.4; + } + } + m_imageOffset = mouseOffset - (e->pos()-contentsRect().topLeft())/m_scale; + repaint(); + } +} + + +void ImageDisplay::paintEvent(QPaintEvent *e) +{ + QFrame::paintEvent(e); + if (!m_image.isNull()) { + QPainter p(this); + + QImage subImg; + if (m_aScaling->isChecked()) { + + // Scale to frame size + subImg = m_image.scaled(contentsRect().size(), Qt::KeepAspectRatio); + m_scaledImageSize = subImg.size(); + + } else { + + // User-defined scaling + subImg = m_image.copy(std::floor(m_imageOffset.x()), std::floor(m_imageOffset.y()), + std::ceil(contentsRect().width()/m_scale+1), std::ceil(contentsRect().height()/m_scale+1)); + subImg = subImg.scaled(m_scale*subImg.size(), Qt::KeepAspectRatio, Qt::SmoothTransformation); + subImg = subImg.copy(m_scale*(m_imageOffset.x()-floor(m_imageOffset.x())), + m_scale*(m_imageOffset.y()-floor(m_imageOffset.y())), + contentsRect().width(), + contentsRect().height()); + } + + p.drawImage(contentsRect().topLeft(), subImg); + + if (m_states.countsAsMove() && !QApplication::mouseButtons().testFlag(Qt::NoButton)) { + QRect r; + QPoint origin = convertImageToCanvas(m_states.mouseInitialImagePos); + + r.setTopLeft(min(m_states.mousePrevPos, origin)); + r.setWidth(abs(m_states.mousePrevPos.x()-origin.x())); + r.setHeight(abs(m_states.mousePrevPos.y()-origin.y())); + + p.drawRect(r); + } + + } +} + +void ImageDisplay::slotExportImage() +{ + Q_ASSERT(!m_image.isNull()); + + QSettings settings; + + QFileDialog dialog(this, tr("Export render preview to image")); + dialog.setAcceptMode(QFileDialog::AcceptSave); + dialog.setFileMode(QFileDialog::AnyFile); + dialog.setDirectory(settings.value("directories/imageDisplay", QDir::homePath()).toString()); + if (dialog.exec() == QDialog::Accepted) { + m_image.save(dialog.selectedFiles().at(0)); + settings.setValue("directories/imageDisplay", QFileInfo(dialog.selectedFiles().at(0)).absolutePath()); + } +} + + + + +qreal ImageDisplay::clamp(qreal val, qreal min, qreal max) const +{ + return (val < min) ? min : ( (val > max) ? max : val ); +} +QPointF ImageDisplay::max(QPointF p1, QPointF p2, bool limitToImage) const +{ + QPointF p(qMax(p1.x(), p2.x()), qMax(p1.y(), p2.y())); + if (limitToImage) { + p.rx() = clamp(p.x(), 0, m_image.width()-1); + p.ry() = clamp(p.y(), 0, m_image.height()-1); + } + return p; +} + +QPointF ImageDisplay::min(QPointF p1, QPointF p2, bool limitToImage) const +{ + QPointF p(qMin(p1.x(), p2.x()), qMin(p1.y(), p2.y())); + if (limitToImage) { + p.rx() = clamp(p.x(), 0, m_image.width()-1); + p.ry() = clamp(p.y(), 0, m_image.height()-1); + } + return p; +} + +QPoint ImageDisplay::min(QPoint p1, QPoint p2) const +{ + return QPoint(qMin(p1.x(), p2.x()), qMin(p1.y(), p2.y())); +} +QPoint ImageDisplay::max(QPoint p1, QPoint p2) const +{ + return QPoint(qMax(p1.x(), p2.x()), qMax(p1.y(), p2.y())); +}
View file
slowmoVideo-0.6.tar.xz/src/libgui/imageDisplay.h
Added
@@ -0,0 +1,97 @@ +/* +This file is part of slowmoVideo. +Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +*/ + +#ifndef IMAGEDISPLAY_H +#define IMAGEDISPLAY_H + +#include <QFrame> +#include <QtCore/QRect> + +/** + \brief Simple image display. + + Images can be scaled to the frame size and exported to a file + via the context menu. + */ +class ImageDisplay : public QFrame +{ + Q_OBJECT +public: + explicit ImageDisplay(QWidget *parent = 0, Qt::WindowFlags f = 0); + ~ImageDisplay(); + + void trackMouse(bool track); + + /// \return The image that is currently displayed + const QImage& image() const; + +public slots: + /// Loads the given image; does \em not call repaint()! + void loadImage(const QImage img); + /// Loads the overlay that will be painted over the image; does \em not call repaint() either. + /// \return \c false if the image sizes do not match + bool loadOverlay(const QImage img); + void clearOverlay(); + +signals: + void signalMouseMoved(float x, float y); + void signalMousePressed(float x, float y); + void signalRectDrawn(QRectF imageRect); + +protected slots: + virtual void paintEvent(QPaintEvent *e); + virtual void contextMenuEvent(QContextMenuEvent *e); + virtual void mousePressEvent(QMouseEvent *e); + virtual void mouseMoveEvent(QMouseEvent *e); + virtual void mouseReleaseEvent(QMouseEvent *e); + virtual void wheelEvent(QWheelEvent *e); + +private: + QImage m_image; + QImage m_overlay; + + QAction *m_aScaling; + QAction *m_aExportImage; + + float m_scale; + QPointF m_imageOffset; + QSize m_scaledImageSize; + + struct { + QPointF mouseInitialImagePos; + + QPoint mousePrevPos; + + int manhattan; + + bool countsAsMove() { return manhattan > 4; } + + } m_states; + + /// Convert canvas coordinates to image coordinates. + /// The image may have an offset. + QPointF convertCanvasToImage(QPoint p) const; + /// Convert canvas coordinates to pixel coordinates (ignores the image offset) + QPointF convertCanvasToPixel(QPoint p) const; + QPoint convertImageToCanvas(QPointF p) const; + QPoint convertImageToPixel(QPointF p) const; + + qreal clamp(qreal val, qreal min, qreal max) const; + QPointF max(QPointF p1, QPointF p2, bool limitToImage) const; + QPointF min(QPointF p1, QPointF p2, bool limitToImage) const; + QPoint min(QPoint p1, QPoint p2) const; + QPoint max(QPoint p1, QPoint p2) const; + +private slots: + void slotExportImage(); + +}; + +#endif // IMAGEDISPLAY_H
View file
slowmoVideo-0.6.tar.xz/src/project
Added
+(directory)
View file
slowmoVideo-0.6.tar.xz/src/project/CMakeLists.txt
Added
@@ -0,0 +1,45 @@ +set(SRCS_PROJ + project_sV.cpp + projectPreferences_sV.cpp + renderPreferences_sV.cpp + tag_sV.cpp + node_sV.cpp + nodeList_sV.cpp + segment_sV.cpp + segmentList_sV.cpp + nodeHandle_sV.cpp + renderTask_sV.cpp + xmlProjectRW_sV.cpp + abstractFrameSource_sV.cpp + imagesFrameSource_sV.cpp + videoFrameSource_sV.cpp + emptyFrameSource_sV.cpp + abstractRenderTarget_sV.cpp + imagesRenderTarget_sV.cpp + videoRenderTarget_sV.cpp + abstractFlowSource_sV.cpp + flowSourceOpenCV_sV.cpp + flowSourceV3D_sV.cpp + interpolator_sV.cpp + shutterFunction_sV.cpp + shutterFunctionList_sV.cpp + motionBlur_sV.cpp + canvasObject_sV.h + exportVideoRenderTarget.cpp + work_flow.cpp +) + +if (OLD_FFMPEG) +set(SRCS_PROJ + ${SRCS_PROJ} + new_videoRenderTarget.cpp +) +endif() + +include_directories(${FFMPEG_INCLUDE_PATHS}) +add_library(sVproj STATIC ${SRCS_PROJ}) +qt5_use_modules(sVproj Core) +qt5_use_modules(sVproj Gui) +qt5_use_modules(sVproj Xml) +qt5_use_modules(sVproj Script) +target_link_libraries(sVproj sV sVinfo sVflow sVencode ${EXTERNAL_LIBS})
View file
slowmoVideo-0.6.tar.xz/src/project/abstractFlowSource_sV.cpp
Added
@@ -0,0 +1,63 @@ +/* + This file is part of slowmoVideo. + Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + */ + +#include "abstractFlowSource_sV.h" + +#include <QDir> + +#include "project_sV.h" + +AbstractFlowSource_sV::AbstractFlowSource_sV(Project_sV *project) : + m_project(project) +{ +} + +Project_sV* AbstractFlowSource_sV::project() +{ + return m_project; +} + +/* + * clear all flow file in flow directories + */ +void AbstractFlowSource_sV::cleardirectory(QDir dir) +{ + dir.setFilter( QDir::NoDotAndDotDot | QDir::Files ); + foreach( QString dirItem, dir.entryList() ) + dir.remove( dirItem ); + + dir.setFilter( QDir::NoDotAndDotDot | QDir::Dirs ); + foreach( QString dirItem, dir.entryList() ) { + QDir subDir( dir.absoluteFilePath( dirItem ) ); + subDir.removeRecursively(); + } +} + + +void AbstractFlowSource_sV::clearFlowCache() +{ + cleardirectory(m_dirFlowSmall); + cleardirectory(m_dirFlowOrig); +} + +void AbstractFlowSource_sV::slotUpdateProjectDir() +{ + //TODO: check + //m_dirFlowSmall.rmdir("."); + //m_dirFlowOrig.rmdir("."); + createDirectories(); +} + + +void AbstractFlowSource_sV::createDirectories() +{ + m_dirFlowSmall = project()->getDirectory("cache/oFlowSmall"); + m_dirFlowOrig = project()->getDirectory("cache/oFlowOrig"); +}
View file
slowmoVideo-0.6.tar.xz/src/project/abstractFlowSource_sV.h
Added
@@ -0,0 +1,59 @@ +/* +This file is part of slowmoVideo. +Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +*/ + +#ifndef ABSTRACTFLOWSOURCE_SV_H +#define ABSTRACTFLOWSOURCE_SV_H + +#include "../lib/defs_sV.hpp" + +#include <QtCore> +#include <QDir> + +class Project_sV; +class FlowField_sV; + +class AbstractFlowSource_sV +{ +public: + AbstractFlowSource_sV(Project_sV *project); + virtual ~AbstractFlowSource_sV() {} + + /** \return The flow field from \c leftFrame to \c rightFrame */ + virtual FlowField_sV* buildFlow(uint leftFrame, uint rightFrame, FrameSize frameSize) noexcept(false) = 0; + /** \return The path to the flow file for the given frames */ + virtual const QString flowPath(const uint leftFrame, const uint rightFrame, const FrameSize frameSize = FrameSize_Orig) const = 0; + + virtual void setLambda(double lambda) { m_lambda = lambda;} ; + + void clearFlowCache(); + void createDirectories(); + void cleardirectory(QDir dir); + +public slots: + /** + \fn slotUpdateProjectDir() + Informs the flow source that the project directory has changed. If the flow source created sub-directories + in the old project directories, it can e.g. delete them and create them at the new place. + */ + virtual void slotUpdateProjectDir() ; + +protected: + Project_sV* project(); + double m_lambda; + + QDir m_dirFlowSmall; + QDir m_dirFlowOrig; + +private: + Project_sV *m_project; + +}; + +#endif // ABSTRACTFLOWSOURCE_SV_H
View file
slowmoVideo-0.6.tar.xz/src/project/abstractFrameSource_sV.cpp
Added
@@ -0,0 +1,26 @@ +/* +This file is part of slowmoVideo. +Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +*/ + +#include "abstractFrameSource_sV.h" + +AbstractFrameSource_sV::AbstractFrameSource_sV(const Project_sV *project) : + m_project(project) +{ +} + +AbstractFrameSource_sV::~AbstractFrameSource_sV() +{ + +} + +double AbstractFrameSource_sV::maxTime() const noexcept(false) +{ + return (framesCount()-1)/fps()->fps(); +}
View file
slowmoVideo-0.6.tar.xz/src/project/abstractFrameSource_sV.h
Added
@@ -0,0 +1,119 @@ +/* +This file is part of slowmoVideo. +Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +*/ + +#ifndef ABSTRACTFRAMESOURCE_SV_H +#define ABSTRACTFRAMESOURCE_SV_H + +#include "../lib/defs_sV.hpp" + +#include <QImage> +#include <QCache> +#include <QtCore/QDir> + +class Project_sV; + +class Div0Exception {}; + +/** \brief Represents a source for input frames, like a video or an image sequence */ +class AbstractFrameSource_sV : public QObject +{ + Q_OBJECT +public: + AbstractFrameSource_sV(const Project_sV *project); + virtual ~AbstractFrameSource_sV(); + + const Project_sV* project() { return m_project; } + + /** + \fn initialize() + Initializes the frame source (like extracting frames from a video). + When re-implementing this method, the parent function must be called in order for + initialized() to work. + \see signalNextTask() and the other signals + */ + /** + \fn initialized() + \return \c true, if the frame source has been initialized. + */ + virtual void initialize() = 0; + virtual bool initialized() const = 0; + + /** + \fn framesCount() + \return Number of frames in this frame source + */ + virtual int64_t framesCount() const = 0; + virtual const Fps_sV* fps() const = 0; + double maxTime() const noexcept(false); + + /* + * add a qcache here for perf loading + */ + QCache<QString,QImage> frameCache; + // use it in frameAt + /** + \fn frameAt() + \return The frame at the given position, as image. Fails + if the frames have not been extracted yet. + */ + /** + \fn framePath() + \return The path to the frame at position \c frame + */ + virtual QImage frameAt(const uint frame, const FrameSize frameSize = FrameSize_Orig) = 0; + virtual const QString framePath(const uint frame, const FrameSize frameSize = FrameSize_Orig) const = 0; + + virtual void loadOrigFrames() =0; + +signals: + /** + \fn void signalNextTask(const QString taskDescription, int taskSize) + A new task has been started, like extracting frames from a video when loading a new frame source. + \param taskSize Number of task items in this task (e.g. number of frames to extract from a video file) + */ + /** + \fn void signalTaskProgress(int progress) + The current task has made progress. + \param progress Task item that has been completed. Should be smaller than taskSize given in signalNextTask(). + */ + /** + \fn void signalTaskItemDescription(const QString desc) + \param desc Description for the current task (like the file name of an extracted frame) + */ + /** + \fn void signalAllTasksFinished() + All due tasks have been completed. + */ + void signalNextTask(const QString taskDescription, int taskSize); + void signalTaskProgress(int progress); + void signalTaskItemDescription(const QString desc); + void signalAllTasksFinished(); + +public slots: + /** + \fn slotAbortInitialization() + Should abort the initialization of the frame source since this might take a long time + (e.g. extracting large frames from a long video, or re-sizing lots of frames). + */ + /** + \fn slotUpdateProjectDir() + Informs the frame source that the project directory has changed. If the frame source created sub-directories + in the old project directories, it can e.g. delete them and create them at the new place. + */ + virtual void slotAbortInitialization() = 0; + virtual void slotUpdateProjectDir() = 0; + +protected: + const Project_sV *m_project; + +}; + + +#endif // ABSTRACTFRAMESOURCE_SV_H
View file
slowmoVideo-0.6.tar.xz/src/project/abstractProgressDialog.h
Added
@@ -0,0 +1,15 @@ + +#ifndef PROGRESSDIALOG_H +#define PROGRESSDIALOG_H + +class progressDialog { + + public: + progressDialog() {}; + virtual ~progressDialog() {} + + virtual void updateProgress() = 0; +}; + +#endif +
View file
slowmoVideo-0.6.tar.xz/src/project/abstractRenderTarget_sV.cpp
Changed
(renamed from src/slowmoVideo/project/abstractRenderTarget_sV.cpp)
View file
slowmoVideo-0.6.tar.xz/src/project/abstractRenderTarget_sV.h
Added
@@ -0,0 +1,42 @@ +/* +This file is part of slowmoVideo. +Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +*/ + +#ifndef ABSTRACTRENDERTARGET_SV_H +#define ABSTRACTRENDERTARGET_SV_H + +#include <QtGui/QImage> +#include "../lib/defs_sV.hpp" + +class RenderTask_sV; + +/** \brief Should represent a render target like video or an image sequence */ +class AbstractRenderTarget_sV +{ +public: + AbstractRenderTarget_sV(RenderTask_sV *parentRenderTask); + virtual ~AbstractRenderTarget_sV(); + + RenderTask_sV* renderTask() { return m_renderTask; } + + /// Prepares the render target (if necessary), like initializing video streams etc. + virtual void openRenderTarget() noexcept(false) = 0; + /// Finishes the render target (e.g. writes the trailer to a video file) + virtual void closeRenderTarget() noexcept(false) = 0; + +public slots: + /// Adds one frame to the output + virtual void slotConsumeFrame(const QImage &image, const int frameNumber) = 0; + +private: + RenderTask_sV *m_renderTask; + +}; + +#endif // ABSTRACTRENDERTARGET_SV_H
View file
slowmoVideo-0.6.tar.xz/src/project/canvasObject_sV.h
Changed
(renamed from src/slowmoVideo/project/canvasObject_sV.h)
View file
slowmoVideo-0.6.tar.xz/src/project/emptyFrameSource_sV.cpp
Changed
(renamed from src/slowmoVideo/project/emptyFrameSource_sV.cpp)
View file
slowmoVideo-0.6.tar.xz/src/project/emptyFrameSource_sV.h
Added
@@ -0,0 +1,44 @@ +/* +This file is part of slowmoVideo. +Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +*/ + +#ifndef EMPTYFRAMESOURCE_H +#define EMPTYFRAMESOURCE_H + +#include "abstractFrameSource_sV.h" + +class EmptyFrameSource_sV : public AbstractFrameSource_sV +{ + Q_OBJECT + +public: + EmptyFrameSource_sV(const Project_sV *project); + ~EmptyFrameSource_sV() {} + + void initialize(); + bool initialized() const { return true; } + + int64_t framesCount() const { return 1000; } + const Fps_sV* fps() const { return &m_fps; } + int frameRateNum() const { return 24; } + int frameRateDen() const { return 1; } + QImage frameAt(const uint, const FrameSize = FrameSize_Orig) { return QImage(); } + const QString framePath(const uint, const FrameSize) const { return QString(); } + + void loadOrigFrames() {}; + +public slots: + void slotAbortInitialization() {} + void slotUpdateProjectDir() {} + +private: + Fps_sV m_fps; +}; + +#endif // EMPTYFRAMESOURCE_H
View file
slowmoVideo-0.6.tar.xz/src/project/exportVideoRenderTarget.cpp
Added
@@ -0,0 +1,87 @@ +/* +This file is part of slowmoVideo. +Copyright (C) 2014 Valery Brasseur <vbrasseur@gmail.com> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +*/ + +#include <QtCore/QObject> + +#include "exportVideoRenderTarget.h" +#include "renderTask_sV.h" +#include "../lib/video_enc.h" + + +exportVideoRenderTarget::exportVideoRenderTarget(RenderTask_sV *parentRenderTask) : + AbstractRenderTarget_sV(parentRenderTask) +{ + + m_targetDir = parentRenderTask->getRenderDirectory(); + m_filenamePattern = "rendered-%1.png"; + + use_qt = 1; + first = 0; +} + +exportVideoRenderTarget::~exportVideoRenderTarget() +{ + qDebug() << "Closing exporter. Not deleting temporary files under " << m_targetDir.absolutePath() << "."; +} + +void exportVideoRenderTarget::setTargetFile(const QString &filename) +{ + m_filename = filename; +} +void exportVideoRenderTarget::setVcodec(const QString &codec) +{ + m_vcodec = codec; +} + +void exportVideoRenderTarget::slotConsumeFrame(const QImage &image, const int frameNumber) +{ + if (!m_targetDir.exists()) { + m_targetDir.mkpath("."); + } + QString path = m_targetDir.absoluteFilePath(m_filenamePattern.arg(frameNumber+1, 5, 10, QChar::fromLatin1('0'))); + + bool ok; + ok = image.save(path); + if (!ok) { + qDebug() << " Writing image to " << path << " failed!"; + } else { + qDebug() << " Saved frame number " << frameNumber << " to " << path; + } + if (first == 0) + first = frameNumber + 1; +} + +void exportVideoRenderTarget::closeRenderTarget() noexcept(false) +{ + VideoWriter* writer; + + qDebug() << "exporting temporary frame to Video" << m_filename << " using codec " << m_vcodec << "starting at " << first; + if (m_vcodec.isEmpty()) + writer = CreateVideoWriter(m_filename.toStdString().c_str(), + renderTask()->resolution().width(), + renderTask()->resolution().height(), + renderTask()->fps().fps(),use_qt,0); + else + writer = CreateVideoWriter(m_filename.toStdString().c_str(), + renderTask()->resolution().width(), + renderTask()->resolution().height(), + renderTask()->fps().fps(),use_qt,m_vcodec.toStdString().c_str()); + + if (writer == 0) { + throw Error_sV(QObject::tr("Video could not be prepared .\n")); + } + exportFrames(writer, m_targetDir.absoluteFilePath(m_filenamePattern.arg("%05d")).toStdString().c_str(),first,renderTask()); + ReleaseVideoWriter( &writer ); +} + + + + +
View file
slowmoVideo-0.6.tar.xz/src/project/exportVideoRenderTarget.h
Added
@@ -0,0 +1,62 @@ +/* +This file is part of slowmoVideo. +Copyright (C) 2014 Valery Brasseur <vbrasseur@gmail.com> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +*/ + +/* + * handle both ffmpeg and qtkit + */ +#ifndef EXPORTVIDEORENDERTARGET_SV_H +#define EXPORTVIDEORENDERTARGET_SV_H + +#include "abstractRenderTarget_sV.h" + +#include <QtCore/QDir> + +class VideoWriter; +class RenderTask_sV; + +/// Produces videos from frames. +// store temporary frame on disk (png) then export with "ffmpeg" or quicktime +class exportVideoRenderTarget : public AbstractRenderTarget_sV +{ +public: + /// Constructs a new video render target + exportVideoRenderTarget(RenderTask_sV *parentRenderTask); + virtual ~exportVideoRenderTarget(); + + void openRenderTarget() noexcept(false) {} ; + + /// openRenderTarget() will throw an error if the target file cannot be opened. + void setTargetFile(const QString& filename); + /// Set a custom video codec + void setVcodec(const QString& codec); + + void closeRenderTarget() noexcept(false); + + void setQT(int use) { use_qt = use;}; + +public slots: + void slotConsumeFrame(const QImage &image, const int frameNumber); + +private: + QString m_filename; + QString m_vcodec; + VideoWriter* writer; + + int m_width; + int m_height; + int use_qt; // using QuickTime + int first; // first frame to be written + + // png temp + QDir m_targetDir; + QString m_filenamePattern; +}; + +#endif // EXPORTVIDEORENDERTARGET_SV_H
View file
slowmoVideo-0.6.tar.xz/src/project/flowSourceOpenCV_sV.cpp
Added
@@ -0,0 +1,407 @@ +/* +This file is part of slowmoVideo. +Copyright (C) 2012 Lucas Walter + 2012 Simon A. Eugster (Granjow) <simon.eu@gmail.com> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +*/ +#include "flowSourceOpenCV_sV.h" +#include "project_sV.h" +#include "abstractFrameSource_sV.h" +#include "flowRW_sV.h" +#include "flowField_sV.h" + +#include <QtCore/QTime> +#include <iostream> +#include <fstream> + +#if CV_VERSION_MAJOR == 4 +#include <opencv2/optflow.hpp> +#endif + +#include <QList> + +using namespace cv; + +FlowSourceOpenCV_sV::FlowSourceOpenCV_sV(Project_sV *project, int _algo, int _ocl_dev_idx) : + AbstractFlowSource_sV(project) +{ + ocl_device_index = _ocl_dev_idx; + algo = _algo; + createDirectories(); +} + +/** + * create a optical flow file + * + * @param flow optical flow to save + * @param flowname file name for optical flow + */ +void drawOptFlowMap(const Mat& flow, std::string flowname ) +{ + + FlowField_sV flowField(flow.cols, flow.rows); + + //qDebug() << "flow is : " << flow.cols << " by " << flow.rows; + for(int y = 0; y < flow.rows; y++) + for(int x = 0; x < flow.cols; x++) { + const Point2f& fxyo = flow.at<Point2f>(y, x); + + flowField.setX(x, y, fxyo.x); + flowField.setY(x, y, fxyo.y); + } + + FlowRW_sV::save(flowname, &flowField); +} + +void drawOptFlowMapSeparateXandY(const Mat& flowx, const Mat& flowy, std::string flowname ) +{ + FlowField_sV flowField(flowx.cols, flowy.rows); + for(int y = 0; y < flowx.rows; y++) { + for(int x = 0; x < flowx.cols; x++) { + const float flowx_float = flowx.at<float>(y, x); + const float flowy_float = flowy.at<float>(y, x); + flowField.setX(x, y, flowx_float); + flowField.setY(x, y, flowy_float); + } + } + FlowRW_sV::save(flowname, &flowField); +} + +/** + * build path of flow file + * + * @param leftFrame left frame for flow + * @param rightFrame right frame + * @param frameSize resolution (small/orig) + * + * @return name of flow file + */ +const QString FlowSourceOpenCV_sV::flowPath(const uint leftFrame, const uint rightFrame, const FrameSize frameSize) const +{ + QDir dir; + if (frameSize == FrameSize_Orig) { + dir = m_dirFlowOrig; + } else { + dir = m_dirFlowSmall; + } + QString direction; + if (leftFrame < rightFrame) { + direction = "forward"; + } else { + direction = "backward"; + } + + return dir.absoluteFilePath(QString("ocv-%1-%2-%3.sVflow").arg(direction).arg(leftFrame).arg(rightFrame)); +} + +/** + * setup parameter value for flow algorithm + * + * @param levels number of pyramide level + * @param winsize windows size + * @param polySigma sigma + * @param pyrScale pyramide scale + * @param polyN <#polyN description#> + */ +void FlowSourceOpenCV_sV::setupOpticalFlow(const int levels, const int winsize, const double polySigma, + const double pyrScale, const int polyN) +{ + qDebug() << "setup Optical Flow "; + this->pyrScale = pyrScale; + this->polyN = polyN; + this->polySigma = polySigma; + this->flags = 0; + this->numLevels = levels; + this->winSize = winsize; + //const int iterations = 8; // 10 + this->numIters = 8; + +} + +void FlowSourceOpenCV_sV::setupTVL1(const double tau, const double lambda, const int nscales, const int warps, const int iterations, const double epsilon) +{ + qDebug() << "setup Optical Flow TLV1"; + this->tau = tau; + this->lambda = lambda; + this->nscales = nscales; + this->warps = warps; + this->iterations = iterations; + this->epsilon = epsilon; +} + +FlowField_sV* FlowSourceOpenCV_sV::buildFlow(uint leftFrame, uint rightFrame, FrameSize frameSize) noexcept(false) +{ +#if CV_MAJOR_VERSION == 2 +#ifdef HAVE_OPENCV_OCL + if (ocl_device_index >= 0) { + setupOclDevice(); + } +#endif +#endif + QString flowFileName(flowPath(leftFrame, rightFrame, frameSize)); + + /// \todo Check if size is equal + if (!QFile(flowFileName).exists()) { + QTime time; + time.start(); + QString prevpath = project()->frameSource()->framePath(leftFrame, frameSize); + QString path = project()->frameSource()->framePath(rightFrame, frameSize); + + qDebug() << "Building flow for left frame " << leftFrame << " to right frame " << rightFrame << "; Size: " << frameSize; + + // check if file have been generated ! + //TODO: maybe better error handling ? + if (!QFile(prevpath).exists()) + throw FlowBuildingError(QString("Could not read image " + prevpath)); + + if (!QFile(path).exists()) + throw FlowBuildingError(QString("Could not read image " + path)); + + cv::Mat prevgray, gray; + +#if CV_VERSION_MAJOR >= 4 + prevgray = cv::imread(prevpath.toStdString(), IMREAD_GRAYSCALE); + gray = cv::imread(path.toStdString(), IMREAD_GRAYSCALE); + cv::UMat uprevgray, ugray; + prevgray.copyTo(uprevgray); + gray.copyTo(ugray); +#elif CV_MAJOR_VERSION == 3 + prevgray = cv::imread(prevpath.toStdString(), CV_LOAD_IMAGE_ANYDEPTH); + gray = cv::imread(path.toStdString(), CV_LOAD_IMAGE_ANYDEPTH); + cv::UMat uprevgray, ugray; + prevgray.copyTo(uprevgray); + gray.copyTo(ugray); +#endif + + { + if (!prevgray.empty()) { +#if CV_VERSION_MAJOR >= 4 + buildFlowOpenCV_4(uprevgray, ugray, flowFileName.toStdString()); +#elif CV_MAJOR_VERSION == 3 + buildFlowOpenCV_3(uprevgray, ugray, flowFileName.toStdString()); +#else +#ifdef HAVE_OPENCV_OCL + if (ocl_device_index >= 0) { + buildFlowOpenCV_OCL(prevgray, gray, flowFileName.toStdString()); + } else { + buildFlowOpenCV_CPU(prevgray, gray, flowFileName.toStdString()); + } +#else + buildFlowOpenCV_CPU(prevgray, gray, flowFileName.toStdString()); +#endif +#endif + } else { + qDebug() << "imread: Could not read image " << prevpath; + throw FlowBuildingError(QString("imread: Could not read image " + prevpath)); + } + } + qDebug() << "Optical flow built for " << flowFileName << " in " << time.elapsed() << " ms."; + } else { + qDebug().nospace() << "Re-using existing flow image for left frame " << leftFrame << " to right frame " << rightFrame << ": " << flowFileName; + } + + try { + return FlowRW_sV::load(flowFileName.toStdString()); + } catch (FlowRW_sV::FlowRWError &err) { + throw FlowBuildingError(err.what()); + } +} + +void FlowSourceOpenCV_sV::dumpAlgosParams() +{ + if (algo == 1) { // DualTVL1 + qDebug() << "flow via TLV1 algo." << " lambda:" << + lambda << " tau:" << tau << " nscales:" << nscales << + "warps:" << warps << " iterations:" << iterations << + "epsilon:" << epsilon; + } else { // _FARN_ + qDebug() << "flow via Farneback algo." << + " pyrScale:" << pyrScale << " numLevels:" << + numLevels << " winSize:" << winSize << " numIters:" << + numIters << " polyN:" << polyN << " polySigma:" << + polySigma << " flags:" << flags; + } +} + +#if CV_VERSION_MAJOR >= 4 +void FlowSourceOpenCV_sV::buildFlowOpenCV_4(cv::UMat& uprevgray, cv::UMat& ugray, std::string flowfilename) +{ + dumpAlgosParams(); + qDebug() << "Have OpenCL: " << cv::ocl::haveOpenCL() << " useOpenCL:" << cv::ocl::useOpenCL(); + qDebug() << (uprevgray.size() == ugray.size()) << uprevgray.channels() << ugray.channels(); + UMat uflow; + if (algo == 1) { // DualTVL1 + cv::Ptr<cv::optflow::DualTVL1OpticalFlow> tvl1; + tvl1 = cv::optflow::createOptFlow_DualTVL1(); + tvl1->setLambda(lambda); + tvl1->setTau(tau); + tvl1->setScalesNumber(nscales); + tvl1->setWarpingsNumber(warps); + // In OpenCV 4, iterations have been split into inner and outer iterations + // See https://github.com/opencv/opencv/pull/724/files#diff-beae2b00b19536f45d2a4a513b5f2c76L147 + // Use default ratio as in the OpenCV code + tvl1->setInnerIterations(std::max(1, iterations / 10)); + tvl1->setOuterIterations(std::max(1, iterations / 30)); + tvl1->setEpsilon(epsilon); + tvl1->calc( + uprevgray, + ugray, + uflow + ); + } else { // _FARN_ + calcOpticalFlowFarneback( + uprevgray, + ugray, + uflow, + pyrScale, //0.5, + numLevels, //3, + winSize, //15, + numIters, //8, + polyN, //5, + polySigma, //1.2, + flags //0 + ); + } + Mat flow; + uflow.copyTo(flow); + qDebug() << "finished"; + drawOptFlowMap(flow, flowfilename); +} + +#elif CV_MAJOR_VERSION == 3 +void FlowSourceOpenCV_sV::buildFlowOpenCV_3(cv::UMat& uprevgray, cv::UMat& ugray, std::string flowfilename) +{ + dumpAlgosParams(); + qDebug() << "Have OpenCL: " << cv::ocl::haveOpenCL() << " useOpenCL:" << cv::ocl::useOpenCL(); + UMat uflow; + if (algo == 1) { // DualTVL1 + cv::Ptr<cv::DualTVL1OpticalFlow> tvl1 = cv::createOptFlow_DualTVL1(); + tvl1->setLambda(lambda); + tvl1->setTau(tau); + tvl1->setScalesNumber(nscales); + tvl1->setWarpingsNumber(warps); + tvl1->setOuterIterations(iterations); + tvl1->setEpsilon(epsilon); + tvl1->calc( + uprevgray, + ugray, + uflow + ); + } else { // _FARN_ + calcOpticalFlowFarneback( + uprevgray, + ugray, + uflow, + pyrScale, //0.5, + numLevels, //3, + winSize, //15, + numIters, //8, + polyN, //5, + polySigma, //1.2, + flags //0 + ); + } + Mat flow; + uflow.copyTo(flow); + qDebug() << "finished"; + drawOptFlowMap(flow, flowfilename); +} + +#else // start CV_MAJOR_VERSION != 3 + +void FlowSourceOpenCV_sV::buildFlowOpenCV_CPU(cv::Mat& prevgray, cv::Mat& gray, std::string flowfilename) +{ + dumpAlgosParams(); + cv::Mat_<cv::Point2f> flow; + if (algo == 1) { // DualTVL1 + cv::Ptr<cv::DenseOpticalFlow> tvl1 = cv::createOptFlow_DualTVL1(); + tvl1->set("lambda", lambda); + tvl1->set("tau", tau); + tvl1->set("nscales", nscales); + tvl1->set("warps", warps); + tvl1->set("iterations", iterations); + tvl1->set("epsilon", epsilon); + tvl1->calc(prevgray, gray, flow); + } else { // _FARN_ + // TODO: check to use prev flow as initial flow ? (flags) + //gray, prevgray, // TBD this seems to match V3D output better but a sign flip could also do that + calcOpticalFlowFarneback( + prevgray, + gray, + flow, + pyrScale, //0.5, + numLevels, //3, + winSize, //15, + numIters, //8, + polyN, //5, + polySigma, //1.2, + flags //0 + ); + } + qDebug() << "finished"; + drawOptFlowMap(flow, flowfilename); +} + +#ifdef HAVE_OPENCV_OCL +/** + * OpenCV2 OCL algos have memleaks. + */ +void FlowSourceOpenCV_sV::buildFlowOpenCV_OCL(cv::Mat& prevgray, cv::Mat& gray, std::string flowfilename) +{ + dumpAlgosParams(); + using namespace cv::ocl; + oclMat ocl_flowx, ocl_flowy; + if (algo == 1) { + OpticalFlowDual_TVL1_OCL tvl1_ocl_alg; + tvl1_ocl_alg.tau = tau; + tvl1_ocl_alg.lambda = lambda; + tvl1_ocl_alg.nscales = nscales; + tvl1_ocl_alg.warps = warps; + tvl1_ocl_alg.epsilon = epsilon; + tvl1_ocl_alg.iterations = iterations; + tvl1_ocl_alg(oclMat(prevgray), oclMat(gray), ocl_flowx, ocl_flowy); + tvl1_ocl_alg.collectGarbage(); + } else { + FarnebackOpticalFlow farneback_ocl_algo; + farneback_ocl_algo.numLevels = numLevels; + farneback_ocl_algo.pyrScale = pyrScale; + farneback_ocl_algo.pyrScale = pyrScale; + farneback_ocl_algo.winSize = winSize; + farneback_ocl_algo.numIters = numIters; + farneback_ocl_algo.polyN = polyN; + farneback_ocl_algo.polySigma = polySigma; + farneback_ocl_algo.flags = flags; + farneback_ocl_algo(oclMat(prevgray), oclMat(gray), ocl_flowx, ocl_flowy); + farneback_ocl_algo.releaseMemory(); + } + Mat flowx, flowy; + ocl_flowx.download(flowx); + ocl_flowy.download(flowy); + drawOptFlowMapSeparateXandY(flowx, flowy, flowfilename); +} + +void FlowSourceOpenCV_sV::setupOclDevice() { + qDebug() << "using olc device index: " << ocl_device_index; + using namespace cv::ocl; + PlatformsInfo platform_infos; + getOpenCLPlatforms(platform_infos); + int index = 0; + for (unsigned int i = 0; i < platform_infos.size(); i++) { + const PlatformInfo *pi = platform_infosi; + for (unsigned int j = 0; j < pi->devices.size(); j++) { + if (index == ocl_device_index) { + const DeviceInfo *dic = pi->devicesj; + DeviceInfo *di = (DeviceInfo *)dic; + di->deviceName = "ocl_devicename_slowmovideo"; + setDevice(di); + break; + } + } + } +} +#endif // end if HAVE_OPENCV_OCL +#endif // above CV_MAJOR_VERSION == 2
View file
slowmoVideo-0.6.tar.xz/src/project/flowSourceOpenCV_sV.h
Added
@@ -0,0 +1,89 @@ +/* +This file is part of slowmoVideo. +Copyright (C) 2012 Lucas Walter + 2012 Simon A. Eugster (Granjow) <simon.eu@gmail.com> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +*/ + +#ifndef FLOWSOURCEOPENCV_SV_H +#define FLOWSOURCEOPENCV_SV_H + + +#include "abstractFlowSource_sV.h" + +#include <QtCore/QDir> + +#include "opencv2/core/version.hpp" +#include "opencv2/video/tracking.hpp" +#include "opencv2/imgproc/imgproc.hpp" +#include "opencv2/highgui/highgui.hpp" +#include "opencv2/opencv_modules.hpp" + +#if CV_MAJOR_VERSION == 2 +#include "opencv2/core/gpumat.hpp" + +#ifdef HAVE_OPENCV_OCL +#include "opencv2/ocl/ocl.hpp" +#endif + +#else +#include "opencv2/core/ocl.hpp" +#endif + + +class FlowSourceOpenCV_sV : public AbstractFlowSource_sV +{ + +public: + FlowSourceOpenCV_sV(Project_sV *project, int algo, int ocl_dev_index); + ~FlowSourceOpenCV_sV() {} + + virtual FlowField_sV* buildFlow(uint leftFrame, uint rightFrame, FrameSize frameSize) noexcept(false); + virtual const QString flowPath(const uint leftFrame, const uint rightFrame, const FrameSize frameSize = FrameSize_Orig) const; + + void setupOpticalFlow(const int levels,const int winsize,const double polySigma, const double pyrScale, const int polyN); + void setupTVL1(const double tau, const double lambda, const int nscales, const int warps, const int iterations, const double epsilon); + + void printOpencvDetails(); + +private: + int ocl_device_index; + int algo; + + // optical flow Farn + int numLevels; + int numIters; + int winSize; + double polySigma; + double pyrScale; + int polyN; + int flags; + + // optical TVL1 + double tau; + double lambda; + int warps; + int nscales; + int iterations; + double epsilon; + +#if CV_MAJOR_VERSION >= 4 + void buildFlowOpenCV_4(cv::UMat& prevgray, cv::UMat& gray, std::string flowfilename); +#elif CV_MAJOR_VERSION == 3 + void buildFlowOpenCV_3(cv::UMat& prevgray, cv::UMat& gray, std::string flowfilename); +#else // OpenCV 2 + void buildFlowOpenCV_CPU(cv::Mat& prevgray, cv::Mat& gray, std::string flowfilename); +#ifdef HAVE_OPENCV_OCL + void buildFlowOpenCV_OCL(cv::Mat& prevgray, cv::Mat& gray, std::string flowfilename); + void setupOclDevice(); +#endif +#endif + + void dumpAlgosParams(); +}; + +#endif // FLOWSOURCEOPENCV_SV_H
View file
slowmoVideo-0.6.tar.xz/src/project/flowSourceV3D_sV.cpp
Added
@@ -0,0 +1,143 @@ +/* +This file is part of slowmoVideo. +Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +*/ + +#include "flowSourceV3D_sV.h" +#include "project_sV.h" +#include "abstractFrameSource_sV.h" +#include "flowRW_sV.h" + +#include <QtCore/QCoreApplication> +#include <QtCore/QProcess> +#include <QtCore/QSettings> +#include <QtCore/QTime> + +FlowSourceV3D_sV::FlowSourceV3D_sV(Project_sV *project, double lambda) : + AbstractFlowSource_sV(project) +{ + createDirectories(); + m_lambda = lambda; +} + + +FlowField_sV* FlowSourceV3D_sV::buildFlow(uint leftFrame, uint rightFrame, FrameSize frameSize) noexcept(false) +{ + QString flowFileName(flowPath(leftFrame, rightFrame, frameSize)); + + /// \todo Check if size is equal + if (!QFile(flowFileName).exists()) { + QSettings settings; + QString programLocation(settings.value("binaries/v3dFlowBuilder", "/usr/local/bin/slowmoFlowBuilder").toString()); + if (!QFile(programLocation).exists()) { + QString newLoc = correctFlowBinaryLocation(); + if (newLoc.length() > 0) { + programLocation = newLoc; + } + } + if (!QFile(programLocation).exists()) { + throw FlowBuildingError("Program\n" + programLocation + "\ndoes not exist (did you compile/make V3D?), cannot build flow!"); + } + QString program(programLocation); + + qDebug() << "Building flow for left frame " << leftFrame << " to right frame " << rightFrame << "; Size: " << frameSize; + + QStringList args; + args << project()->frameSource()->framePath(leftFrame, frameSize) + << project()->frameSource()->framePath(rightFrame, frameSize) + << flowFileName + << QVariant(m_lambda).toString() << "100"; + + qDebug() << "Arguments: " << args; + + + QTime time; + QProcess proc; + + time.start(); + proc.start(program, args); + proc.waitForFinished(-1); + if (proc.exitCode() != 0) { + qDebug() << "Failed: " << proc.readAllStandardError() << proc.readAllStandardOutput(); + throw FlowBuildingError(QString("Flow builder exited with exit code %1; For details see debugging output").arg(proc.exitCode())); + } else { + qDebug() << "Optical flow built for " << flowFileName << " in " << time.elapsed() << " ms"; + qDebug() << proc.readAllStandardError() << proc.readAllStandardOutput(); + } + } else { + qDebug().nospace() << "Re-using existing flow image for left frame " << leftFrame << " to right frame " << rightFrame << ": " << flowFileName; + } + + try { + return FlowRW_sV::load(flowFileName.toStdString()); + } catch (FlowRW_sV::FlowRWError &err) { + throw FlowBuildingError(err.what()); + } +} + + + +QString FlowSourceV3D_sV::correctFlowBinaryLocation() +{ + QSettings settings; + QString programLocation(settings.value("binaries/v3dFlowBuilder", "/usr/local/bin/slowmoFlowBuilder").toString()); + + QStringList paths; + paths << programLocation; + paths << QDir::currentPath() + "/slowmoFlowBuilder"; + paths << QCoreApplication::applicationDirPath() + "/slowmoFlowBuilder"; + paths << "/usr/bin/slowmoFlowBuilder" << "/usr/local/bin/slowmoFlowBuilder"; + for (int i = 0; i < paths.size(); i++) { + if (validateFlowBinary(paths.at(i))) { + settings.setValue("binaries/v3dFlowBuilder", paths.at(i)); + return paths.at(i); + } + } + return QString(); +} + +bool FlowSourceV3D_sV::validateFlowBinary(const QString path) +{ + bool valid = false; + qDebug() << "Checking " << path << " ..."; + if (QFile(path).exists() && QFileInfo(path).isExecutable()) { + QProcess process; + QStringList args; + args << "--identify"; + process.start(path, args); + process.waitForFinished(2000); + QString output(process.readAllStandardOutput()); + if (output.startsWith("slowmoFlowBuilder")) { + valid = true; + qDebug() << path << " is valid."; + } else { + qDebug() << "Invalid output from flow executable: " << output; + } + process.terminate(); + } + return valid; +} + + +const QString FlowSourceV3D_sV::flowPath(const uint leftFrame, const uint rightFrame, const FrameSize frameSize) const +{ + QDir dir; + if (frameSize == FrameSize_Orig) { + dir = m_dirFlowOrig; + } else { + dir = m_dirFlowSmall; + } + QString direction; + if (leftFrame < rightFrame) { + direction = "forward"; + } else { + direction = "backward"; + } + + return dir.absoluteFilePath(QString("%1-lambda%4_%2-%3.sVflow").arg(direction).arg(leftFrame).arg(rightFrame).arg(m_lambda, 0, 'f', 2)); +}
View file
slowmoVideo-0.6.tar.xz/src/project/flowSourceV3D_sV.h
Added
@@ -0,0 +1,36 @@ +/* +This file is part of slowmoVideo. +Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +*/ + +#ifndef V3DFLOWSOURCE_SV_H +#define V3DFLOWSOURCE_SV_H + +#include "abstractFlowSource_sV.h" + +#include <QtCore/QDir> + +class FlowSourceV3D_sV : public AbstractFlowSource_sV +{ +public: + /** Creates a new flow source using V3D optical flow */ + FlowSourceV3D_sV(Project_sV *project, double lambda = 10); + ~FlowSourceV3D_sV() {} + + + FlowField_sV* buildFlow(uint leftFrame, uint rightFrame, FrameSize frameSize) noexcept(false); + const QString flowPath(const uint leftFrame, const uint rightFrame, const FrameSize frameSize) const; + + static bool validateFlowBinary(const QString path); + static QString correctFlowBinaryLocation(); + +private: + +}; + +#endif // V3DFLOWSOURCE_SV_H
View file
slowmoVideo-0.6.tar.xz/src/project/imagesFrameSource_sV.cpp
Added
@@ -0,0 +1,148 @@ +/* +This file is part of slowmoVideo. +Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +*/ + +#include "imagesFrameSource_sV.h" +#include "project_sV.h" + +#include <QtCore/QFileInfo> +#include <QtCore/QDebug> +#include <QtGui/QImageReader> + +ImagesFrameSource_sV::ImagesFrameSource_sV(Project_sV *project, QStringList images) noexcept(false) : + AbstractFrameSource_sV(project), + m_fps(24, 1), + m_initialized(false), + m_stopInitialization(false), + m_nextFrame(0) +{ + QString msg = validateImages(images); + if (msg.length() > 0) { + throw FrameSourceError("Image frame source: " + msg); + } + + m_imagesList.append(images); + m_imagesList.sort(); + + QImage repImage(m_imagesList.at(0)); + if (repImage.isNull()) { + qDebug() << "Image is null: " << m_imagesList.at(0); + qDebug() << "Supported image formats: " << QImageReader::supportedImageFormats(); + throw FrameSourceError(QString("Cannot read image: %1").arg(m_imagesList.at(0))); + } + m_sizeSmall = repImage.size(); + if (m_sizeSmall.isEmpty()) { + throw FrameSourceError(QString("Image read from %1 is empty.").arg(m_imagesList.at(0))); + } + while (m_sizeSmall.width() > 600) { + m_sizeSmall = m_sizeSmall/2; + } + + createDirectories(); +} + +QString ImagesFrameSource_sV::validateImages(const QStringList images) +{ + if (images.size() == 0) { return tr("No images selected."); } + + QSize size = QImage(images.at(0)).size(); + for (int i = 0; i < images.length(); i++) { + if (QImage(images.at(i)).size() != size) { + return tr("Image %1 is not of the same size (%2) as the first image (%3).") + .arg(images.at(i)).arg(toString(QImage(images.at(i)).size())).arg(toString(size)); + } + } + return QString(); +} + +const QStringList ImagesFrameSource_sV::inputFiles() const +{ + return m_imagesList; +} + +void ImagesFrameSource_sV::slotUpdateProjectDir() +{ + //TODO: really needed ? + //m_dirImagesSmall.rmdir("."); + createDirectories(); +} + +void ImagesFrameSource_sV::createDirectories() +{ + m_dirImagesSmall = m_project->getDirectory("frames/imagesSmall"); +} + +void ImagesFrameSource_sV::initialize() +{ + m_stopInitialization = false; + QMetaObject::invokeMethod(this, "slotContinueInitialization", Qt::QueuedConnection); +} +bool ImagesFrameSource_sV::initialized() const +{ + return m_initialized; +} + +/// \todo What if image missing? +void ImagesFrameSource_sV::slotContinueInitialization() +{ + emit signalNextTask(tr("Creating preview images from the input images"), m_imagesList.size()); + for (; m_nextFrame < m_imagesList.size(); m_nextFrame++) { + + QString outputFile(framePath(m_nextFrame, FrameSize_Small)); + if (QFile(outputFile).exists()) { + emit signalTaskItemDescription(tr("Resized image already exists for %1").arg(QFileInfo(m_imagesList.at(m_nextFrame)).fileName())); + } else { + emit signalTaskItemDescription(tr("Re-sizing image %1 to:\n%2") + .arg(QFileInfo(m_imagesList.at(m_nextFrame)).fileName()) + .arg(outputFile)); + QImage small = QImage(m_imagesList.at(m_nextFrame)).scaled(m_sizeSmall, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + small.save(outputFile); + } + + emit signalTaskProgress(m_nextFrame); + if (m_stopInitialization) { + break; + } + } + m_initialized = true; + emit signalAllTasksFinished(); +} + +void ImagesFrameSource_sV::slotAbortInitialization() +{ + m_stopInitialization = true; +} + +int64_t ImagesFrameSource_sV::framesCount() const +{ + return m_imagesList.size(); +} +const Fps_sV* ImagesFrameSource_sV::fps() const +{ + return &m_fps; +} + +QImage ImagesFrameSource_sV::frameAt(const uint frame, const FrameSize frameSize) +{ + if (int(frame) < m_imagesList.size()) { + return QImage(framePath(frame, frameSize)); + } else { + return QImage(); + } +} +const QString ImagesFrameSource_sV::framePath(const uint frame, const FrameSize frameSize) const +{ + switch (frameSize) { + case FrameSize_Orig: + return QString(m_imagesList.at(frame)); + case FrameSize_Small: + default: + return QString(m_dirImagesSmall.absoluteFilePath(QFileInfo(m_imagesList.at(frame)).completeBaseName() + ".png")); + } +}
View file
slowmoVideo-0.6.tar.xz/src/project/imagesFrameSource_sV.h
Added
@@ -0,0 +1,69 @@ +/* +This file is part of slowmoVideo. +Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +*/ + +#ifndef IMAGESFRAMESOURCE_SV_H +#define IMAGESFRAMESOURCE_SV_H + +#include "abstractFrameSource_sV.h" +#include <QtCore/QStringList> +#include <QtCore/QDir> +#include <QtCore/QSize> + +class Project_sV; + +/** + \todo Allow re-ordering of images + \todo Check image resolution more efficiently for large number of images + \todo Support OpenEXR or similar through ffmpeg. 16-bit images. + */ +class ImagesFrameSource_sV : public AbstractFrameSource_sV +{ + Q_OBJECT +public: + ImagesFrameSource_sV(Project_sV *project, QStringList images) noexcept(false); + + static QString validateImages(const QStringList images); + + void initialize(); + bool initialized() const; + + int64_t framesCount() const; + const Fps_sV* fps() const; + QImage frameAt(const uint frame, const FrameSize frameSize = FrameSize_Orig); + const QString framePath(const uint frame, const FrameSize frameSize) const; + + const QStringList inputFiles() const; + + void loadOrigFrames() { }; // TODO + +public slots: + void slotAbortInitialization(); + void slotUpdateProjectDir(); + +private: + QStringList m_imagesList; + QDir m_dirImagesSmall; + QSize m_sizeSmall; + + Fps_sV m_fps; + + bool m_initialized; + bool m_stopInitialization; + int m_nextFrame; + + void createDirectories(); + + +private slots: + void slotContinueInitialization(); + +}; + +#endif // IMAGESFRAMESOURCE_SV_H
View file
slowmoVideo-0.6.tar.xz/src/project/imagesRenderTarget_sV.cpp
Added
@@ -0,0 +1,50 @@ +/* +This file is part of slowmoVideo. +Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +*/ + +#include "imagesRenderTarget_sV.h" + +#include <QtCore/QDebug> + +ImagesRenderTarget_sV::ImagesRenderTarget_sV(RenderTask_sV *parentRenderTask) : + AbstractRenderTarget_sV(parentRenderTask) +{ + m_targetDir = QDir::temp(); + m_filenamePattern = "rendered-%1.jpg"; +} + +void ImagesRenderTarget_sV::setTargetDir(const QDir dir) +{ + m_targetDir = dir; +} + +bool ImagesRenderTarget_sV::setFilenamePattern(const QString pattern) +{ + if (pattern.contains("%1")) { + m_filenamePattern = pattern; + return true; + } + return false; +} + +void ImagesRenderTarget_sV::slotConsumeFrame(const QImage &image, const int frameNumber) +{ + if (!m_targetDir.exists()) { + m_targetDir.mkpath("."); + } + QString path = m_targetDir.absoluteFilePath(m_filenamePattern.arg(frameNumber+1, 5, 10, QChar::fromLatin1('0'))); + + bool ok; + ok = image.save(path); + if (!ok) { + qDebug() << " Writing image to " << path << " failed!"; + } else { + qDebug() << " Saved frame number " << frameNumber << " to " << path; + } +}
View file
slowmoVideo-0.6.tar.xz/src/project/imagesRenderTarget_sV.h
Added
@@ -0,0 +1,40 @@ +/* +This file is part of slowmoVideo. +Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +*/ + +#ifndef IMAGESRENDERTARGET_SV_H +#define IMAGESRENDERTARGET_SV_H + +#include "abstractRenderTarget_sV.h" + +#include <QtCore/QDir> + +class RenderTask_sV; + +class ImagesRenderTarget_sV : public AbstractRenderTarget_sV +{ +public: + ImagesRenderTarget_sV(RenderTask_sV *parentRenderTask); + + virtual void openRenderTarget() noexcept(false) {} ; + virtual void closeRenderTarget() noexcept(false) {} ; + + + void setTargetDir(const QDir dir); + bool setFilenamePattern(const QString pattern); + +public slots: + void slotConsumeFrame(const QImage &image, const int frameNumber); + +private: + QDir m_targetDir; + QString m_filenamePattern; +}; + +#endif // IMAGESRENDERTARGET_SV_H
View file
slowmoVideo-0.6.tar.xz/src/project/interpolator_sV.cpp
Added
@@ -0,0 +1,123 @@ +#include "interpolator_sV.h" +#include "abstractFrameSource_sV.h" +#include "flowField_sV.h" +#include "../lib/interpolate_sV.h" +#include <QtCore/QObject> + +#define MIN_FRAME_DIST .001 + +QImage Interpolator_sV::interpolate(Project_sV *pr, float frame, const RenderPreferences_sV &prefs) noexcept(false) +{ + if (frame > pr->frameSource()->framesCount()) { + throw InterpolationError(QObject::tr("Requested frame %1: Not within valid range. (%2 frames)") + .arg(frame).arg(pr->frameSource()->framesCount())); + } + if (frame-floor(frame) > MIN_FRAME_DIST) { + + QImage left = pr->frameSource()->frameAt(floor(frame), prefs.size); + QImage right = pr->frameSource()->frameAt(floor(frame)+1, prefs.size); + QImage out(left.size(), QImage::Format_ARGB32); + + /// Position between two frames, on 0 1 + const float pos = frame-floor(frame); + + switch (prefs.interpolation) { + case InterpolationType_Twoway: { + FlowField_sV *forwardFlow = pr->requestFlow(floor(frame), floor(frame)+1, prefs.size); + FlowField_sV *backwardFlow = pr->requestFlow(floor(frame)+1, floor(frame), prefs.size); + + Q_ASSERT(forwardFlow != NULL); + Q_ASSERT(backwardFlow != NULL); + + if (forwardFlow == NULL || backwardFlow == NULL) { + qDebug() << "No flow received!"; + Q_ASSERT(false); + } + + Interpolate_sV::twowayFlow(left, right, forwardFlow, backwardFlow, pos, out); + delete forwardFlow; + delete backwardFlow; + + } + break; + case InterpolationType_TwowayNew: { + FlowField_sV *forwardFlow = pr->requestFlow(floor(frame), floor(frame)+1, prefs.size); + FlowField_sV *backwardFlow = pr->requestFlow(floor(frame)+1, floor(frame), prefs.size); + + Q_ASSERT(forwardFlow != NULL); + Q_ASSERT(backwardFlow != NULL); + + if (forwardFlow == NULL || backwardFlow == NULL) { + qDebug() << "No flow received!"; + Q_ASSERT(false); + } + + Interpolate_sV::newTwowayFlow(left, right, forwardFlow, backwardFlow, pos, out); + delete forwardFlow; + delete backwardFlow; + + } + break; + case InterpolationType_Forward: { + FlowField_sV *forwardFlow = pr->requestFlow(floor(frame), floor(frame)+1, prefs.size); + + Q_ASSERT(forwardFlow != NULL); + + if (forwardFlow == NULL) { + qDebug() << "No flow received!"; + Q_ASSERT(false); + } + + Interpolate_sV::forwardFlow(left, forwardFlow, pos, out); + delete forwardFlow; + + } + break; + case InterpolationType_ForwardNew: { + FlowField_sV *forwardFlow = pr->requestFlow(floor(frame), floor(frame)+1, prefs.size); + + Q_ASSERT(forwardFlow != NULL); + + if (forwardFlow == NULL) { + qDebug() << "No flow received!"; + Q_ASSERT(false); + } + + Interpolate_sV::newForwardFlow(left, forwardFlow, pos, out); + delete forwardFlow; + + } + break; + case InterpolationType_Bezier: { + FlowField_sV *currNext = pr->requestFlow(floor(frame)+2, floor(frame)+1, prefs.size); // Allowed to be NULL + FlowField_sV *currPrev = pr->requestFlow(floor(frame)+0, floor(frame)+1, prefs.size); + + Q_ASSERT(currPrev != NULL); + + Interpolate_sV::bezierFlow(left, right, currPrev, currNext, pos, out); + + delete currNext; + delete currPrev; + + } + break; + case InterpolationType_None: { + //qDebug() << "Simple interpolation type!"; + Interpolate_sV::simpleinterpolate(left, right, pos, out); + } + break; + case InterpolationType_Nearest: { + Interpolate_sV::nearestinterpolate(left, right, pos, out); + } + break; + default : { + qDebug() << "Unsupported interpolation type!"; + Q_ASSERT(false); + } + } + return out; + } else { + qDebug() << "No interpolation necessary."; + return pr->frameSource()->frameAt(floor(frame), prefs.size); + } +}
View file
slowmoVideo-0.6.tar.xz/src/project/interpolator_sV.h
Added
@@ -0,0 +1,13 @@ +#ifndef INTERPOLATOR_SV_H +#define INTERPOLATOR_SV_H + +#include "renderPreferences_sV.h" +#include "project_sV.h" + +class Interpolator_sV +{ +public: + static QImage interpolate(Project_sV *project, float frame, const RenderPreferences_sV& prefs) noexcept(false); +}; + +#endif // INTERPOLATOR_SV_H
View file
slowmoVideo-0.6.tar.xz/src/project/motionBlur_sV.cpp
Added
@@ -0,0 +1,288 @@ +/* +This file is part of slowmoVideo. +Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +*/ + +#include "motionBlur_sV.h" +#include "project_sV.h" +#include "abstractFrameSource_sV.h" +#include "abstractFlowSource_sV.h" +#include "interpolator_sV.h" +#include "renderTask_sV.h" +#include "flowField_sV.h" +#include "../lib/shutter_sV.h" + +#define MAX_CONV_FRAMES 5 + +//#define DEBUG + +MotionBlur_sV::MotionBlur_sV(Project_sV *project) : + m_project(project), + m_slowmoSamples(16), + m_maxSamples(64), + m_slowmoMaxFrameDist(.5) +{ + createDirectories(); +} + +QImage MotionBlur_sV::blur(float startFrame, float endFrame, float replaySpeed, RenderPreferences_sV prefs) noexcept(false) +{ + if (prefs.motionblur == MotionblurType_Nearest) { + return nearest(startFrame, prefs); + } else if (prefs.motionblur == MotionblurType_Convolving) { + return convolutionBlur(startFrame, endFrame, replaySpeed, prefs); + } else { + if (replaySpeed > 0.5) { + return fastBlur(startFrame, endFrame, prefs); + } else { + return slowmoBlur(startFrame, endFrame, prefs); + } + } +} + +QImage MotionBlur_sV::nearest(float startFrame, const RenderPreferences_sV &prefs) +{ + return m_project->frameSource()->frameAt(startFrame, prefs.size); +} + +QImage MotionBlur_sV::fastBlur(float startFrame, float endFrame, const RenderPreferences_sV &prefs) noexcept(false) +{ + float low, high; + if (startFrame < endFrame) { + low = startFrame; high = endFrame; + } else { + low = endFrame; high = startFrame; + } + low = qMax(low, float(0)); + high = qMin(high, (float)m_project->frameSource()->framesCount()-1); + + float dist = 0.125; + float lowRounded; + float highRounded; + for (; ; dist *= 2) { + lowRounded = ceil(low/dist)*dist; + highRounded = floor(high/dist)*dist; + if ((highRounded-lowRounded)/dist <= m_maxSamples) { + break; + } + } + + float pos = lowRounded; + + QStringList frameList; + + while (pos < high) { + frameList << cachedFramePath(pos, prefs); + pos += dist; + } + qDebug() << "Fast blurring " << frameList.size() << " frames from " << startFrame << " to " << endFrame << ", low: " << low + << ", high: " << high << ", with a distance of " << dist; + + if (frameList.size() > 1) { + return Shutter_sV::combine(frameList); + } else { + throw RangeTooSmallError_sV(QObject::tr("Range too small: Start frame is %1, end frame is %2. " + "Using normal interpolation.").arg(startFrame).arg(endFrame)); + } + +} + +/// \todo fixed distance as additional option +QImage MotionBlur_sV::slowmoBlur(float startFrame, float endFrame, const RenderPreferences_sV &prefs) +{ + float low, high; + if (startFrame < endFrame) { + low = startFrame; high = endFrame; + } else { + low = endFrame; high = startFrame; + } + low = qMax(low, float(0)); + high = qMin(high, (float)m_project->frameSource()->framesCount()); + + QStringList frameList; + float increment = (high-low)/(m_slowmoSamples-1); + if (increment < .1) { + qDebug() << "slowmoBlur(): Increasing distance from " << increment << " to .1"; + increment = .1; + } + if (increment > m_slowmoMaxFrameDist) { + qDebug() << "slowmoBlur(): Decreasing distance from " << increment << " to " << m_slowmoMaxFrameDist; + increment = m_slowmoMaxFrameDist; + } + for (float pos = low; pos <= high; pos += increment) { + frameList << cachedFramePath(pos, prefs, true); + } + + return Shutter_sV::combine(frameList); +} + +QImage MotionBlur_sV::convolutionBlur(float startFrame, float endFrame, float replaySpeed, const RenderPreferences_sV &prefs) +{ + float low, high; + if (startFrame < endFrame) { + low = startFrame; high = endFrame; + } else { + low = endFrame; high = startFrame; + } + low = qMax(low, float(0)); + high = qMin(high, (float)m_project->frameSource()->framesCount()-1); + + if (floor(low) == floor(high) && low > .01) { + if (floor(low) < m_project->frameSource()->framesCount()-1) { + qDebug() << "Small shutter." << startFrame << endFrame; + FlowField_sV *field = m_project->requestFlow(floor(low), floor(low)+1, prefs.size); + QImage blur = Shutter_sV::convolutionBlur(Interpolator_sV::interpolate(m_project, startFrame, prefs), + field, + high-low, + low-floor(low)); + delete field; + return blur; + } else { + /// \todo Convolve last frame as well + qDebug() << "No shutter, at the last frame."; + return m_project->frameSource()->frameAt(floor(low), prefs.size); + } + } + + QList<QImage> images; + FlowField_sV *field; + int start = floor(low); + int end = std::min((int64_t)ceil(high), m_project->frameSource()->framesCount()-2); + int inc = 1; + qDebug() << "Large shutter." << startFrame << endFrame << " -- replay speed is " << replaySpeed; + qDebug() << "Additional parts: " << start << end; + if (replaySpeed < 2) { + // \todo Lower weight for those frames when combining + if (low-start > .1) { + qDebug() << "First part: " << start << low; + field = m_project->requestFlow(start, start+1, prefs.size); + images << Shutter_sV::convolutionBlur(Interpolator_sV::interpolate(m_project, startFrame, prefs), + field, + floor(low)+1 - low, + low-floor(low)); + delete field; + start++; + } + if (end-high > .1) { + qDebug() << "Last part: " << end-1 << high; + field = m_project->requestFlow(end-1, end, prefs.size); + images << Shutter_sV::convolutionBlur(m_project->frameSource()->frameAt(end-1, prefs.size), + field, + 1 + high-end); + delete field; + end--; + } + } else { + // \todo Check increment value + while ((end-start) / inc > MAX_CONV_FRAMES) { + if (inc == 1) { + inc = 2; + } else { + inc += 2; + } + } + start = start - start%inc; + end = end - end%inc; + qDebug() << "Parts scaled to " << start << end << " with increment " << inc; + } + for (int f = start; f <= end; f += inc) { + QString name = QString("%1/convolved-%2+%3.png").arg(cacheDir(prefs.size).absolutePath()).arg(f).arg(inc); + if (replaySpeed < 2) { + if (QFileInfo(name).exists()) { + qDebug() << "Using convolved image from cache: " << name; + images << QImage(name); + continue; + } + } + field = m_project->requestFlow(f, f+1, prefs.size); + images << Shutter_sV::convolutionBlur(m_project->frameSource()->frameAt(f, prefs.size), + field, + inc); + if (replaySpeed < 2) { + qDebug() << "Caching convolved image: " << name; + images.last().save(name); + } + + delete field; + } + +#ifdef DEBUG + for (int i = 0; i < images.size(); i++) { + images.at(i).save(QString("/tmp/mblur-%1.png").arg(i)); + } +#endif + + return Shutter_sV::combine(images); +} + +QDir MotionBlur_sV::cacheDir(FrameSize size) const +{ + switch (size) { + case FrameSize_Small: + return m_dirCacheSmall; + case FrameSize_Orig: + return m_dirCacheOrig; + default: + qDebug() << "Unknown frame size in MotionBlur_sV: " << toString(size); + Q_ASSERT(false); + return QDir(); + } +} + +QString MotionBlur_sV::cachedFramePath(float framePos, const RenderPreferences_sV &prefs, bool highPrecision) +{ + int precision = 2; + if (highPrecision) { precision = 2; } /// \todo check precision + int width = 5+1 + precision; + QString name = QString("%2/cached%1.png").arg(framePos, width, 'f', precision, '0'); + if (prefs.size == FrameSize_Small) { + name = name.arg(m_dirCacheSmall.absolutePath()); + } else if (prefs.size == FrameSize_Orig) { + name = name.arg(m_dirCacheOrig.absolutePath()); + } else { + qDebug() << "MotionBlur: Frame size " << toString(prefs.size) << " given, not supported!"; + Q_ASSERT(false); + } + if (fabs(framePos-int(framePos)) < MOTIONBLUR_PRECISION_LIMIT) { + name = m_project->frameSource()->framePath(uint(framePos), prefs.size); + } else { + if (!QFileInfo(name).exists()) { + qDebug() << name << " does not exist yet. Interpolating and saving to cache."; + QImage frm = Interpolator_sV::interpolate(m_project, framePos, prefs); + frm.save(name); + } + } + return name; +} + +void MotionBlur_sV::slotUpdateProjectDir() +{ + //TODO: check if really needed ? + //m_dirCacheSmall.rmdir("."); + //m_dirCacheOrig.rmdir("."); + createDirectories(); +} + + +void MotionBlur_sV::createDirectories() +{ + m_dirCacheSmall = m_project->getDirectory("cache/motionBlurSmall"); + m_dirCacheOrig = m_project->getDirectory("cache/motionBlurOrig"); +} + +void MotionBlur_sV::setSlowmoSamples(int slowmoSamples) +{ + m_slowmoSamples = slowmoSamples; + Q_ASSERT(m_slowmoSamples > 0); +} + +void MotionBlur_sV::setMaxSamples(int maxSamples) +{ + m_maxSamples = maxSamples; + Q_ASSERT(m_maxSamples > 0); +}
View file
slowmoVideo-0.6.tar.xz/src/project/motionBlur_sV.h
Added
@@ -0,0 +1,96 @@ +/* +This file is part of slowmoVideo. +Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +*/ + +#ifndef MOTIONBLUR_SV_H +#define MOTIONBLUR_SV_H + +#include <QtCore/QDir> +#include <QtGui/QImage> +#include "renderPreferences_sV.h" +class Project_sV; + +/// Thrown if the frame range is too small for motion blur to still make sense +class RangeTooSmallError_sV : public Error_sV { +public: + RangeTooSmallError_sV(QString msg) : Error_sV(msg) {} +}; + +/// If a frame is closer than this to a full frame, the full frame will be used instead. +#define MOTIONBLUR_PRECISION_LIMIT .01 + +/** + \brief Renders motion blur + \todo Force fast blurring for a segment? + \todo Use .jpg for cached frames? + */ +class MotionBlur_sV +{ +public: + MotionBlur_sV(Project_sV *project); + + /** + Selects either fastBlur() or slowmoBlur(), depending on the replay speed. + \param replaySpeed Must be >= 0 + */ + QImage blur(float startFrame, float endFrame, float replaySpeed, RenderPreferences_sV prefs) noexcept(false); + + /** + Blurs frames using cached frames on fixed, coarse-grained intervals. + If the replay speed is high enough, it does not matter if frame 1.424242 or frame 1.5 is used + together with other frames for rendering motion blur. That way calculation can be sped up a little bit. + */ + QImage fastBlur(float startFrame, float endFrame, const RenderPreferences_sV &prefs) noexcept(false); + + /** + Blurs frames that are re-played at very low speed, such that fastBlur() cannot be used. + The blurred parts of the image still need to move slowly, rounding frames to interpolate to 0.5 + would not work therefore. + */ + QImage slowmoBlur(float startFrame, float endFrame, const RenderPreferences_sV& prefs); + + QImage convolutionBlur(float startFrame, float endFrame, float replaySpeed, const RenderPreferences_sV& prefs); + + QImage nearest(float startFrame, const RenderPreferences_sV& prefs); + + /** + \fn setSlowmoSamples(); + Sets the minimum number of samples for motion blur. This is ignored by fastBlur() where the interpolation scale + is fixed (i.e. at most 1/8 steps between two frames). However slowmoBlur() uses this exact value for interpolating. + */ + /** + \fn setMaxSamples(); + Sets the maximum number of samples that are used for rendering motion blur. + */ + void setSlowmoSamples(int slowmoSamples); + void setMaxSamples(int maxSamples); + void setSlowmoMaxFrameDistance(float distance); + + int slowmoSamples() const { return m_slowmoSamples; } + int maxSamples() const { return m_maxSamples; } + +public slots: + void slotUpdateProjectDir(); + +private: + Project_sV *m_project; + QDir m_dirCacheSmall; + QDir m_dirCacheOrig; + + int m_slowmoSamples; + int m_maxSamples; + float m_slowmoMaxFrameDist; + + QString cachedFramePath(float framePos, const RenderPreferences_sV &prefs, bool highPrecision = false); + void createDirectories(); + + QDir cacheDir(FrameSize size) const; +}; + +#endif // MOTIONBLUR_SV_H
View file
slowmoVideo-0.6.tar.xz/src/project/new_videoRenderTarget.cpp
Added
@@ -0,0 +1,67 @@ +/* +This file is part of slowmoVideo. +Copyright (C) 2014 Valery Brasseur <vbrasseur@gmail.com> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +*/ + +// Against the «UINT64_C not declared» message. +// See: http://code.google.com/p/ffmpegsource/issues/detail?id=11 +#ifdef __cplusplus + #define __STDC_CONSTANT_MACROS + #ifdef _STDINT_H + #undef _STDINT_H + #endif + # include <stdint.h> +#endif + +#include "new_videoRenderTarget.h" +#include "renderTask_sV.h" +#include <QtCore/QObject> + +#include "../lib/video_enc.h" + +newVideoRenderTarget::newVideoRenderTarget(RenderTask_sV *parentRenderTask) : + AbstractRenderTarget_sV(parentRenderTask) +{ + +} +newVideoRenderTarget::~newVideoRenderTarget() +{ + +} + +void newVideoRenderTarget::setTargetFile(const QString &filename) +{ + m_filename = filename; +} +void newVideoRenderTarget::setVcodec(const QString &codec) +{ + m_vcodec = codec; +} + +void newVideoRenderTarget::openRenderTarget() noexcept(false) +{ + writer = CreateVideoWriter(m_filename.toStdString().c_str(), + renderTask()->resolution().width(), + renderTask()->resolution().height(), + renderTask()->fps().fps(),1, m_vcodec.toStdString().c_str()); + + + if (writer == 0) { + throw Error_sV(QObject::tr("Video could not be prepared .\n")); + } +} + +void newVideoRenderTarget::slotConsumeFrame(const QImage &image, const int frameNumber) +{ + WriteFrame(writer, image); +} + +void newVideoRenderTarget::closeRenderTarget() noexcept(false) +{ + ReleaseVideoWriter( &writer ); +}
View file
slowmoVideo-0.6.tar.xz/src/project/new_videoRenderTarget.h
Added
@@ -0,0 +1,50 @@ +/* +This file is part of slowmoVideo. +Copyright (C) 2014 Valery Brasseur <vbrasseur@gmail.com> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +*/ + +/* + * handle both ffmpeg and qtkit + */ +#ifndef NEW_VIDEORENDERTARGET_SV_H +#define NEW_VIDEORENDERTARGET_SV_H + +#include "abstractRenderTarget_sV.h" + +class VideoWriter; +class RenderTask_sV; + +/// Produces videos from frames. +class newVideoRenderTarget : public AbstractRenderTarget_sV +{ +public: + /// Constructs a new video render target + newVideoRenderTarget(RenderTask_sV *parentRenderTask); + virtual ~newVideoRenderTarget(); + + /// openRenderTarget() will throw an error if the target file cannot be opened. + void setTargetFile(const QString& filename); + /// Set a custom video codec + void setVcodec(const QString& codec); + + void openRenderTarget() noexcept(false); + void closeRenderTarget() noexcept(false); + +public slots: + void slotConsumeFrame(const QImage &image, const int frameNumber); + +private: + QString m_filename; + QString m_vcodec; + VideoWriter* writer; + + int m_width; + int m_height; +}; + +#endif // NEW_VIDEORENDERTARGET_SV_H
View file
slowmoVideo-0.6.tar.xz/src/project/nodeHandle_sV.cpp
Changed
(renamed from src/slowmoVideo/project/nodeHandle_sV.cpp)
View file
slowmoVideo-0.6.tar.xz/src/project/nodeHandle_sV.h
Changed
(renamed from src/slowmoVideo/project/nodeHandle_sV.h)
View file
slowmoVideo-0.6.tar.xz/src/project/nodeList_sV.cpp
Added
@@ -0,0 +1,625 @@ +/* +slowmoUI is a user interface for slowmoVideo. +Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +*/ + +#include "nodeList_sV.h" +#include "node_sV.h" +#include "../lib/bezierTools_sV.h" + +#include <cmath> + +#include <QDebug> + +//#define DEBUG_NL +#ifdef DEBUG_NL +#include <iostream> +#endif + +NodeList_sV::NodeList_sV(float minDist) : + m_maxY(10), + m_list(), + m_minDist(minDist) +{ +} + +void NodeList_sV::setMaxY(qreal time) +{ + Q_ASSERT(time > 0); + m_maxY = time; +} + +qreal NodeList_sV::startTime(bool useMoved) const +{ + if (m_list.length() > 0) { + if (useMoved) { + return m_list0.x(); + } else { + return m_list0.xUnmoved(); + } + } else { +// qDebug() << "No start time available (no nodes)"; + return 0; + } +} +qreal NodeList_sV::endTime(bool useMoved) const +{ + if (m_list.length() > 0) { + if (useMoved) { + return m_listm_list.length()-1.x(); + } else { + return m_listm_list.length()-1.xUnmoved(); + } + } else { +// qDebug() << "No end time available (no nodes)"; + return 0; + } +} +bool NodeList_sV::isInsideCurve(qreal targetTime, bool useMoved) const +{ + return m_list.size() >= 2 && + startTime(useMoved) <= targetTime && + targetTime <= endTime(useMoved); +} +qreal NodeList_sV::totalTime() const +{ + return endTime()-startTime(); +} +qreal NodeList_sV::sourceTime(qreal targetTime) const +{ + qreal srcTime = -1; + int index = find(targetTime); + if (index >= 0) { + if (m_list.size() > index+1) { + if (m_list.at(index).rightCurveType() == CurveType_Bezier + && m_list.at(index+1).leftCurveType() == CurveType_Bezier) { + srcTime = BezierTools_sV::interpolateAtX(targetTime, + m_list.at(index).toQPointF(), + m_list.at(index).toQPointF()+m_list.at(index).rightNodeHandle(), + m_list.at(index+1).toQPointF()+m_list.at(index+1).leftNodeHandle(), + m_list.at(index+1).toQPointF()).y(); + } else { + float ratio = (targetTime-m_listindex.x())/(m_listindex+1.x()-m_listindex.x()); + srcTime = m_listindex.y() + ratio*( m_listindex+1.y()-m_listindex.y() ); + } + } else { + //TODO: + if (index >= m_list.size()) { + qDebug() << "index " << index << " is > list size: " << m_list.size(); + //Q_ASSERT(false); + } else { + srcTime = m_listindex.y(); + } + } + } else { + // this seem because no project loaded ? + // TODO: how can we check ? + qDebug() << "No node before " << targetTime; + //Q_ASSERT(false); + if (m_list.size() > 0) { + srcTime = m_list0.y(); + } + } + return srcTime; +} + +bool NodeList_sV::add(Node_sV node) +{ + bool add = true; + +#ifdef DEBUG_NL + qDebug() << "Before adding: \n" << *this; +#endif + + node.setX(qMax(.0, node.x())); + node.setY(qMax(.0, qMin(m_maxY, node.y()))); + + int pos = find(node.x()); + if (pos >= 0 && m_list.size() > pos) { + add = fabs(node.x()-m_list.at(pos).x()) > m_minDist; +#ifdef DEBUG_NL + qDebug() << "Left distance is " << fabs(node.x()-m_list.at(pos).x()); +#endif + if (add && m_list.size() > pos+1) { + add = fabs(node.x()-m_list.at(pos+1).x()) > m_minDist; +#ifdef DEBUG_NL + qDebug() << "Right distance is " << fabs(node.x()-m_list.at(pos+1).x()); +#endif + } + } +#ifdef DEBUG_NL + qDebug() << "Adding? " << add; +#endif + if (add) { + m_list.append(node); + qSort(m_list); + + if (m_list.size() > 1) { + m_segments.grow(); + } + + // Reset curve type of neighbours if this is a linear node + int index = m_list.indexOf(node); + if (index > 0 && node.leftCurveType() == CurveType_Linear) { + m_listindex-1.setRightCurveType(CurveType_Linear); + } + if (index < m_list.size()-1 && node.rightCurveType() == CurveType_Linear) { + m_listindex+1.setLeftCurveType(CurveType_Linear); + } + + fixHandles(index-1); + fixHandles(index); + } +#ifdef DEBUG_NL + qDebug() << "After adding: \n" << *this; +#endif + + validate(); + return add; +} + +uint NodeList_sV::deleteSelected() +{ + uint counter = 0; + for (int i = 0; i < m_list.size(); ) { + if (m_list.at(i).selected()) { + m_list.removeOne(m_list.at(i)); + if (m_list.size() > 0) { + m_segments.shrink(); + } + counter++; + } else { + i++; + } + } + validate(); + return counter; +} +void NodeList_sV::deleteNode(int index) +{ + Q_ASSERT(index >= 0); + Q_ASSERT(index < m_list.size()); + if (m_list.size() > 0) { + if (m_list.size() > 1) { + m_segments.shrink(); + } + m_list.removeAt(index); + } + if (index > m_list.size() && (index-1) >= 0) { + if (m_list.at(index-1).rightCurveType() != m_list.at(index).leftCurveType()) { + m_listindex-1.setRightCurveType(CurveType_Linear); + m_listindex.setLeftCurveType(CurveType_Linear); + } + } + validate(); +} + + +void NodeList_sV::select(const Node_sV *node, bool newSelection) +{ + if (newSelection) { + unselectAll(); + const_cast<Node_sV*>(node)->select(true); + } else { + const_cast<Node_sV*>(node)->select(!node->selected()); + } +} + +void NodeList_sV::unselectAll() +{ + for (int i = 0; i < m_list.size(); i++) { + m_listi.select(false); + } +} + + +bool NodeList_sV::validate() const +{ + bool valid = true; + qreal last = -m_minDist; + for (int i = 0; i < m_list.size() && valid; i++) { + valid = m_list.at(i).x() >= 0 + && m_list.at(i).y() >= 0 + && m_list.at(i).x() - last >= m_minDist + && m_list.at(i).y() <= m_maxY; + if (!valid) { + qDebug() << "Invalid node position for node " << i << " (" << m_list.size() << " total); Distance is " << m_list.at(i).x() - last; + qDebug() << "Positions: " << last << "/" << m_list.at(i).x(); + Q_ASSERT(false); + break; + } + last = m_list.at(i).x(); + } + if (valid) { + for (int i = 1; i < m_list.size(); i++) { + float space = (m_list.at(i).x() + m_list.at(i).leftNodeHandle().x()) + - (m_list.at(i-1).x() + m_list.at(i-1).rightNodeHandle().x()); + valid = space >= 0; + if (!valid) { + qDebug() << "Invalid handle position for nodes " << i-1 << " and " << i; + qDebug() << "Positions: " << m_list.at(i-1) << " with handle " << toString(m_list.at(i-1).rightNodeHandle()) + << ", " << m_list.at(i) << " with handle " << toString(m_list.at(i).leftNodeHandle()) + << ", space: " << space; + Q_ASSERT(false); + break; + } + } + } + if (valid) { + Q_ASSERT( (m_list.size() == 0 && m_segments.size() == 0) + || (m_list.size() > 0 && m_segments.size() == m_list.size()-1) ); + } + return valid; +} + + +////////// Moving + +void NodeList_sV::moveSelected(const Node_sV &time,bool snap) +{ + qreal maxRMove = 100000; + qreal maxLMove = -100000; + qreal maxUMove = 100000; + qreal maxDMove = -100000; + const Node_sV *left = NULL; + const Node_sV *right; + for (int i = 0; i < m_list.size(); i++) { + right = &m_list.at(i); + + /* + Get the maximum allowed horizontal movement distance here such that there is no + overlapping. For moving the selected nodes to the left, only unselected nodes + which are directly followed by a selected node need to be taken into account. + O----O + / \ x + -----x \ / + x-----------O + + min( ^1^, ^-----2-----^ ) + minDist + + */ + if (left != NULL) { + if (left->selected() && !right->selected()) { + // Move-right distance + maxRMove = qMin(maxRMove, + right->xUnmoved()+right->leftNodeHandle().x() - + (left->xUnmoved()+left->rightNodeHandle().x()) - + m_minDist); + } else if (!left->selected() && right->selected()) { + // Move-left distance + maxLMove = qMax(maxLMove, + left->xUnmoved()+left->rightNodeHandle().x() - + (right->xUnmoved()+right->leftNodeHandle().x()) + + m_minDist); + } + } + + if (right->selected()) { + maxDMove = qMax(maxDMove, -right->yUnmoved()); + maxUMove = qMin(maxUMove, m_maxY-right->yUnmoved()); + } + + left = right; + } + if (m_list.size() > 0 && m_list.at(0).selected()) { + // Do not allow to move nodes to x < 0 + maxLMove = qMax(maxLMove, -m_list.at(0).xUnmoved()); + } +#ifdef DEBUG_NL + qDebug() << "Max move: left " << maxLMove << ", right: " << maxRMove; +#endif + Node_sV newTime( + qMax(maxLMove, qMin(maxRMove, time.x())), + qMax(maxDMove, qMin(maxUMove, time.y())) + ); + for (int i = 0; i < m_list.size(); i++) { + if (m_list.at(i).selected()) { + m_listi.move(newTime); + } + } +} +void NodeList_sV::shift(qreal after, qreal by) +{ + int pos = nodeAfter(after); + if (pos >= 0) { + if (pos > 0) { + // ----o o------- <- nodes with handles + // <---> <- maximum distance + by = qMax(by, + m_list.at(pos-1).xUnmoved()+m_list.at(pos-1).rightNodeHandle().x() - + (m_list.at(pos).xUnmoved()+m_list.at(pos).leftNodeHandle().x()) + + m_minDist + ); + } + if (pos == 0) { + by = qMax(by, -m_list.at(pos).xUnmoved()); + } + for (; pos < m_list.size(); pos++) { + m_listpos.move(Node_sV(by, 0)); + } + } + if (!validate()) { + qDebug() << "Invalid node configuration! (This should not happen.)"; + } +} + +void NodeList_sV::confirmMove() +{ + for (int i = 0; i < m_list.size(); i++) { + m_listi.confirmMove(); + } + validate(); +} +void NodeList_sV::abortMove() +{ + for (int i = 0; i < m_list.size(); i++) { + if (m_list.at(i).selected()) { + m_listi.abortMove(); + } + } +} + +void NodeList_sV::moveHandle(const NodeHandle_sV *handle, Node_sV relPos) +{ + Node_sV otherNode; + Node_sV *currentNode = const_cast<Node_sV*>(handle->parentNode()); + + int nodeIndex = indexOf(handle->parentNode()); + Q_ASSERT(nodeIndex >= 0); + Q_ASSERT(nodeIndex < m_list.size()); + + if (handle == ¤tNode->leftNodeHandle()) { + // o------ + if (nodeIndex > 0) { + // Ensure that it does not overlap with the left node's handle (injectivity) + otherNode = m_list.at(nodeIndex-1); + qDebug() << "Left node: " << otherNode; + qDebug() << "Right node: " << currentNode; + qDebug() << "Before overlapping check: " << relPos; + relPos.setX(qMax(relPos.x(), -(currentNode->x() - otherNode.x() - otherNode.rightNodeHandle().x()))); + qDebug() << "After overlapping check: " << relPos; + qDebug() << "Space left: " << currentNode->x() + relPos.x() - (otherNode.x() + otherNode.rightNodeHandle().x()); + } + // Additionally the handle has to stay on the left of its node + relPos.setX(qMin(relPos.x(), .0)); + + currentNode->setLeftNodeHandle(relPos.x(), relPos.y()); + + } else { + // -------o + if (nodeIndex+1 < m_list.size()) { + otherNode = m_list.at(nodeIndex+1); + relPos.setX(qMin(relPos.x(), otherNode.x() - currentNode->x() + otherNode.leftNodeHandle().x())); + } + relPos.setX(qMax(relPos.x(), .0)); + + currentNode->setRightNodeHandle(relPos.x(), relPos.y()); + } + validate(); +} + + + + +////////// Curve + +void NodeList_sV::setCurveType(qreal segmentTime, CurveType type) +{ + int left, right; + findBySegment(segmentTime, left, right); +#ifdef DEBUG_NL + qDebug() << "Setting curve type for nodes " << left << " and " << right; +#endif + if (left != -1) { + m_listleft.setRightCurveType(type); + } + if (right != -1) { + m_listright.setLeftCurveType(type); + } +} +void NodeList_sV::fixHandles(int leftIndex) +{ + if (leftIndex >= 0 && (leftIndex+1) < m_list.size()) { + qreal right = m_list.at(leftIndex+1).x() - m_list.at(leftIndex).x(); + qreal leftHandle = m_list.at(leftIndex).rightNodeHandle().x(); + qreal rightHandle = m_list.at(leftIndex+1).leftNodeHandle().x(); + + if (leftHandle < 0) { leftHandle = 0; } + if (rightHandle > 0) { rightHandle = 0; } + + if (leftHandle > right+rightHandle && (leftHandle-rightHandle) > 0) { + qreal factor = right / (leftHandle - rightHandle); + qDebug() << "Factor: " << factor << ", left: " << leftHandle << ", right: " << rightHandle << ", distance: " << right; + leftHandle *= factor; + rightHandle *= factor; + qDebug() << "After scaling: left: " << leftHandle << ", right: " << rightHandle; + Q_ASSERT(leftHandle <= right+rightHandle); + } + m_listleftIndex.setRightNodeHandle(leftHandle, m_list.at(leftIndex).rightNodeHandle().y()); + m_listleftIndex+1.setLeftNodeHandle(rightHandle, m_list.at(leftIndex+1).leftNodeHandle().y()); + } +} + +/** + * on error return int indicating error type + * hint : maybe add error method ? + */ +int NodeList_sV::setSpeed(qreal segmentTime, qreal speed) +{ + int error = 0; + int left, right; + findBySegment(segmentTime, left, right); + if (left >= 0 && right >= 0) { + Node_sV *leftN = &m_listleft; + Node_sV *rightN = &m_listright; + qreal y = leftN->y() + speed*(rightN->x()-leftN->x()); + if (y > m_maxY || y < 0) { + if (y > m_maxY) { + qDebug() << speed << "x speed would shoot over maximum time. Correcting."; + error = -1; + y = m_maxY; + } else { + qDebug() << speed << "x speed goes below 0. Correcting."; + error = -2; + y = 0; + } + qreal xNew = leftN->x() + (y - leftN->y())/speed; + rightN->setY(y); + if (xNew - leftN->x() >= m_minDist) { + add(Node_sV(xNew, y)); + } else { + qDebug() << "New node would be too close, not adding it."; + error = -3; + } + } else { + rightN->setY(y); + } + } else { + qDebug() << "Outside segment."; + error = -4; + } + validate(); + return error; +} + + + + +////////// Access + +int NodeList_sV::indexOf(const Node_sV *node) const +{ + return m_list.indexOf(*node); +} + +int NodeList_sV::find(qreal time) const +{ + int pos; + for ( + pos = 0; + m_list.size() > (pos+1) && m_list.at(pos+1).x() <= time; + pos++ + ) {} + if (m_list.size() == 0 || (pos == 0 && time < m_list0.x())) { +#ifdef DEBUG_NL + if (m_list.size() > 0) { + std::cout.precision(30); + std::cout << "find(): time: " << time << ", left boundary: " << m_list0.x() + << ", unmoved: " << m_list0.xUnmoved() + << ", diff: " << m_listpos.x()-time << std::endl; + } +#endif + pos = -1; + } + return pos; +} +int NodeList_sV::find(QPointF pos, qreal tdelta) const +{ + for (int i = 0; i < m_list.size(); i++) { + if (std::pow(m_list.at(i).xUnmoved() - pos.x(), 2) + std::pow(m_list.at(i).yUnmoved()-pos.y(), 2) + < std::pow(tdelta, 2)) { + return i; + } + } + return -1; +} + +void NodeList_sV::findBySegment(qreal tx, int &leftIndex_out, int &rightIndex_out) const +{ + for (int i = 0; i < m_list.size(); i++) { + leftIndex_out = i-1; + rightIndex_out = i; + if (m_list.at(i).xUnmoved() > tx) { + break; + } + if (i == m_list.size()-1) { + leftIndex_out = i; + rightIndex_out = -1; + } + } +} + +QList<NodeList_sV::PointerWithDistance> NodeList_sV::objectsNear(QPointF pos, qreal tmaxdist) const +{ + qreal maxdist2 = std::pow(tmaxdist, 2); + + QList<PointerWithDistance> objects; + qreal dist; + for (int i = 0; i < m_list.size(); i++) { + + dist = dist2(m_list.at(i).toQPointF() - pos); + if (dist <= maxdist2) { + objects << PointerWithDistance(&m_listi, dist, PointerWithDistance::Node); + } + + if (m_list.at(i).leftCurveType() != CurveType_Linear) { + dist = dist2(m_list.at(i).toQPointF() + m_list.at(i).leftNodeHandle() - pos); + if (dist <= maxdist2) { + objects << PointerWithDistance(&m_listi.leftNodeHandle(), dist, PointerWithDistance::Handle); + } + } + if (m_list.at(i).rightCurveType() != CurveType_Linear) { + dist = dist2(m_list.at(i).toQPointF() + m_list.at(i).rightNodeHandle() - pos); + if (dist <= maxdist2) { + objects << PointerWithDistance(&m_listi.rightNodeHandle(), dist, PointerWithDistance::Handle); + } + } + if (i > 0) { + if (m_list.at(i-1).x() < pos.x() && m_list.at(i).x() > pos.x()) { + objects << PointerWithDistance(&m_segments.at(i-1), std::pow(sourceTime(pos.x()) - pos.y(), 2), PointerWithDistance::Segment); + } + } + } + + qSort(objects); + return objects; +} +qreal NodeList_sV::dist2(QPointF point) const +{ + return std::pow(point.x(), 2) + std::pow(point.y(), 2); +} + +int NodeList_sV::nodeAfter(qreal time) const +{ + int pos = 0; + while (m_list.size() > pos) { + if (m_list.at(pos).xUnmoved() >= time) { + break; + } + pos++; + } + if (pos >= m_list.size()) { + pos = -1; + } + Q_ASSERT(pos < 0 || m_list.at(pos).xUnmoved() >= time); + return pos; +} + +const Node_sV& NodeList_sV::at(int i) const { return m_list.at(i); } +Node_sV& NodeList_sV::operator(int i) { return m_listi; } +int NodeList_sV::size() const { return m_list.size(); } + +SegmentList_sV* NodeList_sV::segments() +{ + return &m_segments; +} + + + + + +////////// Debug + +QDebug operator<<(QDebug dbg, const NodeList_sV &list) +{ + for (int i = 0; i < list.size(); i++) { + dbg.nospace() << i << ": " << list.at(i) << " "; + } + return dbg.maybeSpace(); +} +
View file
slowmoVideo-0.6.tar.xz/src/project/nodeList_sV.h
Added
@@ -0,0 +1,170 @@ +/* +slowmoUI is a user interface for slowmoVideo. +Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +*/ + +#ifndef NODELIST_SV_H +#define NODELIST_SV_H + +#include "node_sV.h" +#include "segmentList_sV.h" +#include "canvasObject_sV.h" +#include "../lib/defs_sV.hpp" + +#include <QList> +#include <QtGlobal> + +/** + \brief Represents a curve defined by a Node_sV list. + + This object can be queried for the source time given an output time. + + The curve is (ensured to be) injective, i.e. + \f$ t_1 \neq t_2 \rightarrow f(t_1) \neq f(t_2) \f$ + with \f$ t_1,t_2 \in \f$ target time, \f$ f(t_1),f(t_2) \in \f$ source time. This means that + there is alwas a non-ambiguous answer to the question: + <em>Which frame from the input video has to be displayed at output time \f$ t \f$?</em> + */ +class NodeList_sV +{ +public: + NodeList_sV(float minDist = 1/30.0f); + + /// For sorting objects + struct PointerWithDistance { + + /// Defines the order on object types. Nodes will come first in a sorted list. + enum ObjectType { Node = 1, Handle = 2, Segment = 3, Tag = 4 }; + /// Pointer to the object + const CanvasObject_sV* ptr; + /// Distance to the object from the search position (e.g. mouse position) + qreal dist; + /// The object type should only be used for sorting! + ObjectType type; + + bool operator <(const PointerWithDistance &other) const { + return type < other.type || (type == other.type && dist < other.dist); + } + PointerWithDistance(const CanvasObject_sV* ptr, qreal dist, ObjectType type) : + ptr(ptr), + dist(dist), + type(type) + { } + }; + + + void setMaxY(qreal time); ///< Sets the maximum y value that is allowed, usually the duration of the input. + + qreal sourceTime(qreal targetTime) const; ///< Calculates the source time in seconds for the given output time. + qreal startTime(bool useMoved = false) const; ///< Time of the first node. useMoved uses the unconfirmed position of the node while it is moved. + qreal endTime(bool useMoved = false) const; ///< Time of the rightmost node. See totalTime() for the curve length. + qreal totalTime() const; ///< Length of the curve, ignores space (startTime())at the beginning. + bool isInsideCurve(qreal targetTime, bool useMoved = false) const; ///< Returns true if startTime <= targetTime <= endTime + + /** + Add a new node at the given position. + @return true if the node has been added. The node is NOT added + if it is too close to another node. + */ + bool add(Node_sV node); + uint deleteSelected(); + void deleteNode(int index); + + void select(const Node_sV *node, bool newSelection = true); + void unselectAll(); + + void shift(qreal after, qreal by); + /** + Move the selected nodes by the given time vector. + Only succeeds if the nodes are still within valid bounds. + A move has to be either confirmed or aborted. + */ + void moveSelected(const Node_sV &time,bool snap = false); + /** + Confirm the move on all nodes. + */ + void confirmMove(); + /** + Abort the move on all nodes. Resets the temporary movement vector. + */ + void abortMove(); + + void moveHandle(const NodeHandle_sV *handle, Node_sV relPos); + + /// Sets the curve type for the segment at time \c segmentTime. + void setCurveType(qreal segmentTime, CurveType type); + + void fixHandles(int leftIndex); + + int setSpeed(qreal segmentTime, qreal speed); + + + + /** + \brief Returns the \c node's index in the node list + \return -1 if the node could not be located + */ + int indexOf(const Node_sV *node) const; + /** + @return The position of the node whose target time (x()) is <= time, + or -1 if there is no such node. + */ + int find(qreal time) const; + + /** + @return The position of the first node in the list which is within a radius + of \c tdelta around the point <tt>(tx|ty)</tt>, or -1 if no such node exists. + */ + int find(QPointF pos, qreal tdelta) const; + /** + \brief Searches for a segment (or path) between two nodes at time \c tx. + + If a left or right node does not exist (when \c tx is outside of the curve), the return + value for this index is -1. + */ + void findBySegment(qreal tx, int& leftIndex_out, int& rightIndex_out) const; + /** + \brief Searches for node objects (nodes, handles, and segments) around a position. + \param pos Center of the search position. + \param tmaxdist This is the search radius. Elements are included if their euclidian distance + to \c pos is <= tmaxdist, except for segments where only the x position is taken into account. + */ + QList<PointerWithDistance> objectsNear(QPointF pos, qreal tmaxdist) const; + + /** + @return The index of the node whose time is equal or greater than + the given time, or -1 if there is no such node. + */ + int nodeAfter(qreal time) const; + + const Node_sV& at(int i) const; + Node_sV& operator (int i); + int size() const; + + /** + @return false if nodes are not in a valid position. + Nodes must be ordered, and the minimum distance (on the y axis) + must be at least m_minDist. + */ + bool validate() const; + + SegmentList_sV* segments(); + +private: + qreal m_maxY; + QList<Node_sV> m_list; + SegmentList_sV m_segments; + const float m_minDist; + + qreal bezierSourceTime(qreal targetTime, QPointF p0, QPointF p1, QPointF p2, QPointF p3) const; + inline qreal dist2(QPointF point) const; +}; + +QDebug operator<<(QDebug qd, const NodeList_sV &list); + +#endif // NODELIST_SV_H
View file
slowmoVideo-0.6.tar.xz/src/project/node_sV.cpp
Changed
(renamed from src/slowmoVideo/project/node_sV.cpp)
View file
slowmoVideo-0.6.tar.xz/src/project/node_sV.h
Changed
(renamed from src/slowmoVideo/project/node_sV.h)
View file
slowmoVideo-0.6.tar.xz/src/project/projectPreferences_sV.cpp
Added
@@ -0,0 +1,78 @@ +#include "projectPreferences_sV.h" +#include <QtCore/QDir> +#include <QDesktopServices> + +ProjectPreferences_sV::ProjectPreferences_sV() : + m_tagAxis(TagAxis_Source), + m_viewport_t0(0, 0), + m_viewport_secRes(50, 50), + m_canvas_xAxisFPS(24), + m_renderSectionMode("full"), + m_renderFrameSize(FrameSize_Orig), + m_renderInterpolationType(InterpolationType_TwowayNew), + m_motionblurType(MotionblurType_Convolving), + m_renderFPS(24), + m_imagesOutputDir(QDir::homePath()), + m_imagesFilenamePattern("rendered-%1.jpg"), + m_flowV3DLambda(20.0) +{ +#ifdef USE_QTKIT + m_videoFilename = (QStandardPaths::writableLocation(QStandardPaths::MoviesLocation)+"/rendered.mov"); +#else + m_videoFilename = (QStandardPaths::writableLocation(QStandardPaths::MoviesLocation)+"/rendered.mp4"); +#endif + +} + + +TagAxis& ProjectPreferences_sV::lastSelectedTagAxis() +{ + return m_tagAxis; +} + +QPointF& ProjectPreferences_sV::viewport_secRes() +{ + return m_viewport_secRes; +} +QPointF& ProjectPreferences_sV::viewport_t0() +{ + return m_viewport_t0; +} +Fps_sV& ProjectPreferences_sV::canvas_xAxisFPS() +{ + return m_canvas_xAxisFPS; +} + +FrameSize& ProjectPreferences_sV::renderFrameSize() +{ + return m_renderFrameSize; +} +InterpolationType& ProjectPreferences_sV::renderInterpolationType() +{ + return m_renderInterpolationType; +} +MotionblurType& ProjectPreferences_sV::renderMotionblurType() +{ + return m_motionblurType; +} + +QString& ProjectPreferences_sV::renderSectionMode() { return m_renderSectionMode; } +QString& ProjectPreferences_sV::renderStartTag() { return m_renderStartTag; } +QString& ProjectPreferences_sV::renderEndTag() { return m_renderEndTag; } +QString& ProjectPreferences_sV::renderStartTime() { return m_renderStartTime; } +QString& ProjectPreferences_sV::renderEndTime() { return m_renderEndTime; } + +Fps_sV& ProjectPreferences_sV::renderFPS() { return m_renderFPS; } +QString& ProjectPreferences_sV::renderTarget() { return m_renderTarget; } + +QString& ProjectPreferences_sV::imagesOutputDir() { return m_imagesOutputDir; } +QString& ProjectPreferences_sV::imagesFilenamePattern() { return m_imagesFilenamePattern; } + +QString& ProjectPreferences_sV::videoFilename() { +qDebug() << "filename is : " << m_videoFilename; +return m_videoFilename; } +QString& ProjectPreferences_sV::videoCodec() { return m_vcodec; } + +float& ProjectPreferences_sV::flowV3DLambda() { return m_flowV3DLambda; } + +bool& ProjectPreferences_sV::renderFormat() { return m_renderFormat;}
View file
slowmoVideo-0.6.tar.xz/src/project/projectPreferences_sV.h
Added
@@ -0,0 +1,68 @@ +#ifndef PROJECTPREFERENCES_SV_H +#define PROJECTPREFERENCES_SV_H + +#include "../lib/defs_sV.hpp" +class ProjectPreferences_sV +{ +public: + ProjectPreferences_sV(); + + /** + \return Reference to the previously selected tag axis + */ + TagAxis& lastSelectedTagAxis(); + QPointF& viewport_t0(); + QPointF& viewport_secRes(); + + Fps_sV& canvas_xAxisFPS(); + + // Rendering + QString& renderSectionMode(); + QString& renderStartTag(); + QString& renderEndTag(); + QString& renderStartTime(); + QString& renderEndTime(); + FrameSize& renderFrameSize(); + InterpolationType& renderInterpolationType(); + MotionblurType& renderMotionblurType(); + Fps_sV& renderFPS(); + QString& renderTarget(); + bool& renderFormat(); + QString& imagesOutputDir(); + QString& imagesFilenamePattern(); + QString& videoFilename(); + QString& videoCodec(); + + float& flowV3DLambda(); + + +private: + TagAxis m_tagAxis; + QPointF m_viewport_t0; + QPointF m_viewport_secRes; + + Fps_sV m_canvas_xAxisFPS; + + QString m_renderSectionMode; + QString m_renderStartTag; + QString m_renderEndTag; + QString m_renderStartTime; + QString m_renderEndTime; + FrameSize m_renderFrameSize; + InterpolationType m_renderInterpolationType; + MotionblurType m_motionblurType; + Fps_sV m_renderFPS; + QString m_renderTarget; + bool m_renderFormat; + + QString m_imagesOutputDir; + QString m_imagesFilenamePattern; + QString m_videoFilename; + QString m_vcodec; + + float m_flowV3DLambda; + + +}; + +#endif // PROJECTPREFERENCES_SV_H
View file
slowmoVideo-0.6.tar.xz/src/project/project_sV.cpp
Added
@@ -0,0 +1,511 @@ +/* +This file is part of slowmoVideo. +Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +*/ + +#include "project_sV.h" +#include "projectPreferences_sV.h" +#include "emptyFrameSource_sV.h" +#include "flowSourceV3D_sV.h" +#include "flowSourceOpenCV_sV.h" +#include "interpolator_sV.h" +#include "motionBlur_sV.h" +#include "nodeList_sV.h" +#include "renderTask_sV.h" +#include "shutterFunction_sV.h" +#include "shutterFunctionList_sV.h" +#include "../lib/shutter_sV.h" +#include "../lib/interpolate_sV.h" +#include "flowRW_sV.h" +#include "flowField_sV.h" + +#if 1 +#include "work_flow.h" +#endif + +#include <cmath> + +#include <QFile> +#include <QSettings> +#include <QThread> + +#include <QTemporaryDir> + +//#define DEBUG_P +#ifdef DEBUG_P +#include <iostream> +#endif + + +#define MIN_FRAME_DIST .001 + +Project_sV::Project_sV() +{ + +//TODO: scoping problem + m_projDir = getDirectoryName(); + + init(); + + int tid; + for(tid=0;tid<4;tid++) { + workertid=0; + threadtid=0; + } +} + +Project_sV::Project_sV(QString projectDir) : m_projDir(projectDir) +{ + init(); +} + +QDir Project_sV::getDirectoryName() +{ + QDir dirName; + + QTemporaryDir tempDir; // use default + if (tempDir.isValid()) + dirName = QDir(tempDir.path()); + else + dirName = QDir::temp(); + + return dirName; +} + +void Project_sV::init() +{ + m_preferences = new ProjectPreferences_sV(); + m_frameSource = new EmptyFrameSource_sV(this); + m_flowSource = 0; // leak ? new FlowSourceV3D_sV(this); + m_motionBlur = new MotionBlur_sV(this); + reloadFlowSource(); + m_tags = new QList<Tag_sV>(); + m_nodes = new NodeList_sV(); + m_shutterFunctions = new ShutterFunctionList_sV(m_nodes); + m_renderTask = nullptr; + + m_v3dFailCounter = 0; + + /* better here ? */ + int tid; + for(tid=0;tid<4;tid++) { + workertid=0; + threadtid=0; + } +} + +Project_sV::~Project_sV() +{ + int tid; + for(tid=0;tid<4;tid++) { + if (workertid!=0) { + workertid->abort(); + threadtid->wait(); + + //qDebug()<<"Deleting thread and worker in Thread "<<this->QObject::thread()->currentThreadId(); + + delete workertid; + delete threadtid; + } + } + + delete m_renderTask; + delete m_preferences; + delete m_frameSource; + delete m_flowSource; + delete m_motionBlur; + delete m_tags; + delete m_nodes; + delete m_shutterFunctions; +} + +void Project_sV::reloadFlowSource() +{ + if (m_flowSource != 0) + delete m_flowSource; + + QSettings m_settings; + QString method = m_settings.value("preferences/flowMethod", "OpenCV-CPU").toString(); + if ("V3D" == method) { + m_flowSource = new FlowSourceV3D_sV(this); + } else { + int algo = m_settings.value("preferences/preferredOpenCVAlgo", 0).toInt(); + int dev_index = m_settings.value("preferences/oclDriver", -1).toInt(); + if (method == "OpenCV-CPU") { + dev_index = -1; + } + m_flowSource = new FlowSourceOpenCV_sV(this, algo, dev_index); + } +} + +void Project_sV::setupProjectDir() +{ + //qDebug() << "Project directory: " << m_projDir.absolutePath(); + + m_frameSource->slotUpdateProjectDir(); + m_flowSource->slotUpdateProjectDir(); + m_motionBlur->slotUpdateProjectDir(); +} + +void Project_sV::setProjectDir(QString projectDir) +{ + m_projDir = projectDir; + // Create directory if necessary + qDebug() << "Project directory: " << m_projDir.absolutePath(); + if (!m_projDir.exists()) { + m_projDir.mkpath("."); + } + + setupProjectDir(); +} + +void Project_sV::setProjectFilename(QString filename) +{ + m_projectFilename = filename; +} + +QString Project_sV::projectFilename() const { + return m_projectFilename; +} + +void Project_sV::loadFrameSource(AbstractFrameSource_sV *frameSource) +{ + if (m_frameSource != nullptr) { + delete m_frameSource; + } + if (frameSource == nullptr) { + m_frameSource = new EmptyFrameSource_sV(this); + } else { + m_frameSource = frameSource; + } + m_nodes->setMaxY(m_frameSource->maxTime()); +} + + +//TODO: remove this +void Project_sV::replaceRenderTask(RenderTask_sV *task) +{ + /* + if (m_renderTask != nullptr) { + m_renderTask->slotStopRendering(); + m_renderTask->deleteLater(); + m_renderTask = nullptr; + } + */ + m_renderTask = task; +} + + +const QDir Project_sV::getDirectory(const QString &name, bool createIfNotExists) const +{ + QDir dir(m_projDir.absolutePath() + "/" + name); + if (createIfNotExists && !dir.exists()) { + dir.mkpath("."); + } + return dir; +} + +QImage Project_sV::render(qreal outTime, RenderPreferences_sV prefs) +{ + if (outTime < m_nodes->startTime() || outTime > m_nodes->endTime()) { +#ifdef DEBUG_P + std::cout.precision(30); + std::cout << m_nodes->startTime() << " -- " << outTime << " -- " << m_nodes->endTime() << std::endl; + std::cout.flush(); +#endif + qDebug() << "Output time out of bounds"; + Q_ASSERT(false); + } + + float sourceTime = m_nodes->sourceTime(outTime); + if (sourceTime < 0) { + sourceTime = 0; + } + if (sourceTime > m_frameSource->maxTime()) { + sourceTime = m_frameSource->maxTime(); + } + + float sourceFrame = sourceTimeToFrame(sourceTime); + + int leftIndex = m_nodes->find(outTime); + if (leftIndex < 0) { + qDebug() << "left node is not here!"; + Q_ASSERT(false); + } + if (leftIndex == m_nodes->size()-1) { + // outTime is at the very end of the node. + // Take next to last node to still have a right node. + leftIndex--; + } + + const Node_sV *leftNode = &(*m_nodes)leftIndex; + const Node_sV *rightNode = &(*m_nodes)leftIndex+1; + + ShutterFunction_sV *shutterFunction = m_shutterFunctions->function(leftNode->shutterFunctionID()); + + if (shutterFunction != nullptr) { + float dy; + if (outTime+1/prefs.fps().fps() <= m_nodes->endTime()) { + dy = m_nodes->sourceTime(outTime+1/prefs.fps().fps()) - sourceTime; + } else { + dy = sourceTime - m_nodes->sourceTime(outTime-1/prefs.fps().fps()); + } + float replaySpeed = fabs(dy)*prefs.fps().fps(); + float shutter = shutterFunction->evaluate( + (outTime-leftNode->x())/(rightNode->x()-leftNode->x()), // x on 0,1 + outTime, // t + prefs.fps().fps(), // FPS + sourceFrame, // y + dy // dy to next frame + ); + qDebug() << "Shutter value for output time " << outTime << " is " << shutter; + if (shutter > 0) { + try { + return m_motionBlur->blur(sourceFrame, sourceFrame+shutter*prefs.fps().fps(), + replaySpeed, + prefs); + } catch (RangeTooSmallError_sV &err) {} + } + } + return Interpolator_sV::interpolate(this, sourceFrame, prefs); +} + +FlowField_sV* Project_sV::requestFlow(int leftFrame, int rightFrame, const FrameSize frameSize) noexcept(false) +{ + Q_ASSERT(leftFrame < m_frameSource->framesCount()); + Q_ASSERT(rightFrame < m_frameSource->framesCount()); + if (dynamic_cast<EmptyFrameSource_sV*>(m_frameSource) == nullptr) { + + FlowSourceV3D_sV *v3d; + if ((v3d = dynamic_cast<FlowSourceV3D_sV*>(m_flowSource)) != nullptr) { + v3d->setLambda(m_preferences->flowV3DLambda()); + try { + return m_flowSource->buildFlow(leftFrame, rightFrame, frameSize); + } catch (FlowBuildingError) { + m_v3dFailCounter++; + qDebug() << "Failed creating optical flow, falling back to OpenCV ..."; + qDebug() << "Failed attempts so far: " << m_v3dFailCounter; + delete m_flowSource; + QSettings m_settings; + int algo = m_settings.value("preferences/preferredOpenCVAlgo", 0).toInt(); + int dev_index = m_settings.value("preferences/oclDriver", -1).toInt(); + QString method = m_settings.value("preferences/flowMethod", "OpenCV-CPU").toString(); + if (method == "OpenCV-CPU") { + dev_index = -1; + } + m_flowSource = new FlowSourceOpenCV_sV(this, algo, dev_index); + return m_flowSource->buildFlow(leftFrame, rightFrame, frameSize); + } + } + return m_flowSource->buildFlow(leftFrame, rightFrame, frameSize); + } else { + throw FlowBuildingError(tr("Empty frame source; Cannot build flow.")); + } +} + +inline +qreal Project_sV::sourceTimeToFrame(qreal time) const +{ + Q_ASSERT(time >= 0); + return time * m_frameSource->fps()->fps(); +} + +qreal Project_sV::snapToFrame(const qreal time, bool roundUp, const Fps_sV &fps, int *out_framesBeforeHere) +{ + Q_ASSERT(time >= 0); + int frameCount = 0; + double snapTime = 0; + double frameLength; + frameLength = 1.0/fps.fps(); + + while (snapTime < time) { + snapTime += frameLength; + frameCount++; + } + + // snapTime is now >= time + + if (!roundUp && snapTime != time) { + snapTime -= frameLength; + frameCount--; + } + + if (out_framesBeforeHere != nullptr) { + *out_framesBeforeHere = frameCount; + } + + return snapTime; +} +qreal Project_sV::snapToOutFrame(qreal time, bool roundUp, const Fps_sV &fps, int *out_framesBeforeHere) const +{ + if (time > m_nodes->endTime()) { + time = m_nodes->endTime(); + } + time -= m_nodes->startTime(); + if (time < 0) { time = 0; } + float snapped = snapToFrame(time, roundUp, fps, out_framesBeforeHere) + m_nodes->startTime(); + return snapped; +} +qreal Project_sV::toOutTime(QString timeExpression, const Fps_sV &fps) const noexcept(false) +{ + if (m_nodes->size() < 2) { + throw Error_sV(tr("Not enough nodes available in the project.")); + } + + // t:time l:label f:frame p:percent :start :end time + bool ok = false; + qreal time = 0; + if (timeExpression.startsWith("t:")) { + time = timeExpression.mid(2).toDouble(&ok); + if (!ok) { + throw Error_sV(tr("%1 is not a valid time. Format: t:123.45").arg(timeExpression)); + } + } else if (timeExpression.startsWith("l:")) { + QString label = timeExpression.mid(2); + bool inputAxisFound = false; + for (int i = 0; i < m_tags->size(); i++) { + if (m_tags->at(i).description() == label) { + if (m_tags->at(i).axis() == TagAxis_Output) { + time = m_tags->at(i).time(); + ok = true; + break; + } else { + inputAxisFound = true; + } + } + } + if (!ok) { + if (inputAxisFound) { + throw Error_sV(tr("%1 is an input label and not an output label and cannot be used for rendering.").arg(label)); + } else { + throw Error_sV(tr("No label found for %1").arg(timeExpression)); + } + } + } else if (timeExpression.startsWith("f:")) { + int frame = timeExpression.mid(2).toInt(&ok); + if (ok) { + time = frame / fps.fps(); + } else { + throw Error_sV(tr("%1 is not a valid frame number. Format: f:1234").arg(timeExpression)); + } + } else if (timeExpression.startsWith("p:")) { + QString sPercent = timeExpression.mid(2).trimmed(); + if (sPercent.endsWith("%")) { + sPercent.chop(1); + } + float percent = sPercent.toFloat(&ok); + if (ok) { + if (percent >= 0 && percent <= 100) { + time = m_nodes->startTime() + m_nodes->totalTime()*percent/100; + } else { + throw Error_sV(tr("%1 is not a valid percentage number; must be between 0 and 100.").arg(percent)); + } + } else { + throw Error_sV(tr("%1 is not a valid percentage expression. Format: p:0% until p:100.0%").arg(timeExpression)); + } + } else if (timeExpression.startsWith(":")) { + if (":start" == timeExpression) { + time = m_nodes->startTime(); + } else if (":end" == timeExpression) { + time = m_nodes->endTime(); + } else { + throw Error_sV(tr("%1 is not a valid position. Valid: :start and :end").arg(timeExpression)); + } + } else { + time = timeExpression.toDouble(&ok); + if (!ok) { + throw Error_sV(tr("Not a valid time format. Options: t:1.25 or 1.25 (time), f:1234 (frame), " + "l:slowdown (label), p:42.42% (percentage), :start and :end (project start/end).")); + } + } + + time = qMax(time, m_nodes->startTime()); + time = qMin(time, m_nodes->endTime()); + + return time; +} + +QList<NodeList_sV::PointerWithDistance> Project_sV::objectsNear(QPointF pos, qreal tmaxdist) const +{ + QList<NodeList_sV::PointerWithDistance> list = m_nodes->objectsNear(pos, tmaxdist); + + qreal dist; + for (int i = 0; i < m_tags->size(); i++) { + if (m_tags->at(i).axis() == TagAxis_Source) { + dist = fabs(pos.y() - m_tags->at(i).time()); + } else { + dist = fabs(pos.x() - m_tags->at(i).time()); + } + if (dist <= tmaxdist) { + list << NodeList_sV::PointerWithDistance(&m_tags->at(i), dist, NodeList_sV::PointerWithDistance::Tag); + } + } + + qSort(list); + + return list; +} + +/** + * start an optical flow on a thread + * + * @param threadid the thread on which to run our flow + * @param frameSize size of frame for calcul (small/orig) + * @param direction flow direction + */ +void Project_sV::startFlow(int threadid,const FrameSize frameSize,int direction) +{ + threadthreadid = new QThread(); + workerthreadid = new WorkerFlow(); + + // set on what to work ... + workerthreadid->setFrameSize(frameSize); + workerthreadid->setProject(this); + workerthreadid->setDirection(direction); + workerthreadid->setFlowSource(flowSource()); + + workerthreadid->moveToThread(threadthreadid); + //connect(worker, SIGNAL(valueChanged(QString)), ui->label, SLOT(setText(QString))); + connect(workerthreadid, SIGNAL(workFlowRequested()), threadthreadid, SLOT(start())); + connect(threadthreadid, SIGNAL(started()), workerthreadid, SLOT(doWorkFlow())); + connect(workerthreadid, SIGNAL(finished()), threadthreadid, SLOT(quit()), Qt::DirectConnection); + + // let's start + threadthreadid->wait(); // If the thread is not running, this will immediately return. + + workerthreadid->requestWork(); +} + +/** + * prebuild the optical flow using threading + */ +void Project_sV::buildCacheFlowSource() +{ + + QSettings settings; + bool precalc = settings.value("preferences/precalcFlow", true).toBool(); + if (precalc && (m_flowSource != nullptr)) { +#if 0 + qDebug() << "Creating cached FlowSources "; + Q_ASSERT(m_flowSource != nullptr); + // TODO: test/check better place ? + // we should do it for each size/each way + // use threading here + + startFlow(0,FrameSize_Small,0); + startFlow(1,FrameSize_Small,1); + startFlow(2,FrameSize_Orig,0); + startFlow(3,FrameSize_Orig,1); +#else + qDebug() << "cache flow source disable"; +#endif + + } + +} +
View file
slowmoVideo-0.6.tar.xz/src/project/project_sV.h
Added
@@ -0,0 +1,172 @@ +/* +This file is part of slowmoVideo. +Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +*/ + +#ifndef PROJECT_SV_H +#define PROJECT_SV_H + +#include "tag_sV.h" +#include "nodeList_sV.h" +#include "renderPreferences_sV.h" +#include "../lib/defs_sV.hpp" +#include "../lib/videoInfo_sV.h" + + +#include <QtCore/QObject> +#include <QtCore/QFile> +#include <QtCore/QDir> +#include <QtGui/QImage> +#include <QThread> + +class ProjectPreferences_sV; +class Flow_sV; +class AbstractFrameSource_sV; +class AbstractFlowSource_sV; +class MotionBlur_sV; +class ShutterFunctionList_sV; +class RenderTask_sV; +class FlowField_sV; +class QSignalMapper; +class QProcess; +class QRegExp; +class QTimer; +class WorkerFlow; + +/** + \brief slowmoVideo project holding all important information. + \todo Check if width%4 == 0 for V3D + */ +class Project_sV : public QObject +{ + Q_OBJECT + +public: + /** Creates an empty project. A video file can be loaded with loadFile(QString, QString). */ + Project_sV(); + /** + Creates a new project. + \param filename Input video file + \param projectDir Project directory; All cached files will be put in there. + */ + Project_sV(QString projectDir); + ~Project_sV(); + + ProjectPreferences_sV* preferences() { return m_preferences; } + + void setProjectDir(QString projectDir); + void setupProjectDir(); // TODO: + QDir getProjectDir() { return m_projDir; }; + /** The project filename should be set when saving or loading the project. */ + void setProjectFilename(QString filename); + /** \return The filename this project was last saved as. */ + QString projectFilename() const; + + /** \param frameSource will be managed (deleted) by the project. If \c NULL, an empty frame source will be used. */ + void loadFrameSource(AbstractFrameSource_sV *frameSource); + + AbstractFrameSource_sV* frameSource() { return m_frameSource; } + AbstractFlowSource_sV* flowSource() { return m_flowSource; } + NodeList_sV *nodes() const { return m_nodes; } + QList<Tag_sV> *tags() const { return m_tags; } + ShutterFunctionList_sV* shutterFunctions() { return m_shutterFunctions; } + MotionBlur_sV *motionBlur() { return m_motionBlur; } + + /** \see replaceRenderTask() */ + RenderTask_sV *renderTask() { return m_renderTask; } + void replaceRenderTask(RenderTask_sV *task); + + + /** + \fn snapToFrame() + \brief Snaps in the given time on a grid given by the number of frames per second. + This allows to, for example, render from 0 to 3.2 seconds and then from 3.2 to 5 seconds + to images with the same effect as rendering all at once. Always starts from 0! + \param time Time to snap in + \param roundUp To chose between rounding up or down + \param fps Frames per second to use. + */ + /** + \fn toOutTime() + \brief Converts a time expression like \c f:123 or \c :start to an output time \c float. + + Accepted input format: + \li \c 24.3 or \c t:24.3 for 24.3 seconds + \li \c f:123 for frame 123 + \li \c p:25% for 25 % + \li \c l:slowdown for the slowdown label (tag) + \li \c :start and \c :end for project start/end + */ + static qreal snapToFrame(const qreal time, bool roundUp, const Fps_sV& fps, int* out_framesBeforeHere); + qreal snapToOutFrame(qreal time, bool roundUp, const Fps_sV& fps, int* out_framesBeforeHere) const; + qreal toOutTime(QString timeExpression, const Fps_sV& fps) const noexcept(false); + + + const QDir getDirectory(const QString &name, bool createIfNotExists = true) const; + + QImage render(qreal outTime, RenderPreferences_sV prefs); + + FlowField_sV* requestFlow(int leftFrame, int rightFrame, const FrameSize frameSize) noexcept(false); + + /** + \brief Searches for objects near the given \c pos. + This search includes tags. + \see NodeList_sV::objectsNear() Used by this method. Does not include tags. + */ + QList<NodeList_sV::PointerWithDistance> objectsNear(QPointF pos, qreal tmaxdist) const; + + +public: + /// Reload the flow source in case the user changed the default (preferred) method. + void reloadFlowSource(); + + // prebuilt the need optical flow files + void buildCacheFlowSource(); + + +private: + QDir m_projDir; + QString m_projectFilename; + + ProjectPreferences_sV *m_preferences; + + AbstractFrameSource_sV *m_frameSource; + AbstractFlowSource_sV *m_flowSource; + MotionBlur_sV *m_motionBlur; + + NodeList_sV *m_nodes; + QList<Tag_sV> *m_tags; + //TODO: remove this + RenderTask_sV *m_renderTask; + ShutterFunctionList_sV *m_shutterFunctions; + + qreal sourceTimeToFrame(qreal time) const; + + QDir getDirectoryName(); + void init(); + + /** + * @brief Thread object which will let us manipulate the running thread + */ + QThread *thread4; + /** + * @brief Object which contains methods that should be runned in another thread + */ + WorkerFlow *worker4; + + +private: + /// Count how many times V3D failed, after a certain limit we assume the user does not have an nVidia card + /// and constantly switch to OpenCV + int m_v3dFailCounter; + + // launch a worker thread for optical flow + void startFlow(int threadid,const FrameSize frameSize,int direction); +}; + +#endif // PROJECT_SV_H
View file
slowmoVideo-0.6.tar.xz/src/project/renderPreferences_sV.cpp
Changed
(renamed from src/slowmoVideo/project/renderPreferences_sV.cpp)
View file
slowmoVideo-0.6.tar.xz/src/project/renderPreferences_sV.h
Changed
(renamed from src/slowmoVideo/project/renderPreferences_sV.h)
View file
slowmoVideo-0.6.tar.xz/src/project/renderTask_sV.cpp
Added
@@ -0,0 +1,269 @@ +/* + * 2014 Valery Brasseur <vbrasseur@gmail.com> + */ + +#include "renderTask_sV.h" +#include "abstractRenderTarget_sV.h" +#include "emptyFrameSource_sV.h" + +#include <QCoreApplication> +#include <QImage> +#include <QMetaObject> +#include <QTimer> +#include <QEventLoop> + +#include <QThread> +#include <QDebug> +#include "project_sV.h" +#include "nodeList_sV.h" +#include "../lib/defs_sV.hpp" + +RenderTask_sV::RenderTask_sV(Project_sV *project) : +//m_project(project), +m_renderTarget(NULL), +m_renderTimeElapsed(0), +m_stopRendering(false), +m_prevTime(-1) +{ + //m_project->setupProjectDir(); + m_project = project; + + + m_timeStart = m_project->nodes()->startTime(); + m_timeEnd = m_project->nodes()->endTime(); + + m_nextFrameTime = m_project->nodes()->startTime(); + + _working =false; + +} + +//TODO: +RenderTask_sV::~RenderTask_sV() +{ + if (m_renderTarget != NULL) { delete m_renderTarget; } +} + +/** + * let run the thread ! + */ +void RenderTask_sV::requestWork() +{ + mutex.lock(); + _working = true; + m_stopRendering = false; + qDebug()<<"rendering worker start in Thread "<<thread()->currentThreadId(); + mutex.unlock(); + + //emit workFlowRequested(); + + qDebug() << "workflow request"; +} + +/** + * stop the running thread + */ +void RenderTask_sV::slotStopRendering() +{ + //qDebug()<<"abort rendering required in Thread "<<thread()->currentThreadId(); + mutex.lock(); + if (_working) { + m_stopRendering = true; + qDebug()<<"rendering aborting in Thread "<<thread()->currentThreadId(); + } + mutex.unlock(); +} + +#pragma mark - +#pragma mark progress dialog + +/** + * setup the progress dialog + */ +void RenderTask_sV::setupProgress(QString desc, int taskSize) +{ + //qDebug() << "setup progress call " << desc << " size " << taskSize; + emit signalNewTask(desc,taskSize); +} + +/** + * update progress dialog from outside + */ +void RenderTask_sV::updateProgress(int value) +{ + //qDebug() << "updateProgress call " << value; + currentProgress = value; + emit signalTaskProgress(value ); +} + +void RenderTask_sV::stepProgress(int step) +{ + //qDebug() << "stepProgress call " << step; + currentProgress+=step; + emit signalTaskProgress(currentProgress ); +} + +void RenderTask_sV::updateMessage(QString desc) +{ + emit signalItemDesc(desc); +} + +#pragma mark - +#pragma mark set/get task + +void RenderTask_sV::setRenderTarget(AbstractRenderTarget_sV *renderTarget) +{ + Q_ASSERT(renderTarget != NULL); + + if (m_renderTarget != NULL && m_renderTarget != renderTarget) { + delete m_renderTarget; + } + m_renderTarget = renderTarget; +} + +void RenderTask_sV::setTimeRange(qreal start, qreal end) +{ + Q_ASSERT(start <= end); + Q_ASSERT(start >= m_project->nodes()->startTime()); + Q_ASSERT(end <= m_project->nodes()->endTime()); + + m_timeStart = start; + m_timeEnd = end; +} + +void RenderTask_sV::setTimeRange(QString start, QString end) +{ + Q_ASSERT(m_prefs.fpsSetByUser()); + m_timeStart = m_project->toOutTime(start, m_prefs.fps()); + m_timeEnd = m_project->toOutTime(end, m_prefs.fps()); + Q_ASSERT(m_timeStart < m_timeEnd); +} + +QSize RenderTask_sV::resolution() +{ + return const_cast<Project_sV*>(m_project)->frameSource()->frameAt(0, m_prefs.size).size(); +} + +/* + * return a suitable dir for rendered frame + */ +QDir RenderTask_sV::getRenderDirectory() { + //bug using : return m_project->getDirectory("cache/rendered"); + QDir dir(m_project->getProjectDir().absolutePath() + "/" + "rendered"); + if (!dir.exists()) { + dir.mkpath("."); + } + return dir; + +} + +#pragma mark - +#pragma mark rendering + +/** + * this is the real workhorse. + * maybe we should not call this directly, but instead from doWork ? + */ +void RenderTask_sV::slotContinueRendering() +{ + qDebug()<<"Starting rendering process in Thread "<<thread()->currentThreadId(); + + /* real workhorse, need to account for exporting */ + setupProgress(trUtf8("Rendering Slow-Mo …"), 2* int(m_prefs.fps().fps() * (m_timeEnd-m_timeStart))); + + //TODO: initialize + m_stopwatch.start(); + + m_nextFrameTime=m_timeStart; + + int framesBefore; + qreal snapped = m_project->snapToOutFrame(m_nextFrameTime, false, m_prefs.fps(), &framesBefore); + qDebug() << "Frame snapping in from " << m_nextFrameTime << " to " << snapped; + m_nextFrameTime = snapped; + + Q_ASSERT(int((m_nextFrameTime - m_project->nodes()->startTime()) * m_prefs.fps().fps() + .5) == framesBefore); + + try { + m_renderTarget->openRenderTarget(); + } catch (Error_sV &err) { + m_stopRendering = true; + emit signalRenderingAborted(tr("Rendering aborted.") + " " + err.message()); + return; + } + + // render loop + // TODO: add more threading here + while(m_nextFrameTime<m_timeEnd) { + QCoreApplication::processEvents(); + + // Checks if the process should be aborted + mutex.lock(); + bool abort = m_stopRendering; + mutex.unlock(); + + if (abort) { + // user stop the process + qDebug()<<"Aborting Rendering process in Thread "<<thread()->currentThreadId(); + m_renderTimeElapsed = m_stopwatch.elapsed(); + emit signalRenderingStopped(QTime().addMSecs(m_renderTimeElapsed).toString("hh:mm:ss")); + qDebug() << "Rendering stopped after " << QTime().addMSecs(m_renderTimeElapsed).toString("hh:mm:ss"); + break; + } + + // do the work + int outputFrame = (m_nextFrameTime - m_project->nodes()->startTime()) * m_prefs.fps().fps() + .5; + qreal srcTime = m_project->nodes()->sourceTime(m_nextFrameTime); + + qDebug() << "Rendering frame number " << outputFrame << " @" << m_nextFrameTime << " from source time " << srcTime; + updateMessage(tr("Rendering frame %1 @ %2 s from input position: %3 s (frame %4)") + .arg( QString::number(outputFrame),QString::number(m_nextFrameTime), + QString::number(srcTime), + QString::number(srcTime*m_project->frameSource()->fps()->fps()) + ) ); + + try { + QImage rendered = m_project->render(m_nextFrameTime, m_prefs); + + m_renderTarget->slotConsumeFrame(rendered, outputFrame); + m_nextFrameTime = m_nextFrameTime + 1/m_prefs.fps().fps(); + + updateProgress( (m_nextFrameTime-m_timeStart) * m_prefs.fps().fps() ); + + } catch (FlowBuildingError &err) { + m_stopRendering = true; + emit signalRenderingAborted(err.message()); + } catch (InterpolationError &err) { + updateMessage(err.message()); + } + + + } /* while */ + + + // Checks if the process should be aborted + mutex.lock(); + bool abort = m_stopRendering; + mutex.unlock(); + + if (abort) { + qDebug() << "Rendering : aborting"; + updateMessage(tr("Rendering : aborting")); + } else { + //TODO: closing rendering project + qDebug() << "Rendering : exporting"; + updateMessage(tr("Rendering : exporting")); + m_renderTarget->closeRenderTarget(); + } + + m_renderTimeElapsed = m_stopwatch.elapsed(); + qDebug() << "time : " << m_renderTimeElapsed; + emit signalRenderingFinished(QTime(0,0).addMSecs(m_renderTimeElapsed).toString("hh:mm:ss")); + qDebug() << "Rendering stopped after " << QTime(0,0).addMSecs(m_renderTimeElapsed).toString("hh:mm:ss"); + + qDebug()<<"Rendering process finished in Thread "<<thread()->currentThreadId(); + + // Set _working to false, meaning the process can't be aborted anymore. + mutex.lock(); + _working = false; + mutex.unlock(); +}
View file
slowmoVideo-0.6.tar.xz/src/project/renderTask_sV.h
Added
@@ -0,0 +1,120 @@ +/* +* 2014 Valery Brasseur <vbrasseur@gmail.com> +*/ + +#ifndef RENDERTASK_SV_H +#define RENDERTASK_SV_H + +#include <QtCore/QObject> +#include <QtCore/QDir> +#include <QtCore/QTime> +#include <QtCore/QElapsedTimer> + +#include "renderPreferences_sV.h" + +class Project_sV; +class AbstractRenderTarget_sV; + + + +#include <QObject> +#include <QMutex> + +class RenderTask_sV : public QObject +{ + Q_OBJECT + +public: + RenderTask_sV(Project_sV *project); + ~RenderTask_sV(); + + /** + * Requests the process to start + * + * It is thread safe as it uses #mutex to protect access to #_working variable. + */ + void requestWork(); + /** + * Requests the process to abort + * + * It is thread safe as it uses #mutex to protect access to #_abort variable. + */ + void abort(); + + void setRenderTarget(AbstractRenderTarget_sV *renderTarget); + void setTimeRange(qreal start, qreal end); + void setTimeRange(QString start, QString end); + + QDir getRenderDirectory(); + + /// Rendered frames per second + Fps_sV fps() { return m_prefs.fps(); } + /// Output frame resolution + QSize resolution(); + + RenderPreferences_sV& renderPreferences() { return m_prefs; } + + void setupProgress(QString desc, int taskSize); + void updateProgress(int value); + void stepProgress(int step=1); + void updateMessage(QString desc); + +private: + /** + * true when Worker is doing work + */ + bool _working; + /** + * Protects access to #_abort + */ + QMutex mutex; + + Project_sV *m_project; + RenderPreferences_sV m_prefs; ///< \todo Set preferences + + AbstractRenderTarget_sV *m_renderTarget; + + qreal m_timeStart; + qreal m_timeEnd; + + QElapsedTimer m_stopwatch; + qint64 m_renderTimeElapsed; + + bool m_stopRendering; // Process is aborted when true + qreal m_nextFrameTime; + + qreal m_prevTime; + + int currentProgress; + +signals: + /** + * This signal is emitted when the Worker request to Work + * requestWork() + */ + void workFlowRequested(); + + /** + * signal rendering progression + */ + void signalItemDesc(QString desc); + void signalTaskProgress(int value); + + /** + * This signal is emitted when process is finished (or being aborted) + */ + void signalRenderingContinued(); + void signalRenderingStopped(QString renderTime); + void signalRenderingFinished(QString renderTime); + void signalRenderingAborted(QString reason); + + void signalNewTask(QString desc, int taskSize); + +public slots: + void slotContinueRendering(); + void slotStopRendering(); + +}; + +#endif // RENDERTASK_SV_H +
View file
slowmoVideo-0.6.tar.xz/src/project/segmentList_sV.cpp
Changed
(renamed from src/slowmoVideo/project/segmentList_sV.cpp)
View file
slowmoVideo-0.6.tar.xz/src/project/segmentList_sV.h
Changed
(renamed from src/slowmoVideo/project/segmentList_sV.h)
View file
slowmoVideo-0.6.tar.xz/src/project/segment_sV.cpp
Changed
(renamed from src/slowmoVideo/project/segment_sV.cpp)
View file
slowmoVideo-0.6.tar.xz/src/project/segment_sV.h
Changed
(renamed from src/slowmoVideo/project/segment_sV.h)
View file
slowmoVideo-0.6.tar.xz/src/project/shutterFunctionList_sV.cpp
Changed
(renamed from src/slowmoVideo/project/shutterFunctionList_sV.cpp)
View file
slowmoVideo-0.6.tar.xz/src/project/shutterFunctionList_sV.h
Changed
(renamed from src/slowmoVideo/project/shutterFunctionList_sV.h)
View file
slowmoVideo-0.6.tar.xz/src/project/shutterFunction_sV.cpp
Changed
(renamed from src/slowmoVideo/project/shutterFunction_sV.cpp)
View file
slowmoVideo-0.6.tar.xz/src/project/shutterFunction_sV.h
Changed
(renamed from src/slowmoVideo/project/shutterFunction_sV.h)
View file
slowmoVideo-0.6.tar.xz/src/project/tag_sV.cpp
Changed
(renamed from src/slowmoVideo/project/tag_sV.cpp)
View file
slowmoVideo-0.6.tar.xz/src/project/tag_sV.h
Changed
(renamed from src/slowmoVideo/project/tag_sV.h)
View file
slowmoVideo-0.6.tar.xz/src/project/videoFrameSource_sV.cpp
Added
@@ -0,0 +1,328 @@ +/* +This file is part of slowmoVideo. +Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +*/ + +#include "videoFrameSource_sV.h" +#include "project_sV.h" + +#include <QtCore/QProcess> +#include <QtCore/QTimer> +#include <QtCore/QTime> +#include <QtCore/QRegExp> + +QRegExp VideoFrameSource_sV::regexFrameNumber("frame=\\s*(\\d+)"); + +//not sure about that here, means unlimited ! +const int tmout = (-1); + +/// \todo Check QProcess::exitCode() to find out if ffmpeg worked or not +VideoFrameSource_sV::VideoFrameSource_sV(const Project_sV *project, const QString &filename) noexcept(false) : + AbstractFrameSource_sV(project), + m_inFile(filename), + m_fps(1,1), + m_ffmpegSemaphore(1), + m_initialized(false), + cur_frame(0) +{ + if (!QFileInfo(filename).exists()) { + throw FrameSourceError(tr("Video file %1 does not exist!").arg(filename)); + } + + m_videoInfo = new VideoInfoSV(); + // use copy constructor + *m_videoInfo = getInfo(filename.toStdString().c_str()); + + if (m_videoInfo->streamsCount <= 0) { + qDebug() << "Video info is invalid: " << filename; + throw FrameSourceError(tr("Video is invalid, no streams found in %1").arg(filename)); + } + m_fps = Fps_sV(m_videoInfo->frameRateNum, m_videoInfo->frameRateDen); + + + + createDirectories(); + locateFFmpeg(); + + m_ffmpeg = new QProcess(this); + m_timer = new QTimer(this); + + QObject::connect(m_timer, SIGNAL(timeout()), this, SLOT(slotProgressUpdate())); +} +VideoFrameSource_sV::~VideoFrameSource_sV() +{ + delete m_ffmpeg; + delete m_timer; + delete m_videoInfo; +} + + +void VideoFrameSource_sV::slotUpdateProjectDir() +{ + //TODO: is it really needed ? + // Delete old directories if they are empty + //m_dirFramesSmall.rmdir("."); + //m_dirFramesOrig.rmdir("."); + createDirectories(); +} + +void VideoFrameSource_sV::createDirectories() +{ + m_dirFramesSmall = project()->getDirectory("frames/small"); + m_dirFramesOrig = project()->getDirectory("frames/orig"); +} + +void VideoFrameSource_sV::initialize() +{ + if (!initialized()) { + // Start the frame extraction process + slotExtractSmallFrames(); + } +} +bool VideoFrameSource_sV::initialized() const +{ + return m_initialized; +} + +int64_t VideoFrameSource_sV::framesCount() const +{ + return m_videoInfo->framesCount; +} + +void VideoFrameSource_sV::setFramesCount(int64_t framesCount) { + //qDebug() << "setting frameCount "<< framesCount; + m_videoInfo->framesCount = framesCount; +} + +const Fps_sV* VideoFrameSource_sV::fps() const +{ + return &m_fps; +} +QImage VideoFrameSource_sV::frameAt(const uint frame, const FrameSize frameSize) +{ + // TODO: + QString path = framePath(frame, frameSize); + //qDebug() << "frameAt "<< frame; +#if 0 + if(frameCache.contains(path)) + return *(frameCache.object(path)); +#endif + QImage _frame = QImage(path); +#if 0 + frameCache.insert(path, &_frame); +#endif + return _frame; +} +const QString VideoFrameSource_sV::videoFile() const +{ + return m_inFile.fileName(); +} + +const QString VideoFrameSource_sV::framePath(const uint frame, const FrameSize frameSize) const +{ + QString dir; + switch (frameSize) { + case FrameSize_Orig: + dir = m_dirFramesOrig.absolutePath(); + break; + case FrameSize_Small: + default: + dir = m_dirFramesSmall.absolutePath(); + break; + } + + // ffmpeg numbering starts with 1, therefore add 1 to the frame number + return QString("%1/frame%2.png").arg(dir).arg(frame+1, 5, 10, QChar::fromLatin1('0')); +} + +void VideoFrameSource_sV::extractFramesFor(const FrameSize frameSize, QProcess *process) +{ + QStringList args; + args << "-i" << m_inFile.fileName(); + args << "-f" << "image2"; + + if (frameSize == FrameSize_Small) { + int w = m_videoInfo->width; + int h = m_videoInfo->height; + while (w > 600) { + w /= 2; + h /= 2; + } + qDebug() << "Thumbnail frame size: " << w << "x" << h; + args << "-s" << QString("%1x%2").arg(w).arg(h); + args << m_dirFramesSmall.absoluteFilePath("frame%05d.png"); + } else { + args << m_dirFramesOrig.absoluteFilePath("frame%05d.png"); + } + + qDebug() << "Extracting frames with " << m_settings.value("binaries/ffmpeg", "ffmpeg").toString() << args; +// { +// QStringList a2; +// a2 << "-version"; +// process->start(m_settings.value("binaries/ffmpeg").toString());//, "ffmpeg").toString(), a2); +// qDebug() << process->readAllStandardOutput(); +// qDebug() << process->readAllStandardError(); +// process->terminate(); +// } + process->start(m_settings.value("binaries/ffmpeg", "ffmpeg").toString(), args); + qDebug() << process->readAllStandardOutput(); + qDebug() << process->readAllStandardError(); +} + +bool VideoFrameSource_sV::rebuildRequired(const FrameSize frameSize) +{ + bool needsRebuild = false; + + QImage frame = frameAt(0, frameSize); + needsRebuild |= frame.isNull(); + + //qDebug() << "last frame to check " << m_videoInfo->framesCount-1; + // rewind a little bit to account rounding error... + frame = frameAt(m_videoInfo->framesCount-10, frameSize); + needsRebuild |= frame.isNull(); + + return needsRebuild; +} + +void VideoFrameSource_sV::locateFFmpeg() +{ + if (m_avconvInfo.locate(m_settings.value("binaries/ffmpeg", "").toString())) { + m_settings.setValue("binaries/ffmpeg", m_avconvInfo.executablePath()); + m_settings.sync(); + } else { + throw FrameSourceError(tr("ffmpeg/avconv executable not found! Cannot load video." + "\n(It is also possible that it took a little long to respond " + "due to high workload, so you might want to try again.)" + #ifdef WINDOWS + "\nPlease download the static ffmpeg build from ffmpeg.zeranoe.com " + "and extract ffmpeg.exe in the same directory as slowmoUI.exe." + #endif + )); + } +} + +void VideoFrameSource_sV::slotExtractSmallFrames() +{ + emit signalNextTask(tr("Extracting thumbnail-sized frames from the video file"), m_videoInfo->framesCount); + m_timer->start(100); + if (rebuildRequired(FrameSize_Small)) { + + m_ffmpegSemaphore.acquire(); + + m_ffmpeg->waitForFinished(tmout); + m_ffmpeg->terminate(); + + disconnect(m_ffmpeg, SIGNAL(finished(int)), this, nullptr); + connect(m_ffmpeg, SIGNAL(finished(int)), this, SLOT(slotExtractOrigFrames())); + + extractFramesFor(FrameSize_Small, m_ffmpeg); + + m_ffmpegSemaphore.release(); + + } else { + slotExtractOrigFrames(); + } +} + +void VideoFrameSource_sV::slotExtractOrigFrames() +{ + emit signalNextTask(tr("Extracting original-sized frames from the video file"), m_videoInfo->framesCount); + m_timer->start(100); + if (rebuildRequired(FrameSize_Orig)) { + + m_ffmpegSemaphore.acquire(); + + m_ffmpeg->waitForFinished(tmout); + m_ffmpeg->terminate(); + + disconnect(m_ffmpeg, SIGNAL(finished(int)), this, 0); + connect(m_ffmpeg, SIGNAL(finished(int)), this, SLOT(slotInitializationFinished())); + + extractFramesFor(FrameSize_Orig, m_ffmpeg); + + m_ffmpegSemaphore.release(); + + } else { + slotInitializationFinished(); + } +} + +void VideoFrameSource_sV::slotInitializationFinished() +{ + m_timer->stop(); + emit signalAllTasksFinished(); + + m_ffmpegSemaphore.acquire(); + m_ffmpeg->waitForFinished(tmout); + + QRegExp regex(regexFrameNumber); + QString s; + s = QString(m_ffmpeg->readAllStandardError()); + qDebug() << "slotExtractOrigFrames : " << s << "end"; + if (regex.lastIndexIn(s) >= 0) { + //fprintf(stderr,"last frame is : %d\n",regex.cap(1).toInt()); + setFramesCount(regex.cap(1).toLong()); + } else { + //fprintf(stderr, "last frame not found !\n" ); + qDebug() << "last frame not found"; + } + + m_ffmpeg->terminate(); + m_ffmpegSemaphore.release(); + + if (!rebuildRequired(FrameSize_Small) && !rebuildRequired(FrameSize_Orig)) { + m_initialized = true; + } +} + +void VideoFrameSource_sV::slotAbortInitialization() +{ + m_ffmpegSemaphore.acquire(); + if (m_ffmpeg != NULL) { + m_ffmpeg->terminate(); + } + m_ffmpegSemaphore.release(); + +} + +void VideoFrameSource_sV::slotProgressUpdate() +{ + QRegExp regex(regexFrameNumber); + QString s; + m_ffmpegSemaphore.acquire(); + s = QString(m_ffmpeg->readAllStandardError()); + if (regex.lastIndexIn(s) >= 0) { + emit signalTaskProgress(regex.cap(1).toInt()); + emit signalTaskItemDescription(tr("Frame %1 of %2").arg(regex.cap(1)).arg(m_videoInfo->framesCount)); + } + m_ffmpegSemaphore.release(); +} + + +void VideoFrameSource_sV::loadOrigFrames() +{ + + m_ffmpegSemaphore.acquire(); + + m_ffmpeg->waitForFinished(tmout); + m_ffmpeg->terminate(); + + QTime time; + time.start(); + + extractFramesFor(FrameSize_Orig, m_ffmpeg); + + m_ffmpeg->waitForFinished(tmout); + m_ffmpeg->terminate(); + + qDebug() << "ffmpeg in " << time.elapsed() << "ms"; + + m_ffmpegSemaphore.release(); + + +}
View file
slowmoVideo-0.6.tar.xz/src/project/videoFrameSource_sV.h
Added
@@ -0,0 +1,114 @@ +/* +This file is part of slowmoVideo. +Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +*/ + +#ifndef VIDEOFRAMESOURCE_SV_H +#define VIDEOFRAMESOURCE_SV_H + +#include "abstractFrameSource_sV.h" +#include "../lib/defs_sV.hpp" +#include "../lib/avconvInfo_sV.h" +#include <QtCore/QDir> +#include <QtCore/QFile> +#include <QtCore/QTimer> +#include <QtCore/QSettings> +#include <QtCore/QSemaphore> + +#include "../lib/videoInfo_sV.h" + +class QProcess; +class Project_sV; + +/** + \brief Uses frames from a video file + \todo Use libav directly for frame extraction? (not the ffmpeg command) + \todo Extract full frames only before rendering, only used ones + */ +class VideoFrameSource_sV : public AbstractFrameSource_sV +{ + Q_OBJECT +public: + /** Builds a new video frame source from the given file. */ + VideoFrameSource_sV(const Project_sV *project, const QString &filename) noexcept(false); + + ~VideoFrameSource_sV(); + + void initialize(); + bool initialized() const; + + int64_t framesCount() const; + void setFramesCount(int64_t framesCount); + + const Fps_sV* fps() const; + QImage frameAt(const uint frame, const FrameSize frameSize = FrameSize_Orig); + const QString framePath(const uint frame, const FrameSize frameSize) const; + + /** \return The absolute path of the input video file. */ + const QString videoFile() const; + + void loadOrigFrames(); + +public slots: + void slotAbortInitialization(); + void slotUpdateProjectDir(); + +private: + static QRegExp regexFrameNumber; + +private: + QFile m_inFile; + QDir m_dirFramesSmall; + QDir m_dirFramesOrig; + QSettings m_settings; + AvconvInfo m_avconvInfo; + + VideoInfoSV *m_videoInfo; + Fps_sV m_fps; + + QTimer *m_timer; + QProcess *m_ffmpeg; + QSemaphore m_ffmpegSemaphore; + bool m_initialized; + int64_t cur_frame; + + void createDirectories(); + /** + Extracts the frames from the video file into single images + */ + void extractFramesFor(const FrameSize frameSize, QProcess *process); + /** + Checks the availability of the frames and decides + whether they need to be extracted with extractFrames() + */ + bool rebuildRequired(const FrameSize frameSize); + + void locateFFmpeg(); + +public: + static bool testFfmpegExecutable(QString path); + +signals: + /** Emitted when the task for extracting original-sized images has finished (or has been terminated) */ + void signalExtractOrigFramesFinished(); + /** Emitted when the task for extracting thumbnail-sized images has finished (or has been terminated) */ + void signalExtractSmallFramesFinished(); + +private slots: + void slotExtractOrigFrames(); + void slotExtractSmallFrames(); + void slotInitializationFinished(); + /** + Checks the progress of the ffmpeg threads by reading their stderr + and emits signalTaskProgress() and signalTaskItemDescription() if necessary. + */ + void slotProgressUpdate(); + +}; + +#endif // VIDEOFRAMESOURCE_SV_H
View file
slowmoVideo-0.6.tar.xz/src/project/videoRenderTarget_sV.cpp
Added
@@ -0,0 +1,73 @@ +/* +This file is part of slowmoVideo. +Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +*/ + +// Against the «UINT64_C not declared» message. +// See: http://code.google.com/p/ffmpegsource/issues/detail?id=11 +#ifdef __cplusplus + #define __STDC_CONSTANT_MACROS + #ifdef _STDINT_H + #undef _STDINT_H + #endif + # include <stdint.h> +#endif + +#include "videoRenderTarget_sV.h" +#include "renderTask_sV.h" +#include <QtCore/QObject> + +extern "C" { +#include "../lib/ffmpegEncode_sV.h" +} + +VideoRenderTarget_sV::VideoRenderTarget_sV(RenderTask_sV *parentRenderTask) : + AbstractRenderTarget_sV(parentRenderTask) +{ + m_videoOut = (VideoOut_sV*)malloc(sizeof(VideoOut_sV)); +} +VideoRenderTarget_sV::~VideoRenderTarget_sV() +{ + free(m_videoOut); +} + +void VideoRenderTarget_sV::setTargetFile(const QString &filename) +{ + m_filename = filename; +} +void VideoRenderTarget_sV::setVcodec(const QString &codec) +{ + m_vcodec = codec; +} + +void VideoRenderTarget_sV::openRenderTarget() noexcept(false) +{ + char *vcodec = NULL; + if (m_vcodec.length() > 0) { + vcodec = (char*)malloc(m_vcodec.length()+1); + strcpy(vcodec, m_vcodec.toStdString().c_str()); + } + int worked = + prepare(m_videoOut, m_filename.toStdString().c_str(), vcodec, + renderTask()->resolution().width(), renderTask()->resolution().height(), + renderTask()->fps().fps() * renderTask()->resolution().width() * renderTask()->resolution().height(), + renderTask()->fps().den, renderTask()->fps().num); + if (worked != 0) { + throw Error_sV(QObject::tr("Video could not be prepared (error code %1).\n%2").arg(worked).arg(m_videoOut->errorMessage)); + } +} + +void VideoRenderTarget_sV::slotConsumeFrame(const QImage &image, const int frameNumber) +{ + eatARGB(m_videoOut, image.bits()); +} + +void VideoRenderTarget_sV::closeRenderTarget() noexcept(false) +{ + finish(m_videoOut); +}
View file
slowmoVideo-0.6.tar.xz/src/project/videoRenderTarget_sV.h
Added
@@ -0,0 +1,47 @@ +/* +This file is part of slowmoVideo. +Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +*/ + +#ifndef VIDEORENDERTARGET_SV_H +#define VIDEORENDERTARGET_SV_H + +#include "abstractRenderTarget_sV.h" + +struct VideoOut_sV; +class RenderTask_sV; + +/// Produces videos from frames. +class VideoRenderTarget_sV : public AbstractRenderTarget_sV +{ +public: + /// Constructs a new video render target + VideoRenderTarget_sV(RenderTask_sV *parentRenderTask); + virtual ~VideoRenderTarget_sV(); + + /// openRenderTarget() will throw an error if the target file cannot be opened. + void setTargetFile(const QString& filename); + /// Set a custom video codec (see <pre>ffmpeg -codecs</pre> for a list of available codecs). + void setVcodec(const QString& codec); + + void openRenderTarget() noexcept(false); + void closeRenderTarget() noexcept(false); + +public slots: + void slotConsumeFrame(const QImage &image, const int frameNumber); + +private: + QString m_filename; + QString m_vcodec; + VideoOut_sV *m_videoOut; + + int m_width; + int m_height; +}; + +#endif // VIDEORENDERTARGET_SV_H
View file
slowmoVideo-0.6.tar.xz/src/project/work_flow.cpp
Added
@@ -0,0 +1,161 @@ +/* + * precalculate optical flow + * 2014 Valery Brasseur <vbrasseur@gmail.com> + */ + +#include "flowSourceOpenCV_sV.h" +#include "project_sV.h" +#include "abstractFrameSource_sV.h" +#include "flowRW_sV.h" +#include "flowField_sV.h" + +#ifndef OCV_VERSION_3 +// OpenCV 2.x +#include "opencv2/video/tracking.hpp" +#include "opencv2/imgproc/imgproc.hpp" +#include "opencv2/highgui/highgui.hpp" + +#else +#error "need to portto OpenCV 3.x" + +#endif + +#include "work_flow.h" +#include <QTimer> +#include <QEventLoop> + +#include <QThread> +#include <QDebug> + +using namespace cv; + +WorkerFlow::WorkerFlow(QObject *parent) : +QObject(parent) +{ + _working =false; + _abort = false; +} + +void WorkerFlow::requestWork() +{ + mutex.lock(); + _working = true; + _abort = false; + qDebug()<<"OpticalFlow worker start in Thread "<<thread()->currentThreadId(); + mutex.unlock(); + emit workFlowRequested(); +} + +void WorkerFlow::abort() +{ + mutex.lock(); + if (_working) { + _abort = true; + qDebug()<<"OpticalFlow worker aborting in Thread "<<thread()->currentThreadId(); + } + mutex.unlock(); +} + + +//TODO: should get an object Flow... +void WorkerFlow::setFrameSize(FrameSize _frameSize) +{ + frameSize = _frameSize; +} + +void WorkerFlow::setProject(Project_sV *_project) +{ + project = _project; +} + + +void WorkerFlow::setFlowSource(AbstractFlowSource_sV* _flowsource) +{ + flowSource = _flowsource; +} + + +//TODO: call abstractflow source method +/** + * doWorkFlow + * call optical flow on each frame + */ +void WorkerFlow::doWorkFlow() +{ + qDebug() << "Starting OpticalFlow process in Thread " << thread()->currentThreadId(); + int lastFrame; + int frame; + int next = 0; + int nextFrame; + + /* out of loop work */ + lastFrame = project->frameSource()->framesCount(); + frame = 0; + + if (forward) { + qDebug() << "forward flow"; + next = 1; + } else { + qDebug() << "backward flow"; + next = -1; + } + Mat prevgray, gray, flow; + + qDebug() << "Pre Building forward flow for Size: " << frameSize; + + // load first frame + QString prevpath = project->frameSource()->framePath(frame, frameSize); + prevgray = imread(prevpath.toStdString(), 0); + + /* real workhorse */ + for (frame=0; frame<lastFrame; frame++) { + // Checks if the process should be aborted + mutex.lock(); + bool abort = _abort; + mutex.unlock(); + + if (abort) { + qDebug()<<"Aborting OpticalFlow process in Thread "<<thread()->currentThreadId(); + break; + } + + nextFrame = frame + next; + + QString flowFileName(flowSource->flowPath(frame, nextFrame, frameSize)); + + qDebug() << "Building flow for left frame " << frame << " to right frame " << nextFrame << "using" << frameSize; + /// \todo Check if size is equal + if (!QFile(flowFileName).exists()) { + //QTime time; + //time.start(); + + QString prevpath = project->frameSource()->framePath(frame, frameSize); + QString path = project->frameSource()->framePath(nextFrame, frameSize); + + gray = imread(path.toStdString(), 0); + + // use previous flow info + //if (frame!=0) + // flags |= OPTFLOW_USE_INITIAL_FLOW; + qDebug() << "dummy Optical flow built for " << flowFileName; + std::swap(prevgray, gray); + qDebug() << "Optical flow built for " << flowFileName; + } else { + qDebug().nospace() << "Re-using existing flow image for left frame " << frame << " to right frame " << nextFrame << ": " << flowFileName; + } + //qDebug() << "Optical flow built for " << flowFileName << " in " << time.elapsed() << " ms."; + // Once we're done waiting, value is updated + emit valueChanged(QString::number(frame)); + + } /* for */ + + // Set _working to false, meaning the process can't be aborted anymore. + mutex.lock(); + _working = false; + mutex.unlock(); + + qDebug()<<"OpticalFlow process finished in Thread "<<thread()->currentThreadId(); + + // the finished signal is sent + emit finished(); +}
View file
slowmoVideo-0.6.tar.xz/src/project/work_flow.h
Added
@@ -0,0 +1,105 @@ +/* + precalculate optical flow +* 2014 Valery Brasseur <vbrasseur@gmail.com> +*/ + +#ifndef WORKERFLOW_H +#define WORKERFLOW_H + +#include "project_sV.h" + +#include <QObject> +#include <QMutex> + +class WorkerFlow : public QObject +{ + Q_OBJECT + +public: + explicit WorkerFlow(QObject *parent = 0); + /** + * Requests the process to start + * + * It is thread safe as it uses #mutex to protect access to #_working variable. + */ + void requestWork(); + /** + * Requests the process to abort + * + * It is thread safe as it uses #mutex to protect access to #_abort variable. + */ + void abort(); + + /* + * set running size + */ + void setFrameSize(FrameSize _frameSize); + void setProject(Project_sV *_project); + + void setFlowSource(AbstractFlowSource_sV* _flowsource); + + void setDirection(int _forward) { forward = _forward;}; + +private: + /** + * Process is aborted when true + */ + bool _abort; + /** + * true when Worker is doing work + */ + bool _working; + /** + * Protects access to #_abort + */ + QMutex mutex; + + /** + * which source flow + */ + AbstractFlowSource_sV* flowSource; + + /** + * which size do we create + */ + FrameSize frameSize; + + /* + * which project is concern + */ + Project_sV *project; + + int forward; +#if 0 + const QString flowPath(const uint leftFrame, const uint rightFrame, const FrameSize frameSize) const; + + QDir m_dirFlowSmall; + QDir m_dirFlowOrig; +#endif + + +signals: + /** + * This signal is emitted when the Worker request to Work + * requestWork() + */ + void workFlowRequested(); + /** + * This signal is emitted when counted value is changed (every sec) + */ + void valueChanged(const QString &value); + /** + * This signal is emitted when process is finished (or being aborted) + */ + void finished(); + + public slots: + /** + * calculate optical flow + * + */ + void doWorkFlow(); +}; + +#endif // WORKER_H +
View file
slowmoVideo-0.6.tar.xz/src/project/xmlProjectRW_sV.cpp
Added
@@ -0,0 +1,599 @@ +/* +This file is part of slowmoVideo. +Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +*/ + +#include "xmlProjectRW_sV.h" + +#include "project_sV.h" +#include "projectPreferences_sV.h" +#include "shutterFunctionList_sV.h" +#include "shutterFunction_sV.h" +#include "nodeList_sV.h" +#include "videoFrameSource_sV.h" +#include "emptyFrameSource_sV.h" +#include "imagesFrameSource_sV.h" +#include "motionBlur_sV.h" +#include "abstractFlowSource_sV.h" +//TODO: #include "defs_sV.hpp" + +#include <QTextStream> + + +int XmlProjectRW_sV::saveProject(Project_sV *project, QString filename) noexcept(false) +{ + //TODO: use global define in defs ! + QDomDocument doc; + QDomElement root = doc.createElement("sVproject"); + root.setAttribute("version", SLOWMOPROJECT_VERSION_MAJOR); + root.setAttribute("version_minor", SLOWMOPROJECT_VERSION_MINOR); + doc.appendChild(root); + + // File info + QDomElement info = doc.createElement("info"); + root.appendChild(info); + QDomElement appName = doc.createElement("appName"); + appName.appendChild(doc.createTextNode("slowmoVideo")); + QDomElement version = doc.createElement("version"); + version.setAttribute("major", SLOWMOVIDEO_VERSION_MAJOR); + version.setAttribute("minor", SLOWMOVIDEO_VERSION_MINOR); + version.setAttribute("micro", SLOWMOVIDEO_VERSION_PATCH); + info.appendChild(appName); + info.appendChild(version); + + + ProjectPreferences_sV *pr = project->preferences(); + // Project Preferences + QDomElement preferences = doc.createElement("preferences"); + root.appendChild(preferences); + QDomElement renderSectionMode = doc.createElement("renderSectionMode"); + QDomElement renderStartTag = doc.createElement("renderStartTag"); + QDomElement renderEndTag = doc.createElement("renderEndTag"); + QDomElement renderStartTime = doc.createElement("renderStartTime"); + QDomElement renderEndTime = doc.createElement("renderEndTime"); + QDomElement renderFrameSize = doc.createElement("renderFrameSize"); + QDomElement renderInterpolation = doc.createElement("renderInterpolationType"); + QDomElement renderMotionblur = doc.createElement("renderMotionblurType"); + QDomElement renderFPS = doc.createElement("renderFPS"); + QDomElement renderSlowmoSamples = doc.createElement("renderSlowmoSamples"); + QDomElement renderMaxSamples = doc.createElement("renderMaxSamples"); + QDomElement renderTarget = doc.createElement("renderTarget"); + QDomElement imagesOutputDir = doc.createElement("imagesOutputDir"); + QDomElement imagesFilenamePattern = doc.createElement("imagesFilenamePattern"); + QDomElement videoFilename = doc.createElement("videoFilename"); + QDomElement videoCodec = doc.createElement("videoCodec"); + QDomElement flowV3dLambda = doc.createElement("flowV3dLambda"); + QDomElement prevTagAxis = doc.createElement("prevTagAxis"); + QDomElement viewport_t0 = doc.createElement("viewport_t0"); + QDomElement viewport_secRes = doc.createElement("viewport_secRes"); + QDomElement canvas_xAxisFPS = doc.createElement("canvas_xAxisFPS"); + preferences.appendChild(renderSectionMode); + renderSectionMode.appendChild(renderStartTag); + renderSectionMode.appendChild(renderEndTag); + renderSectionMode.appendChild(renderStartTime); + renderSectionMode.appendChild(renderEndTime); + preferences.appendChild(renderFrameSize); + preferences.appendChild(renderInterpolation); + preferences.appendChild(renderMotionblur); + preferences.appendChild(renderFPS); + preferences.appendChild(renderSlowmoSamples); + preferences.appendChild(renderMaxSamples); + preferences.appendChild(renderTarget); + preferences.appendChild(imagesOutputDir); + preferences.appendChild(imagesFilenamePattern); + preferences.appendChild(videoFilename); + preferences.appendChild(videoCodec); + preferences.appendChild(flowV3dLambda); + preferences.appendChild(prevTagAxis); + preferences.appendChild(viewport_t0); + preferences.appendChild(viewport_secRes); + preferences.appendChild(canvas_xAxisFPS); + renderSectionMode.setAttribute("mode", pr->renderSectionMode()); + renderStartTag.setAttribute("label", pr->renderStartTag()); + renderEndTag.setAttribute("label", pr->renderEndTag()); + renderStartTime.setAttribute("time", pr->renderStartTime()); + renderEndTime.setAttribute("time", pr->renderEndTime()); + renderFrameSize.setAttribute("size", pr->renderFrameSize()); + renderInterpolation.setAttribute("type", pr->renderInterpolationType()); + renderMotionblur.setAttribute("type", pr->renderMotionblurType()); + renderFPS.setAttribute("fps", pr->renderFPS().toString()); + renderSlowmoSamples.setAttribute("number", project->motionBlur()->slowmoSamples()); + renderMaxSamples.setAttribute("number", project->motionBlur()->maxSamples()); + renderTarget.setAttribute("target", pr->renderTarget()); + imagesOutputDir.setAttribute("dir", pr->imagesOutputDir()); + imagesFilenamePattern.setAttribute("pattern", pr->imagesFilenamePattern()); + videoFilename.setAttribute("file", pr->videoFilename()); + videoCodec.setAttribute("codec", pr->videoCodec()); + flowV3dLambda.setAttribute("lambda", pr->flowV3DLambda()); + prevTagAxis.setAttribute("axis", QVariant(pr->lastSelectedTagAxis()).toString()); + viewport_t0.setAttribute("x", pr->viewport_t0().x()); + viewport_t0.setAttribute("y", pr->viewport_t0().y()); + viewport_secRes.setAttribute("x", QString().setNum(pr->viewport_secRes().x())); + viewport_secRes.setAttribute("y", QString().setNum(pr->viewport_secRes().y())); + canvas_xAxisFPS.setAttribute("fps", pr->canvas_xAxisFPS().toString()); + + + // Project Resources + QDomElement resources = doc.createElement("resources"); + root.appendChild(resources); + QDomElement projectDir = doc.createElement("projectDir"); + projectDir.appendChild(doc.createTextNode(project->getDirectory(".", false).absolutePath())); + resources.appendChild(projectDir); + resources.appendChild(frameSource(&doc, project->frameSource())); + + + // Shutter functions + QDomElement shutterFunctions = doc.createElement("shutterFunctions"); + root.appendChild(shutterFunctions); + for (int i = 0; i < project->shutterFunctions()->size(); i++) { + QDomElement func = doc.createElement("function"); + func.setAttribute("id", project->shutterFunctions()->at(i)->id()); + QDomElement code = doc.createElement("code"); + func.appendChild(code); + code.appendChild(doc.createTextNode(project->shutterFunctions()->at(i)->function())); + shutterFunctions.appendChild(func); + } + + + // Nodes + QDomElement nodes = doc.createElement("nodes"); + root.appendChild(nodes); + NodeList_sV *nodeList = project->nodes(); + for (int i = 0; i < nodeList->size(); i++) { + nodes.appendChild(nodeToDom(&doc, &nodeList->at(i))); + } + + // Tags + QDomElement tags = doc.createElement("tags"); + root.appendChild(tags); + for (int i = 0; i < project->tags()->size(); i++) { + tags.appendChild(tagToDom(&doc, project->tags()->at(i))); + } + + QFile outFile(filename); + if (!outFile.open(QIODevice::WriteOnly)) { + throw Error_sV(QObject::tr("Cannot write to %1; please check if you have write permissions.").arg(filename)); + } + QTextStream output(&outFile); + doc.save(output, 4); + output.flush(); + outFile.close(); + + project->setProjectFilename(filename); + + return 0; +} + +const QDomElement XmlProjectRW_sV::nodeToDom(QDomDocument *doc, const Node_sV *node) +{ + QDomElement el = doc->createElement("node"); + QDomElement x = doc->createElement("x"); + QDomElement y = doc->createElement("y"); + QDomElement selected = doc->createElement("selected"); + QDomElement leftHandle = doc->createElement("leftHandle"); + QDomElement rightHandle = doc->createElement("rightHandle"); + QDomElement shutterFunc = doc->createElement("shutterFunction"); + QDomElement leftCurveType = doc->createElement("type"); + QDomElement rightCurveType = doc->createElement("type"); + QDomElement leftX = doc->createElement("x"); + QDomElement leftY = doc->createElement("y"); + QDomElement rightX = doc->createElement("x"); + QDomElement rightY = doc->createElement("y"); + el.appendChild(x); + el.appendChild(y); + el.appendChild(selected); + el.appendChild(leftHandle); + el.appendChild(rightHandle); + if (node->shutterFunctionID().length() > 0) { + el.appendChild(shutterFunc); + } + x.appendChild(doc->createTextNode(QString("%1").arg(node->xUnmoved()))); + y.appendChild(doc->createTextNode(QString("%1").arg(node->yUnmoved()))); + selected.appendChild(doc->createTextNode(QString("%1").arg(node->selected()))); + shutterFunc.appendChild(doc->createTextNode(node->shutterFunctionID())); + + leftHandle.appendChild(leftX); + leftHandle.appendChild(leftY); + leftHandle.appendChild(leftCurveType); + rightHandle.appendChild(rightX); + rightHandle.appendChild(rightY); + rightHandle.appendChild(rightCurveType); + + leftX.appendChild(doc->createTextNode(QString("%1").arg(node->leftNodeHandle().x()))); + leftY.appendChild(doc->createTextNode(QString("%1").arg(node->leftNodeHandle().y()))); + leftCurveType.appendChild(doc->createTextNode(QVariant((int)node->leftCurveType()).toString())); + rightX.appendChild(doc->createTextNode(QString("%1").arg(node->rightNodeHandle().x()))); + rightY.appendChild(doc->createTextNode(QString("%1").arg(node->rightNodeHandle().y()))); + rightCurveType.appendChild(doc->createTextNode(QVariant((int)node->rightCurveType()).toString())); + + return el; +} + +const QDomElement XmlProjectRW_sV::tagToDom(QDomDocument *doc, const Tag_sV &tag) +{ + QDomElement el = doc->createElement("tag"); + QDomElement t = doc->createElement("time"); + QDomElement desc = doc->createElement("description"); + QDomElement axis = doc->createElement("axis"); + el.appendChild(t); + el.appendChild(desc); + el.appendChild(axis); + t.appendChild(doc->createTextNode(QString("%1").arg(tag.time()))); + desc.appendChild(doc->createTextNode(tag.description())); + axis.appendChild(doc->createTextNode(QVariant(tag.axis()).toString())); + return el; +} + +const QDomElement XmlProjectRW_sV::frameSource(QDomDocument *doc, const AbstractFrameSource_sV *frameSource) +{ + QDomElement source = doc->createElement("frameSource"); + if (dynamic_cast<const VideoFrameSource_sV *>(frameSource) != NULL) { + qDebug() << "Frame source is a video."; + + const VideoFrameSource_sV *vfs = dynamic_cast<const VideoFrameSource_sV *>(frameSource); + source.setAttribute("type", "videoFile"); + QDomElement file = doc->createElement("inputFile"); + file.appendChild(doc->createTextNode(vfs->videoFile())); + source.appendChild(file); + + } else if (dynamic_cast<const ImagesFrameSource_sV *>(frameSource) != NULL) { + qDebug() << "Frame source are images."; + + const ImagesFrameSource_sV *ifs = dynamic_cast<const ImagesFrameSource_sV *>(frameSource); + source.setAttribute("type", "images"); + QDomElement files = doc->createElement("inputFiles"); + QStringList images = ifs->inputFiles(); + for (int i = 0; i < images.size(); i++) { + QDomElement file = doc->createElement("file"); + file.appendChild(doc->createTextNode(images.at(i))); + files.appendChild(file); + } + source.appendChild(files); + + } else if (dynamic_cast<const EmptyFrameSource_sV *>(frameSource) != NULL) { + qDebug() << "Frame source is empty."; + source.setAttribute("type", "empty"); + } else { + qDebug() << "Unknown frame source type; cannot save!"; + source.setAttribute("type", "unknown"); + Q_ASSERT(false); + } + return source; +} + +void XmlProjectRW_sV::loadFrameSource(QXmlStreamReader *reader, Project_sV *project) noexcept(false) +{ + //qDebug() << "loadFrameSource"; + QStringRef frameSourceType = reader->attributes().value("type"); + if (frameSourceType.compare(QLatin1String("videoFile")) == 0) { + while (reader->readNextStartElement()) { + if (reader->name() == "inputFile") { + VideoFrameSource_sV *frameSource = new VideoFrameSource_sV(project, reader->readElementText()); + project->loadFrameSource(frameSource); + } else { + qDebug() << "Unknown element in video frame source section: " << reader->name(); + reader->skipCurrentElement(); + } + } + + } else if (frameSourceType.compare(QLatin1String("images")) == 0) { + while (reader->readNextStartElement()) { + if (reader->name() == "inputFiles") { + + QStringList images; + while (reader->readNextStartElement()) { + if (reader->name() == "file") { + images << reader->readElementText(); + } else { + reader->skipCurrentElement(); + } + } + ImagesFrameSource_sV *frameSource = new ImagesFrameSource_sV(project, images); + project->loadFrameSource(frameSource); + } + } + } else if (frameSourceType.compare(QLatin1String("empty")) == 0) { + EmptyFrameSource_sV *frameSource = new EmptyFrameSource_sV(project); + project->loadFrameSource(frameSource); + reader->skipCurrentElement(); + } else { + reader->skipCurrentElement(); + qDebug() << "Unknown frame source: " << frameSourceType << "; Cannot load!"; + throw FrameSourceError(QObject::trUtf8("Unknown frame source “%1”. Cannot load the project.").arg(frameSourceType.toString())); + } + //qDebug() << "loadFrameSource ended"; +} + +Project_sV* XmlProjectRW_sV::loadProject(QString filename, QString *warning) noexcept(false) +{ + QFile file(filename); + if (!file.open(QIODevice::ReadOnly)) { + qDebug() << "Cannot read file " << filename; + throw Error_sV(QObject::tr("Cannot read from file %1. (Opening in read-only mode failed.)").arg(filename)); + } else { + + QXmlStreamReader xml; + xml.setDevice(&file); + if (!xml.readNextStartElement()) { + qDebug() << "Could not read " << filename; + throw Error_sV(QObject::tr("Invalid project file: %1").arg(filename)); + + } else { + if (xml.name() != "sVproject") { + qDebug() << "Invalid project file (incorrect root element): " << filename; + } else { + + int projVersionMajor = xml.attributes().value("version").toString().toInt(); + int projVersionMinor = xml.attributes().value("version_minor").toString().toInt(); + if (projVersionMajor > 0) { + qDebug().nospace() << "Reading project file: version " << projVersionMajor << "." << projVersionMinor; + } else { + qDebug() << "Reading project file of unknown version"; + } + + int version_major = 0, version_minor = 0, version_micro = 0; + + Project_sV *project = new Project_sV(); + project->setProjectFilename(filename); + project->setProjectDir(QFileInfo(filename).absolutePath()); + ProjectPreferences_sV *pr = project->preferences(); + + while (xml.readNextStartElement()) { + if (xml.name() == "info") { + while (xml.readNextStartElement()) { + if (xml.name() == "appName") { + qDebug() << "App name: " << xml.readElementText(); + } else if (xml.name() == "version") { + version_major = xml.attributes().value("major").toString().toInt(); + version_minor = xml.attributes().value("minor").toString().toInt(); + version_micro = xml.attributes().value("micro").toString().toInt(); + xml.skipCurrentElement(); + } else { + xml.skipCurrentElement(); + } + } + } else if (xml.name() == "resources") { + while (xml.readNextStartElement()) { + if (projVersionMajor < 2 && xml.name() == "inputFile") { + QString inFilename = xml.readElementText(); + qDebug() << "Input file: " << inFilename; + project->loadFrameSource(new VideoFrameSource_sV(project, inFilename)); + } else if (xml.name() == "frameSource") { + loadFrameSource(&xml, project); + } else if (xml.name() == "projectDir") { + xml.skipCurrentElement(); + } else { + xml.skipCurrentElement(); + } + } + } else if (xml.name() == "shutterFunctions") { + ShutterFunction_sV func; + while (xml.readNextStartElement()) { + if (xml.name() == "function") { + func.setID(xml.attributes().value("id").toString()); + while (xml.readNextStartElement()) { + if (xml.name() == "code") { + func.updateFunction(xml.readElementText()); + } else { + xml.skipCurrentElement(); + } + } + project->shutterFunctions()->addFunction(func, false); + } else { + xml.skipCurrentElement(); + } + } + } else if (xml.name() == "nodes") { + while (xml.readNextStartElement()) { + if (xml.name() == "node") { + Node_sV node; + while (xml.readNextStartElement()) { + if (xml.name() == "x") { + node.setX(QVariant(xml.readElementText()).toFloat()); + } else if (xml.name() == "y") { + node.setY(QVariant(xml.readElementText()).toFloat()); + } else if (xml.name() == "selected") { + node.select(QVariant(xml.readElementText()).toBool()); + } else if (xml.name() == "shutterFunction") { + node.setShutterFunctionID(xml.readElementText()); + } else if (xml.name() == "leftHandle") { + while (xml.readNextStartElement()) { + QString text = xml.readElementText(); + if (xml.name() == "type") { + node.setLeftCurveType((CurveType)text.toInt()); + } else if (xml.name() == "x") { + node.setLeftNodeHandle(text.toDouble(), node.leftNodeHandle().y()); + } else if (xml.name() == "y") { + node.setLeftNodeHandle(node.leftNodeHandle().x(), text.toDouble()); + } else { + xml.skipCurrentElement(); + } + } + } else if (xml.name() == "rightHandle") { + while (xml.readNextStartElement()) { + QString text = xml.readElementText(); + if (xml.name() == "type") { + node.setRightCurveType((CurveType)text.toInt()); + } else if (xml.name() == "x") { + node.setRightNodeHandle(text.toDouble(), node.rightNodeHandle().y()); + } else if (xml.name() == "y") { + node.setRightNodeHandle(node.rightNodeHandle().x(), text.toDouble()); + } else { + xml.skipCurrentElement(); + } + } + } else { + xml.skipCurrentElement(); + } + } + project->nodes()->add(node); + } else { + xml.skipCurrentElement(); + } + } + } else if (xml.name() == "tags") { + while (xml.readNextStartElement()) { + if (xml.name() == "tag") { + Tag_sV tag; + while (xml.readNextStartElement()) { + if (xml.name() == "time") { + tag.setTime(QVariant(xml.readElementText()).toFloat()); + } else if (xml.name() == "description") { + tag.setDescription(xml.readElementText()); + } else if (xml.name() == "axis") { + tag.setAxis((TagAxis)QVariant(xml.readElementText()).toInt()); + } else { + xml.skipCurrentElement(); + } + } + project->tags()->push_back(tag); + } else { + xml.skipCurrentElement(); + } + } + } else if (xml.name() == "preferences") { + while (xml.readNextStartElement()) { + if (xml.name() == "renderSectionMode") { + pr->renderSectionMode() = xml.attributes().value("mode").toString(); + if (projVersionMajor == 2 && projVersionMinor < 4) { + if (pr->renderSectionMode() == "time") { + pr->renderSectionMode() = "expr"; + } + } + while (xml.readNextStartElement()) { + if (xml.name() == "renderStartTag") { + pr->renderStartTag() = xml.attributes().value("label").toString(); + xml.skipCurrentElement(); + } else if (xml.name() == "renderEndTag") { + pr->renderEndTag() = xml.attributes().value("label").toString(); + xml.skipCurrentElement(); + } else if (xml.name() == "renderStartTime") { + pr->renderStartTime() = xml.attributes().value("time").toString(); + xml.skipCurrentElement(); + } else if (xml.name() == "renderEndTime") { + pr->renderEndTime() = xml.attributes().value("time").toString(); + xml.skipCurrentElement(); + } else { + xml.skipCurrentElement(); + } + } + + } else if (xml.name() == "renderFrameSize") { + pr->renderFrameSize() = (FrameSize) xml.attributes().value("size").toString().toInt(); + xml.skipCurrentElement(); + } else if (xml.name() == "renderInterpolationType") { + pr->renderInterpolationType() = (InterpolationType) xml.attributes().value("type").toString().toInt(); + xml.skipCurrentElement(); + } else if (xml.name() == "renderMotionblurType") { + pr->renderMotionblurType() = (MotionblurType) xml.attributes().value("type").toString().toInt(); + xml.skipCurrentElement(); + } else if (xml.name() == "renderFPS") { + if (projVersionMajor == 2 && projVersionMinor <= 2) { + pr->renderFPS() = xml.attributes().value("fps").toString().toFloat(); + } else { + pr->renderFPS() = xml.attributes().value("fps").toString(); + } + xml.skipCurrentElement(); + + } else if (xml.name() == "renderSlowmoSamples") { + project->motionBlur()->setSlowmoSamples(xml.attributes().value("number").toString().toInt()); + xml.skipCurrentElement(); + } else if (xml.name() == "renderMaxSamples") { + project->motionBlur()->setMaxSamples(xml.attributes().value("number").toString().toInt()); + xml.skipCurrentElement(); + + } else if (xml.name() == "renderTarget") { + pr->renderTarget() = xml.attributes().value("target").toString(); + xml.skipCurrentElement(); + + } else if (xml.name() == "imagesOutputDir") { + pr->imagesOutputDir() = xml.attributes().value("dir").toString(); + xml.skipCurrentElement(); + } else if (xml.name() == "imagesFilenamePattern") { + pr->imagesFilenamePattern() = xml.attributes().value("pattern").toString(); + xml.skipCurrentElement(); + } else if (xml.name() == "videoFilename") { + QString filename = xml.attributes().value("file").toString(); + if (!filename.isEmpty()) { + pr->videoFilename() = filename; + } + xml.skipCurrentElement(); + } else if (xml.name() == "videoCodec") { + pr->videoCodec() = xml.attributes().value("codec").toString(); + xml.skipCurrentElement(); + + } else if (xml.name() == "flowV3dLambda") { + pr->flowV3DLambda() = xml.attributes().value("lambda").toString().toFloat(); + xml.skipCurrentElement(); + + } else if (xml.name() == "prevTagAxis") { + pr->lastSelectedTagAxis() = (TagAxis)xml.attributes().value("axis").toString().toInt(); + xml.skipCurrentElement(); + } else if (xml.name() == "viewport_t0") { + pr->viewport_t0().rx() = xml.attributes().value("x").toString().toFloat(); + pr->viewport_t0().ry() = xml.attributes().value("y").toString().toFloat(); + xml.skipCurrentElement(); + } else if (xml.name() == "viewport_secRes") { + pr->viewport_secRes().rx() = xml.attributes().value("x").toString().toFloat(); + pr->viewport_secRes().ry() = xml.attributes().value("y").toString().toFloat(); + xml.skipCurrentElement(); + + } else if (xml.name() == "canvas_xAxisFPS") { + pr->canvas_xAxisFPS() = xml.attributes().value("fps").toString(); + xml.skipCurrentElement(); + } + + + else { + xml.skipCurrentElement(); + } + } + } else { + qDebug() << "Unknown element: " << xml.name(); + xml.skipCurrentElement(); + } + } + xml.readNextStartElement(); + if (xml.name().length() > 0) { + qDebug() << "Did not read the whole project file! Stopped at: " << xml.name(); + } + Q_ASSERT(xml.name().length() == 0); + + + file.close(); + + + // Handle new project versions + if (projVersionMajor > SLOWMOPROJECT_VERSION_MAJOR && projVersionMajor) { + throw Error_sV(QString("This file has been created with slowmoVideo %1.%2.%3 which uses a newer " + "project file version (%4.%5; supported: %6.%7). File cannot be loaded " + "(or only partially). Please upgrade to a newer version of slowmoVideo.") + .arg(version_major).arg(version_minor).arg(version_micro) + .arg(projVersionMajor).arg(projVersionMinor) + .arg(SLOWMOPROJECT_VERSION_MAJOR).arg(SLOWMOPROJECT_VERSION_MINOR)); + } else if (projVersionMinor > SLOWMOPROJECT_VERSION_MINOR) { + QString warningMsg = QString("This file has been created with a slightly newer version of slowmoVideo " + "(version %1.%2.%3) which uses project file version %4.%5 (supported: %6.%7). " + "When saving this project, some added properties will be lost.") + .arg(version_major).arg(version_minor).arg(version_micro) + .arg(projVersionMajor).arg(projVersionMinor) + .arg(SLOWMOPROJECT_VERSION_MAJOR).arg(SLOWMOPROJECT_VERSION_MINOR); + qDebug() << warningMsg; + if (warning != NULL) { + *warning = warningMsg; + } + } + + return project; + + } + } + file.close(); + } + return NULL; +}
View file
slowmoVideo-0.6.tar.xz/src/project/xmlProjectRW_sV.h
Added
@@ -0,0 +1,62 @@ +/* +This file is part of slowmoVideo. +Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +*/ + +#ifndef XMLPROJECTRW_SV_H +#define XMLPROJECTRW_SV_H + +#include "../lib/defs_sV.hpp" +#include "tag_sV.h" + +#include <QtXml> + +class Node_sV; +class Project_sV; +class AbstractFrameSource_sV; + +// Remember to change the slowmoVideo version as well +#define SLOWMOPROJECT_VERSION_MAJOR 2 +#define SLOWMOPROJECT_VERSION_MINOR 7 + +/** + \brief Reads and writes project files in XML format + + Additional stored parameters require a minor version change. + Big changes in the schema, like elements moved to a different node, require + a major version change and a function that loads old project files. + + Version changes (both major and minor) require a micro slowmoVideo version change. + */ +class XmlProjectRW_sV +{ +public: + /** + \fn loadProject() + Reads an XML project file. + \param filename Project file to load + \param warning Information message when trying to load project files with a wrong version number + \return NULL if an error ocurred. + */ + /** + \fn saveProject() + Saves a project to an XML project file. + */ + + static Project_sV* loadProject(QString filename, QString *warning = NULL) noexcept(false); + static int saveProject(Project_sV *project, QString filename) noexcept(false); + +private: + static const QDomElement nodeToDom(QDomDocument *doc, const Node_sV *node); + static const QDomElement tagToDom(QDomDocument *doc, const Tag_sV &tag); + + static const QDomElement frameSource(QDomDocument *doc, const AbstractFrameSource_sV *frameSource); + static void loadFrameSource(QXmlStreamReader *reader, Project_sV *project) noexcept(false); +}; + +#endif // XMLPROJECTRW_SV_H
View file
slowmoVideo-0.6.tar.xz/src/slowmoCLI
Added
+(directory)
View file
slowmoVideo-0.6.tar.xz/src/slowmoCLI/CMakeLists.txt
Added
@@ -0,0 +1,20 @@ + + +set(SOURCES_MAIN + main.cpp +) + +#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99") + +set(SOURCES_VINFO + videoInfo.cpp +) + +add_executable(slowmoInterpolate ${SOURCES_MAIN}) +target_link_libraries(slowmoInterpolate sV sVflow ) + +add_executable(slowmoVideoInfo ${SOURCES_VINFO}) +target_link_libraries(slowmoVideoInfo sVinfo sV ) + +install(TARGETS slowmoInterpolate DESTINATION ${DEST}) +install(TARGETS slowmoVideoInfo DESTINATION ${DEST})
View file
slowmoVideo-0.6.tar.xz/src/slowmoCLI/main.cpp
Added
@@ -0,0 +1,209 @@ +/* +slowmoCLI is a command-line interface for slowmoVideo. +Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +*/ + +#include "../lib/interpolate_sV.h" +#include "flowField_sV.h" +#include "flowRW_sV.h" + +#include <iostream> +#include <cmath> + +#include <QString> + +#include <QImage> +#include <QColor> +#include <QRgb> + +#include <QDebug> + + + +const int RET_MISSING_PARAM = -1; +const int RET_WRONG_PARAM = -2; +const int RET_MISSING_FILE = -3; +const int RET_SIZE_DIFFERS = -4; + + +char *myName; + +enum FlowMode { + FlowMode_Forward, + FlowMode_Twoway, + FlowMode_Undef +}; + + +void printUsage() { + std::cout << "Usage: " << std::endl; + std::cout << "\t" << myName << " twoway <left image> <right image> <flow image> <reverse image> <output pattern> numberOffset fps " << std::endl; + std::cout << "\t" << myName << " forward <left image> <flow image> <output pattern> numberOffset fps " << std::endl; +} + + +char* nextArg(int argc, int &argi, char *argv) +{ + argi++; + if (argi < argc) { + std::cout << "Arg: " << argvargi << std::endl; + return argvargi; + } else { + std::cout << "Argument " << argi << " missing." << std::endl; + printUsage(); + exit(RET_MISSING_PARAM); + } +} + +const char* nextOptArg(int argc, int &argi, char *argv, const char defaultParam) +{ + argi++; + if (argi < argc) { + std::cout << "Optional argument: " << argvargi << std::endl; + return argvargi; + } else { + std::cout << "Optional argument " << argi << " not given." << std::endl; + return defaultParam; + } +} + + +int main(int argc, char *argv) +{ + myName = argv0; + + + int argi = 0; + char *arg; + + + FlowMode mode = FlowMode_Undef; + + arg = nextArg(argc, argi, argv); + if (strcmp("forward", arg) == 0) { + mode = FlowMode_Forward; + } else if (strcmp("twoway", arg) == 0) { + mode = FlowMode_Twoway; + } + + if (mode == FlowMode_Undef) { + printUsage(); + exit(RET_WRONG_PARAM); + } + + + QImage left, right, output; + FlowField_sV *ffForward, *ffBackward; + + switch (mode) { + case FlowMode_Twoway: + std::cout << "Running two-way flow." << std::endl; + left = QImage(nextArg(argc, argi, argv)); + right = QImage(nextArg(argc, argi, argv)); + ffForward = FlowRW_sV::load(nextArg(argc, argi, argv)); + ffBackward = FlowRW_sV::load(nextArg(argc, argi, argv)); + break; + case FlowMode_Forward: + std::cout << "Running forward flow." << std::endl; + left = QImage(nextArg(argc, argi, argv)); + ffForward = FlowRW_sV::load(nextArg(argc, argi, argv)); + break; + case FlowMode_Undef: + Q_ASSERT(false); + break; + } + QString pattern(nextOptArg(argc, argi, argv, "output%1.png")); + if (!pattern.contains("%1")) { + std::cout << "Error: Output pattern must contain a %1 for the image number. Example: output%1.png." << std::endl; + return RET_WRONG_PARAM; + } + bool ok; + int numberOffset = QString(nextOptArg(argc, argi, argv, "0")).toInt(&ok); + if (!ok) { + std::cout << "Error converting argument to number." << std::endl; + return RET_WRONG_PARAM; + } + const unsigned int fps = QString(nextOptArg(argc, argi, argv, "24")).toInt(&ok); + if (!ok) { + std::cout << "Error converting argument to number." << std::endl; + return RET_WRONG_PARAM; + } + + + + switch (mode) { + case FlowMode_Twoway: + if (ffBackward == NULL) { + std::cout << "Backward flow is not valid." << std::endl; + exit(RET_MISSING_FILE); + } + if (right.isNull()) { + std::cout << "Right image does not exist." << std::endl; + exit(RET_MISSING_FILE); + } + if (ffBackward->width() != left.width() || ffBackward->height() != left.height()) { + qDebug() << "Invalid backward flow field size. Image is " << left.width() + << ", flow is " << ffBackward->width() << "x" << ffBackward->height() << "."; + exit(RET_SIZE_DIFFERS); + } + // Fall through + case FlowMode_Forward: + if (left.isNull()) { + std::cout << "Left image does not exist." << std::endl; + exit(RET_MISSING_FILE); + } + if (ffForward == NULL) { + std::cout << "Forward flow is not valid." << std::endl; + exit(RET_MISSING_FILE); + } + if (left.size() != right.size()) { + qDebug() << "Left image size differs from right image size: " << left.size() << " vs. " << right.size() << "."; + } + if (ffForward->width() != left.width() || ffForward->height() != left.height()) { + qDebug() << "Invalid forward flow field size. Image is " << left.width() + << ", flow is " << ffForward->width() << "x" << ffForward->height() << "."; + exit(RET_SIZE_DIFFERS); + } + break; + case FlowMode_Undef: + qDebug() << "Undefined flow mode selected."; + break; + } + + + + output = QImage(left.size(), QImage::Format_RGB32); + + + + + + //const int stepLog = ceil(log10(numberOffset + steps)); + const int stepLog = 8; + float pos; + const QChar fillChar = QLatin1Char('0'); + qDebug() << stepLog << ": max length"; + QString filename; + + for (unsigned int step = 0; step < fps+1; step++) { + pos = step/float(fps); + if (mode == FlowMode_Twoway) { + Interpolate_sV::twowayFlow(left, right, ffForward, ffBackward, pos, output); + } else if (mode == FlowMode_Forward) { + Interpolate_sV::forwardFlow(left, ffForward, pos, output); + } + filename = pattern.arg(QString::number(numberOffset + step), stepLog, fillChar); + qDebug() << "Saving position " << pos << " to image " << filename; + output.save(filename); + } + + delete ffForward; + if (mode == FlowMode_Twoway) { + delete ffBackward; + } +}
View file
slowmoVideo-0.6.tar.xz/src/slowmoCLI/videoInfo.cpp
Added
@@ -0,0 +1,21 @@ + +#include <cstdio> +#include <cstring> + +#include "../lib/videoInfo_sV.h" + +void printUsage(const char progName) +{ + printf("Displays information like frame rate of a video file. \nUsage: %s file\n", progName); +} + +int main(int argc, char *argv) +{ + if (argc < 2 || strcmp("-h", argv1) == 0) { + printUsage(argv0); + return -1; + } + getInfo(argv1); + return 0; + +}
View file
slowmoVideo-0.6.tar.xz/src/slowmoFlowEdit
Added
+(directory)
View file
slowmoVideo-0.6.tar.xz/src/slowmoFlowEdit/CMakeLists.txt
Added
@@ -0,0 +1,63 @@ + +include_directories(${slowmoVideo_SOURCE_DIR}) + +set(SRCS + main.cpp + mainwindow.cpp + flowEditCanvas.cpp + shortcutListDialog.cpp +) + +if(APPLE) + set(BUNDLE "slowmoFlowEdit") + set(ICONS_DIR "${${PROJECT_NAME}_SOURCE_DIR}/slowmoVideo/slowmoUI/res") + message( "OS X build" ) + set(MACOSX_BUNDLE_INFO_STRING "${BUNDLE} ${PROJECT_VERSION}") + set(MACOSX_BUNDLE_BUNDLE_VERSION "${BUNDLE} ${PROJECT_VERSION}") + set(MACOSX_BUNDLE_LONG_VERSION_STRING "${BUNDLE} ${PROJECT_VERSION}") + set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${PROJECT_VERSION}") + set(MACOSX_BUNDLE_COPYRIGHT "${PROJECT_COPYRIGHT_YEAR} ${PROJECT_VENDOR}") + set(MACOSX_BUNDLE_ICON_FILE "slowmoUI.icns") + set(MACOSX_BUNDLE_GUI_IDENTIFIER "${PROJECT_DOMAIN_SECOND}.${PROJECT_DOMAIN_FIRST}") + set(MACOSX_BUNDLE_BUNDLE_NAME "${BUNDLE}") + + set(MACOSX_BUNDLE_RESOURCES "${CMAKE_CURRENT_BINARY_DIR}/${BUNDLE}.app/Contents/Resources") + set(MACOSX_BUNDLE_ICON "${ICONS_DIR}/${MACOSX_BUNDLE_ICON_FILE}") + SET_SOURCE_FILES_PROPERTIES( + ${MACOSX_BUNDLE_ICON} + PROPERTIES MACOSX_PACKAGE_LOCATION Resources) + message(STATUS "Bundle will be : ${MACOSX_BUNDLE} => ${PROJECT_NAME} ") + + set( SRCS ${SRCS} ${MACOSX_BUNDLE_ICON} ) + +endif() + +include_directories(..) +include_directories(${CMAKE_BINARY_DIR}/slowmoVideo/slowmoFlowEdit) +include_directories(${CMAKE_BINARY_DIR}/slowmoVideo/libgui) + +add_executable(slowmoFlowEdit WIN32 MACOSX_BUNDLE ${SRCS}) +qt5_use_modules(slowmoFlowEdit Widgets Gui Core ) +target_link_libraries(slowmoFlowEdit sVgui sVflow sVvis sVflowtools) + +#install(TARGETS slowmoFlowEdit +# BUNDLE DESTINATION . COMPONENT Runtime +# RUNTIME DESTINATION ${DEST} COMPONENT Runtime) + + #install(TARGETS slowmoUI DESTINATION ".") + #install(TARGETS slowmoFlowEdit DESTINATION ${DEST}) + +include(DeployQt5) # 2.8.7 or later + + +if (APPLE) + install(TARGETS slowmoFlowEdit DESTINATION ".") + install_qt5_executable(slowmoFlowEdit.app "" "" ) +elseif(WIN32) + install(TARGETS slowmoFlowEdit DESTINATION ".") + install_qt5_executable(slowmoFlowEdit.exe "" "" ) +else() + install(TARGETS slowmoFlowEdit DESTINATION ${DEST}) +# install_qt5_executable(slowmoFlowEdit "" "" ) +endif() +
View file
slowmoVideo-0.6.tar.xz/src/slowmoFlowEdit/flowEditCanvas.cpp
Added
@@ -0,0 +1,158 @@ +/* +slowmoFlowEdit is a user interface for editing slowmoVideo's Optical Flow files. +Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +*/ + +#include "flowEditCanvas.h" +#include "ui_flowEditCanvas.h" + +#include "flowRW_sV.h" +#include "lib/flowTools_sV.h" +#include "lib/flowVisualization_sV.h" + +#include <QtCore> +#include <QObject> +#include <QtCore/QDebug> +#include <QtWidgets> + +FlowEditCanvas::FlowEditCanvas(QWidget *parent) : + QWidget(parent), + ui(new Ui::FlowEditCanvas), + m_flowField(NULL), + m_boost(1.0) +{ + ui->setupUi(this); + + ui->flow->trackMouse(true); + + connect(ui->flow, SIGNAL(signalRectDrawn(QRectF)), this, SLOT(slotRectDrawn(QRectF))); + connect(ui->flow, SIGNAL(signalMouseMoved(float,float)), this, SLOT(slotExamineValues(float,float))); + connect(ui->flow, SIGNAL(signalMousePressed(float,float)), this,SLOT(slotPickValues(float,float))); + connect(ui->amplification, SIGNAL(valueChanged(int)),this, SLOT(newAmplification(int))); + + tool= 0; + vx = 0.0; + vy = 0.0; + ui->average->setChecked(true); +} + +FlowEditCanvas::~FlowEditCanvas() +{ + delete ui; +} + +float FlowEditCanvas::amplification() const +{ + return m_boost; +} + +void FlowEditCanvas::setAmplification(float val) +{ + //qDebug() << "setAmplification: " << val; + Q_ASSERT(val > 0); + m_boost = val; + repaintFlow(); +} + +void FlowEditCanvas::newAmplification(int val) +{ + //qDebug() << "newAmplification: " << val; + Q_ASSERT(val > 0); + m_boost = (float)val; + repaintFlow(); +} + +/// \todo Make flow visualization configurable +void FlowEditCanvas::repaintFlow() +{ + if (m_flowField != NULL) { + ui->flow->loadImage(FlowVisualization_sV::colourizeFlow(m_flowField, FlowVisualization_sV::HSV, m_boost)); + repaint(); + } +} + +void FlowEditCanvas::slotRectDrawn(QRectF imageRect) +{ + qDebug() << "Rect drawn: " << imageRect; + if (m_flowField != NULL) { + //TODO: ugly code + if (ui->average->isChecked() ) { + // average + qDebug() << "average"; + Kernel_sV k(8, 8); + k.gauss(); + FlowTools_sV::deleteRect(*m_flowField, + imageRect.top(), imageRect.left(), + imageRect.bottom(), imageRect.right()); + FlowTools_sV::refill(*m_flowField, k, + imageRect.top(), imageRect.left(), + imageRect.bottom(), imageRect.right()); + } + if (ui->picker->isChecked() ) { + qDebug() << "paint" << vx << " , " << vy; + FlowTools_sV::fillRect(*m_flowField, + imageRect.top(), imageRect.left(), + imageRect.bottom(), imageRect.right(), vx, vy); + } + + + repaintFlow(); + } +} + +void FlowEditCanvas::slotLoadFlow(QString filename) +{ + if (m_flowField != NULL) { + delete m_flowField; + m_flowField = NULL; + } + m_flowField = FlowRW_sV::load(filename.toStdString()); + m_flowFilename = filename; + + repaintFlow(); +} + +void FlowEditCanvas::slotSaveFlow(QString filename) +{ + if (m_flowField != NULL) { + if (filename.length() == 0) { + filename = m_flowFilename; + } + FlowRW_sV::save(filename.toStdString(), m_flowField); + } else { + qDebug() << "No flow file loaded, cannot save."; + } +} + +void FlowEditCanvas::slotExamineValues(float x, float y) +{ + if (m_flowField != NULL) { + if (x >= 0 && y >= 0 + && x <= m_flowField->width()-1 && y <= m_flowField->height()-1) { + float dx = m_flowField->x(x,y); + float dy = m_flowField->y(x,y); + ui->lblValues->setText(QString("dx/dy: (%1|%2)").arg(dx, 0, 'f', 2).arg(dy, 0, 'f', 2)); + ui->lblPos->setText(QString("(%1|%2)").arg(x).arg(y)); + } + } +} + +void FlowEditCanvas::slotPickValues(float x, float y) +{ + if (ui->eyedropper->isChecked()) { + qDebug() << "pick value"; + if (m_flowField != NULL) { + if (x >= 0 && y >= 0 + && x <= m_flowField->width()-1 && y <= m_flowField->height()-1) { + vx = m_flowField->x(x,y); + vy = m_flowField->y(x,y); + qDebug() << "will fill with : " << vx << " , " << vy; + } + } + } +} \ No newline at end of file
View file
slowmoVideo-0.6.tar.xz/src/slowmoFlowEdit/flowEditCanvas.h
Added
@@ -0,0 +1,58 @@ +/* +slowmoFlowEdit is a user interface for editing slowmoVideo's Optical Flow files. +Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +*/ + +#ifndef FLOWEDITCANVAS_H +#define FLOWEDITCANVAS_H + +#include <QWidget> +#include <QtCore/QRectF> + +class FlowField_sV; +namespace Ui { + class FlowEditCanvas; +} + +/// \todo Auto-fix feature (confirm to accept) +class FlowEditCanvas : public QWidget +{ + Q_OBJECT + +public: + explicit FlowEditCanvas(QWidget *parent = 0); + ~FlowEditCanvas(); + + void setAmplification(float val); + float amplification() const; + + +public slots: + void slotLoadFlow(QString filename); + void slotSaveFlow(QString filename = QString()); + void newAmplification(int val); + +private: + Ui::FlowEditCanvas *ui; + + FlowField_sV *m_flowField; + QString m_flowFilename; + float m_boost; + + float vx,vy; + + int tool; + void repaintFlow(); + +private slots: + void slotRectDrawn(QRectF imageRect); + void slotExamineValues(float x, float y); + void slotPickValues(float x, float y); +}; + +#endif // FLOWEDITCANVAS_H
View file
slowmoVideo-0.6.tar.xz/src/slowmoFlowEdit/flowEditCanvas.ui
Added
@@ -0,0 +1,199 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>FlowEditCanvas</class> + <widget class="QWidget" name="FlowEditCanvas"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>1058</width> + <height>608</height> + </rect> + </property> + <property name="windowTitle"> + <string notr="true">Form</string> + </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="2" column="0"> + <layout class="QHBoxLayout" name="horizontalLayout"> + <property name="sizeConstraint"> + <enum>QLayout::SetMinimumSize</enum> + </property> + <item> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QLabel" name="lblPos"> + <property name="text"> + <string notr="true">TextLabel</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_2"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>10</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QLabel" name="lblValues"> + <property name="text"> + <string>Values at mouse position</string> + </property> + </widget> + </item> + </layout> + </item> + <item row="0" column="0"> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <item> + <widget class="ImageDisplay" name="flow"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="frameShape"> + <enum>QFrame::StyledPanel</enum> + </property> + <property name="frameShadow"> + <enum>QFrame::Raised</enum> + </property> + </widget> + </item> + <item> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QSlider" name="amplification"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Expanding"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="maximum"> + <number>20</number> + </property> + <property name="sliderPosition"> + <number>3</number> + </property> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="tickPosition"> + <enum>QSlider::TicksBelow</enum> + </property> + <property name="tickInterval"> + <number>1</number> + </property> + </widget> + </item> + <item> + <spacer name="verticalSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QGroupBox" name="groupBox"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Expanding"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="title"> + <string>tool</string> + </property> + <widget class="QRadioButton" name="eyedropper"> + <property name="geometry"> + <rect> + <x>0</x> + <y>20</y> + <width>89</width> + <height>22</height> + </rect> + </property> + <property name="text"> + <string>Eyedropper</string> + </property> + </widget> + <widget class="QRadioButton" name="picker"> + <property name="geometry"> + <rect> + <x>0</x> + <y>60</y> + <width>89</width> + <height>22</height> + </rect> + </property> + <property name="text"> + <string>picker</string> + </property> + </widget> + <widget class="QRadioButton" name="average"> + <property name="geometry"> + <rect> + <x>0</x> + <y>40</y> + <width>89</width> + <height>22</height> + </rect> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>average</string> + </property> + </widget> + </widget> + </item> + </layout> + </item> + </layout> + </item> + </layout> + </widget> + <customwidgets> + <customwidget> + <class>ImageDisplay</class> + <extends>QFrame</extends> + <header>libgui/imageDisplay.h</header> + <container>1</container> + </customwidget> + </customwidgets> + <resources/> + <connections/> +</ui>
View file
slowmoVideo-0.6.tar.xz/src/slowmoFlowEdit/main.cpp
Added
@@ -0,0 +1,29 @@ +/* +slowmoFlowEdit is a user interface for editing slowmoVideo's Optical Flow files. +Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +*/ + +#include <QApplication> +#include "mainwindow.h" + +int main(int argc, char *argv) +{ + QApplication a(argc, argv); + + // Set up preferences for the QSettings file + QCoreApplication::setOrganizationName("Granjow"); + QCoreApplication::setOrganizationDomain("granjow.net"); + QCoreApplication::setApplicationName("slowmoFlowEdit"); + + MainWindow w; + + w.show(); + + return a.exec(); +} +
View file
slowmoVideo-0.6.tar.xz/src/slowmoFlowEdit/mainwindow.cpp
Added
@@ -0,0 +1,253 @@ +/* +slowmoFlowEdit is a user interface for editing slowmoVideo's Optical Flow files. +Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +*/ + +#include "mainwindow.h" +#include "ui_mainwindow.h" + + +#include <QtCore> +#include <QObject> +#include <QMainWindow> +#include <QtWidgets> +#include <QSettings> + +#include <QtCore/QDebug> +#include <QFileDialog> +#include <QMessageBox> + +#include "flowEditCanvas.h" +#include "shortcutListDialog.h" + +#define MAX_SEARCH_SHIFT 500 + +MainWindow::MainWindow(QWidget *parent) : + QMainWindow(parent), + ui(new Ui::MainWindow), + m_cs(this) +{ + ui->setupUi(this); + + restoreGeometry(m_settings.value("geometry").toByteArray()); + restoreState(m_settings.value("windowState").toByteArray()); + + m_canvas = new FlowEditCanvas(this); + setCentralWidget(m_canvas); + m_canvas->setAmplification(m_settings.value("view/amplify", 1.0).toFloat()); + + m_cs.addShortcut("o", OPEN, "Open flow file"); + m_cs.addShortcut("s-s", SAVE, "Save"); + m_cs.addShortcut("j", PREV, "Previous file"); + m_cs.addShortcut("k", NEXT, "Next file"); + //m_cs.addShortcut("b-1", BOOST1, "No amplification"); + //m_cs.addShortcut("b-2", BOOST2, "Low amplification"); + //m_cs.addShortcut("b-3", BOOST3, "High amplification (details best visible)"); + m_cs.addShortcut("q-q", QUIT, "Quit"); + m_cs.addShortcut("h-h", HELP, "Show shortcut dialog"); + + ui->actionQuit->setShortcut(QKeySequence("Ctrl+Q")); + ui->actionOpen->setShortcut(QKeySequence("Ctrl+O")); + ui->actionSave->setShortcut(QKeySequence("Ctrl+S")); + ui->actionPrev->setShortcut(QKeySequence("Ctrl+Left")); + ui->actionNext->setShortcut(QKeySequence("Ctrl+Right")); + ui->actionShortcuts->setShortcut(QKeySequence("F1")); + + connect(ui->actionQuit, SIGNAL(triggered()), this, SLOT(close())); + connect(ui->actionOpen, SIGNAL(triggered()), this, SLOT(slotOpenFlow())); + connect(ui->actionSave, SIGNAL(triggered()), this, SLOT(slotSaveFlow())); + connect(ui->actionNext, SIGNAL(triggered()), this, SLOT(slotNextFile())); + connect(ui->actionPrev, SIGNAL(triggered()), this, SLOT(slotPrevFile())); + connect(ui->actionShortcuts, SIGNAL(triggered()), this, SLOT(slotShowShortcuts())); + connect(&m_cs, SIGNAL(signalShortcutUsed(int)), this, SLOT(slotShortcutUsed(int))); + + + updateTitle(); + if (m_settings.value("prevFlowFile", "").toString().length() != 0) { + loadFlow(m_settings.value("prevFlowFile", "").toString()); + } + + qDebug() << "Shortcut list: " << m_cs.shortcutList(); +} + +MainWindow::~MainWindow() +{ + delete ui; +} + +const CombinedShortcuts& MainWindow::shortcuts() const +{ + return m_cs; +} + +void MainWindow::updateTitle() +{ + QString file = m_lastFlowFile; + if (file.length() == 0) { + file = "no file loaded"; + } + setWindowTitle(QString("slowmo Flow Editor (%1)").arg(file)); +} + +void MainWindow::closeEvent(QCloseEvent *e) +{ + m_settings.setValue("geometry", saveGeometry()); + m_settings.setValue("windowState", saveState()); + if (m_lastFlowFile.length() > 0) { + m_settings.setValue("prevFlowFile", m_lastFlowFile); + } + m_settings.setValue("view/amplify", m_canvas->amplification()); + QMainWindow::closeEvent(e); +} + +QString MainWindow::nextFilename(QString originalName, int shift) const +{ + if (false) { + QStringList parts; + QRegExp e("(\\d+)"); + int min = originalName.indexOf("_"); + int pos = 0; + int prevPos = 0; + while ((pos = e.indexIn(originalName, pos)) != -1) { + parts << originalName.mid(prevPos, pos-prevPos); + + if (pos > min) { + parts << QVariant(e.cap(1).toInt()+shift).toString(); + } else { + parts << e.cap(1); + } + + pos += e.matchedLength(); + prevPos = pos; + } + parts << originalName.mid(prevPos); + return parts.join(""); + } else { + QStringList filters; + filters << "*.sVflow"; + + QDir dir(QFileInfo(originalName).absolutePath()); + QStringList filenames = dir.entryList(filters, QDir::Files | QDir::Readable, QDir::Name); + + QString current = QFileInfo(originalName).fileName(); + QString next; + if (filenames.contains(current)) { + int index = filenames.indexOf(current); + if (filenames.size() > index+shift && index+shift >= 0) { + next = QFileInfo(originalName).absolutePath() + "/" + filenamesindex+shift; + } else { + qDebug() << "No file in this direction"; + } + } else { + qDebug() << filenames; + } + + return next; + } +} + +void MainWindow::loadFlow(QString filename) +{ + if (QFileInfo(filename).exists()) { + m_canvas->slotLoadFlow(filename); + m_lastFlowFile = filename; + updateTitle(); + } +} + +void MainWindow::slotOpenFlow() +{ + QFileDialog dialog(this, "Open flow file"); + dialog.setAcceptMode(QFileDialog::AcceptOpen); + dialog.setFileMode(QFileDialog::ExistingFile); + dialog.setNameFilter("Flow files (*.sVflow)"); + if (m_settings.value("directories/lastFlowDir", "").toString().length() > 0) { + dialog.setDirectory(m_settings.value("directories/lastFlowDir", "").toString()); + } + if (dialog.exec() == QDialog::Accepted) { + m_settings.setValue("directories/lastFlowDir", QFileInfo(dialog.selectedFiles().at(0)).absolutePath()); + loadFlow(dialog.selectedFiles().at(0)); + statusBar()->showMessage("Loaded " + m_lastFlowFile, 3000); + } +} + +void MainWindow::slotSaveFlow() +{ + statusBar()->showMessage("Saving ...", 3000); + m_canvas->slotSaveFlow(); + statusBar()->showMessage("Saved " + m_lastFlowFile, 3000); +} + +void MainWindow::slotNextFile() +{ + slotChangeFile(+1); +} + +void MainWindow::slotPrevFile() +{ + slotChangeFile(-1); +} + +void MainWindow::slotChangeFile(int shift) +{ + for (int i = 1; i < MAX_SEARCH_SHIFT; i++) { + QString name = nextFilename(m_lastFlowFile, i*shift); + if (QFileInfo(name).exists()) { + loadFlow(name); + return; + } + } + QMessageBox::warning(this, "File not found", QString("The flow file %1 does not exist.\n\n " + "I even searched %2 steps for a file in this direction, " + "and still did not find a file.") + .arg(nextFilename(m_lastFlowFile, shift)).arg(MAX_SEARCH_SHIFT), QMessageBox::Ok); +} + +void MainWindow::amplify(float val) +{ + m_canvas->setAmplification(val); + statusBar()->showMessage(QString("Setting visual amplification to %1").arg(val), 3000); +} + +void MainWindow::slotShortcutUsed(int id) +{ +/* + if (id == BOOST1) { + qDebug() << "Amplify 1"; + amplify(1); + } else if (id == BOOST2) { + qDebug() << "Amplify 2"; + amplify(3); + } else if (id == BOOST3) { + qDebug() << "Amplify 3"; + amplify(9); + } else + */ + if (id == PREV) { + slotPrevFile(); + } else if (id == NEXT) { + slotNextFile(); + } else if (id == OPEN) { + slotOpenFlow(); + } else if (id == SAVE) { + slotSaveFlow(); + } else if (id == HELP) { + slotShowShortcuts(); + } else if (id == QUIT) { + close(); + } else { + qDebug() << "Shortcut with ID " << id << " has no action!"; + Q_ASSERT(false); + } +} + +void MainWindow::slotShowShortcuts() +{ + ShortcutListDialog dialog(this); + dialog.exec(); +}
View file
slowmoVideo-0.6.tar.xz/src/slowmoFlowEdit/mainwindow.h
Added
@@ -0,0 +1,72 @@ +/* +slowmoFlowEdit is a user interface for editing slowmoVideo's Optical Flow files. +Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +*/ + +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +class FlowEditCanvas; +namespace Ui { + class MainWindow; +} + + +#include <QMainWindow> +#include <QtWidgets> +#include <QSettings> + +#include "../libgui/combinedShortcuts.h" + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + explicit MainWindow(QWidget *parent = 0); + ~MainWindow(); + + const CombinedShortcuts& shortcuts() const; + +protected slots: + void closeEvent(QCloseEvent *e); + +private: + enum Shortcuts { + BOOST1, BOOST2, BOOST3, OPEN, SAVE, PREV, NEXT, HELP, QUIT + }; + + Ui::MainWindow *ui; + CombinedShortcuts m_cs; + + FlowEditCanvas *m_canvas; + + QSettings m_settings; + QString m_lastFlowFile; + + void updateTitle(); + void loadFlow(QString filename); + + void amplify(float val); + + QString nextFilename(QString originalName, int shift) const; + + +private slots: + void slotOpenFlow(); + void slotSaveFlow(); + + void slotNextFile(); + void slotPrevFile(); + void slotChangeFile(int shift); + + void slotShortcutUsed(int id); + void slotShowShortcuts(); +}; + +#endif // MAINWINDOW_H
View file
slowmoVideo-0.6.tar.xz/src/slowmoFlowEdit/mainwindow.ui
Added
@@ -0,0 +1,92 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>MainWindow</class> + <widget class="QMainWindow" name="MainWindow"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>800</width> + <height>600</height> + </rect> + </property> + <property name="windowTitle"> + <string>slowmo Flow Editor</string> + </property> + <widget class="QWidget" name="centralwidget"/> + <widget class="QMenuBar" name="menubar"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>800</width> + <height>22</height> + </rect> + </property> + <widget class="QMenu" name="menuFile"> + <property name="title"> + <string>File</string> + </property> + <addaction name="actionOpen"/> + <addaction name="actionSave"/> + <addaction name="separator"/> + <addaction name="actionPrev"/> + <addaction name="actionNext"/> + <addaction name="separator"/> + <addaction name="actionQuit"/> + </widget> + <widget class="QMenu" name="menuHelp"> + <property name="title"> + <string>Help</string> + </property> + <addaction name="actionShortcuts"/> + </widget> + <addaction name="menuFile"/> + <addaction name="menuHelp"/> + </widget> + <widget class="QStatusBar" name="statusbar"/> + <action name="actionOpen"> + <property name="text"> + <string>Open</string> + </property> + </action> + <action name="actionSave"> + <property name="text"> + <string>Save</string> + </property> + </action> + <action name="actionQuit"> + <property name="text"> + <string>Quit</string> + </property> + <property name="menuRole"> + <enum>QAction::QuitRole</enum> + </property> + </action> + <action name="actionNext"> + <property name="text"> + <string>Next file</string> + </property> + </action> + <action name="actionPrev"> + <property name="text"> + <string>Previous file</string> + </property> + </action> + <action name="actionAmplify"> + <property name="checkable"> + <bool>true</bool> + </property> + <property name="text"> + <string>Amplify colours</string> + </property> + </action> + <action name="actionShortcuts"> + <property name="text"> + <string>Shortcuts</string> + </property> + </action> + </widget> + <resources/> + <connections/> +</ui>
View file
slowmoVideo-0.6.tar.xz/src/slowmoFlowEdit/shortcutListDialog.cpp
Changed
(renamed from src/slowmoVideo/slowmoFlowEdit/shortcutListDialog.cpp)
View file
slowmoVideo-0.6.tar.xz/src/slowmoFlowEdit/shortcutListDialog.h
Changed
(renamed from src/slowmoVideo/slowmoFlowEdit/shortcutListDialog.h)
View file
slowmoVideo-0.6.tar.xz/src/slowmoFlowEdit/shortcutListDialog.ui
Changed
(renamed from src/slowmoVideo/slowmoFlowEdit/shortcutListDialog.ui)
View file
slowmoVideo-0.6.tar.xz/src/slowmoRenderer
Added
+(directory)
View file
slowmoVideo-0.6.tar.xz/src/slowmoRenderer/CMakeLists.txt
Added
@@ -0,0 +1,12 @@ + +include_directories(..) + +set(SRCS + rendererMain.cpp + slowmoRenderer_sV.cpp +) + +add_executable(slowmoRenderer ${SRCS}) +target_link_libraries(slowmoRenderer sVproj ${EXTERNAL_LIBS}) +qt5_use_modules(slowmoRenderer Script Widgets Concurrent Gui Core ) +install(TARGETS slowmoRenderer DESTINATION ${DEST})
View file
slowmoVideo-0.6.tar.xz/src/slowmoRenderer/rendererMain.cpp
Added
@@ -0,0 +1,261 @@ +/* +This file is part of slowmoVideo. +Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +*/ + +#include "slowmoRenderer_sV.h" + +#include <QtCore/QCoreApplication> +#include <QtCore/QStringList> + +#include <iostream> +#include <csignal> +#include <cstdlib> + +QString myName; +SlowmoRenderer_sV renderer; + +int terminateCounter = 0; +int genproj = 0; + +//TODO: maybe in case of abort we should remove directories ? +void terminate(int) +{ + if (terminateCounter == 0) { + std::cout << "Telling renderer to stop." << std::endl; + } else if (terminateCounter == 1) { + std::cout << "Really want to kill rendering? Send the SIGINT a third time." << std::endl; + } else { + exit(SIGINT); + } + terminateCounter++; + renderer.abort(); +} + +void printProgress(int) +{ + renderer.printProgress(); +} + +void printHelp() +{ + std::cout << "slowmoRenderer for slowmoVideo " << Version_sV::version.toStdString() << std::endl + << myName.toStdString() << " <project>" << std::endl + << "\t-target video <path> <codec>|auto | images <filenamePattern> <directory> " << std::endl + << "\t-input video <path> | images <filenamePattern> <directory> " << std::endl + << "\t-size small|orig " << std::endl + << "\t-fps <fps> " << std::endl + << "\t-start <startTime> -end <endTime> " << std::endl + << "\t-interpolation forward2|twoway2 " << std::endl + << "\t -motionblur stack|convolve " << std::endl + << "\t -slowfactor <factor>" << std::endl + << "\t-v3dLambda <lambda> " << std::endl; +} + +void require(int nArgs, int index, int size) +{ + if (size <= index + nArgs) { + std::cout << "Not enough arguments delivered (" << nArgs << " required)." << std::endl; + printHelp(); + exit(-1); + } +} + +int main(int argc, char *argv) +{ + QCoreApplication app(argc, argv); + + // Set up preferences for the QSettings file + QCoreApplication::setOrganizationName("Granjow"); + QCoreApplication::setOrganizationDomain("granjow.net"); + QCoreApplication::setApplicationName("slowmoUI"); + + if (signal(SIGINT, terminate) == SIG_ERR) { + std::cerr << "Could not set up SIGINT handler." << std::endl; + } +#ifndef WINDOWS + if (signal(SIGUSR1, printProgress) == SIG_ERR) { + std::cerr << "Could not set up SIGUSR1 handler." << std::endl; + } +#endif + + QStringList args = app.arguments(); + myName = args.at(0); + if (argc <= 1 + || "--help" == args.at(1) || "-h" == args.at(1)) { + printHelp(); + return 0; + } + + + + int next = 1; + if ((args.at(1)).contains("svProj", Qt::CaseInsensitive) ) { + renderer.load(args.at(1)); + next = 2; + } else + renderer.create(); + + QString start = ":start"; + QString end = ":end"; + + const int n = args.size(); + while (next < n) { + if ("-target" == args.at(next)) { + require(3, next, n); + next++; + if ("video" == args.at(next)) { + next++; + QString filename = args.at(next++); + QString codec = args.at(next++); + if ("auto" == codec) { codec = ""; } + + renderer.setVideoRenderTarget(filename, codec); + + } else if ("images" == args.at(next)) { + next++; + QString filenamePattern = args.at(next++); + QString dir = args.at(next++); + renderer.setImagesRenderTarget(filenamePattern, dir); + + } else { + std::cerr << "Not a valid target: " << args.at(next).toStdString() << std::endl; + return -1; + } + + } else if ("-input" == args.at(next)) { + require(2, next, n); + next++; + if ("video" == args.at(next)) { + next++; + QString filename = args.at(next++); + + renderer.setInputTarget(filename); + + } else if ("images" == args.at(next)) { + next++; + QString filenamePattern = args.at(next++); + QString dir = args.at(next++); + //TODO: pattern ? + //renderer.setImagesRenderTarget(filenamePattern, dir); + + } else { + std::cerr << "Not a valid input: " << args.at(next).toStdString() << std::endl; + return -1; + } + } else if ("-size" == args.at(next)) { + require(1, next, n); + next++; + if ("small" == args.at(next)) { + renderer.setSize(false); + } else if ("orig" == args.at(next)) { + renderer.setSize(true); + } else { + std::cerr << "Not a valid size: " << args.at(next).toStdString() << std::endl; + return -1; + } + next++; + + } else if ("-fps" == args.at(next)) { + require(1, next, n); + next++; + bool b; + double fps = args.at(next).toDouble(&b); + if (!b) { + std::cerr << "Not a number: " << args.at(next).toStdString() << std::endl; + return -1; + } + renderer.setFps(fps); + next++; + + } else if ("-start" == args.at(next)) { + require(1, next, n); + next++; + start = args.at(next++); + + } else if ("-end" == args.at(next)) { + require(1, next, n); + next++; + end = args.at(next++); + + } else if ("-interpolation" == args.at(next)) { + require(1, next, n); + next++; + if ("forward" == args.at(next)) { + renderer.setInterpolation(InterpolationType_Forward); + } else if ("forward2" == args.at(next)) { + renderer.setInterpolation(InterpolationType_ForwardNew); + } else if ("twoway" == args.at(next)) { + renderer.setInterpolation(InterpolationType_Twoway); + } else if ("twoway2" == args.at(next)) { + renderer.setInterpolation(InterpolationType_TwowayNew); + } else { + std::cerr << "Not a valid interpolation type: " << args.at(next).toStdString() << std::endl; + return -1; + } + next++; + + } else if ("-motionblur" == args.at(next)) { + require(1, next, n); + next++; + if ("stack" == args.at(next)) { + renderer.setMotionblur(MotionblurType_Stacking); + } else if ("convolve" == args.at(next)) { + renderer.setMotionblur(MotionblurType_Convolving); + } else { + std::cerr << "Not a valid motion blur type: " << args.at(next).toStdString() << std::endl; + return -1; + } + next++; + + } else if ("-v3dLambda" == args.at(next)) { + require(1, next, n); + next++; + bool b; + float lambda = args.at(next).toFloat(&b); + if (!b) { + std::cerr << "Not a number: " << args.at(next).toStdString() << std::endl; + return -1; + } + renderer.setV3dLambda(lambda); + next++; + + } else if ("-slowfactor" == args.at(next)) { + require(1, next, n); + next++; + bool b; + double slowfactor = args.at(next).toDouble(&b); + if (!b) { + std::cerr << "Not a number: " << args.at(next).toStdString() << std::endl; + return -1; + } + std::cerr << "will slow down to : " << slowfactor << std::endl; + renderer.setSpeed(slowfactor); + next++; + } else { + std::cout << "Argument not recognized: " << args.at(next).toStdString() << std::endl; + printHelp(); + return -1; + } + } + + renderer.setTimeRange(start, end); + + QString msg; + if (!renderer.isComplete(msg)) { + std::cout << msg.toStdString() << std::endl; + std::cout << "Project will not be rendered." << std::endl; + return 42; + } + + if (genproj) + renderer.save("test.svProj"); + else + renderer.start(); + +}
View file
slowmoVideo-0.6.tar.xz/src/slowmoRenderer/slowmoRenderer_sV.cpp
Added
@@ -0,0 +1,280 @@ +/* +This file is part of slowmoVideo. +Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +*/ +#include "config.h" + +#include "slowmoRenderer_sV.h" + +#include "project/project_sV.h" +#include "project/projectPreferences_sV.h" +#include "project/xmlProjectRW_sV.h" +#include "project/renderTask_sV.h" +#include "project/imagesRenderTarget_sV.h" + +#include "project/videoFrameSource_sV.h" +#include "project/emptyFrameSource_sV.h" +#include "project/imagesFrameSource_sV.h" + +#ifdef USE_FFMPEG +#if 0 +#include "project/new_videoRenderTarget.h" +#else +#include "project/exportVideoRenderTarget.h" +#endif +#else +#include "project/videoRenderTarget_sV.h" +#endif + +#include "project/flowSourceV3D_sV.h" + +#include <iostream> + +Error::Error(std::string message) : + // m_nodes->setMaxY(m_frameSource->maxTime()); + message(message) {} + +SlowmoRenderer_sV::SlowmoRenderer_sV() : + m_project(NULL), + m_taskSize(0), + m_lastProgress(0), + m_start(":start"), + m_end(":end"), + m_renderTargetSet(false) +{ +} + +SlowmoRenderer_sV::~SlowmoRenderer_sV() +{ + // TODO Only do this after checking if the directory is really a project directory + //m_project->getProjectDir().removeRecursively(); + + delete m_project; +} + +void SlowmoRenderer_sV::save(QString filename) +{ + XmlProjectRW_sV writer; + writer.saveProject(m_project, filename); +} + +void SlowmoRenderer_sV::load(QString filename) noexcept(false) +{ + if (m_project != NULL) { + delete m_project; + m_project = NULL; + } + QString warning; + try { + Project_sV *proj = XmlProjectRW_sV::loadProject(QString(filename), &warning); + + if (warning.length() > 0) { + std::cout << warning.toStdString() << std::endl; + } + + m_project = proj; + + RenderTask_sV *task = new RenderTask_sV(m_project); + m_project->replaceRenderTask(task); + task->renderPreferences().setFps(24); + task->setTimeRange(m_start, m_end); + + connect(m_project->renderTask(), SIGNAL(signalNewTask(QString,int)), this, SLOT(slotTaskSize(QString,int))); + connect(m_project->renderTask(), SIGNAL(signalTaskProgress(int)), this, SLOT(slotProgressInfo(int))); + connect(m_project->renderTask(), SIGNAL(signalRenderingAborted(QString)), this, SLOT(slotFinished(QString))); + connect(m_project->renderTask(), SIGNAL(signalRenderingFinished(QString)), this, SLOT(slotFinished(QString))); + connect(m_project->renderTask(), SIGNAL(signalRenderingStopped(QString)), this, SLOT(slotFinished(QString))); + + } catch (Error_sV &err) { + throw Error(err.message().toStdString()); + } +} + +void SlowmoRenderer_sV::create() noexcept(false) +{ + std::cout << "Standalone Rendering." << std::endl; + + if (m_project != NULL) { + delete m_project; + m_project = NULL; + } + + try { + + + m_project = new Project_sV(); + + + RenderTask_sV *task = new RenderTask_sV(m_project); + m_project->replaceRenderTask(task); + task->renderPreferences().setFps(24); + //task->setTimeRange(m_start, m_end); + + connect(m_project->renderTask(), SIGNAL(signalNewTask(QString,int)), this, SLOT(slotTaskSize(QString,int))); + connect(m_project->renderTask(), SIGNAL(signalTaskProgress(int)), this, SLOT(slotProgressInfo(int))); + connect(m_project->renderTask(), SIGNAL(signalRenderingAborted(QString)), this, SLOT(slotFinished(QString))); + connect(m_project->renderTask(), SIGNAL(signalRenderingFinished(QString)), this, SLOT(slotFinished(QString))); + connect(m_project->renderTask(), SIGNAL(signalRenderingStopped(QString)), this, SLOT(slotFinished(QString))); + + } catch (Error_sV &err) { + throw Error(err.message().toStdString()); + } +} + + +void SlowmoRenderer_sV::setSpeed(double slowfactor) +{ + /* add a first (default) node */ + Node_sV snode; + + snode.setX(0.0); + snode.setY(0.0); + m_project->nodes()->add(snode); + + Node_sV enode; + // linear slope ? + // maybe should calc ? + // need to check for video loaded ? + enode.setY(m_project->frameSource()->maxTime()); + enode.setX((1/slowfactor)*m_project->frameSource()->maxTime()); + m_project->nodes()->add(enode); + + //m_project->nodes()->setSpeed(0,slowfactor); + m_project->renderTask()->setTimeRange(m_start, m_end); +} + +void SlowmoRenderer_sV::setTimeRange(QString start, QString end) +{ + m_start = start; + m_end = end; + m_project->renderTask()->setTimeRange(m_start, m_end); +} + +void SlowmoRenderer_sV::setFps(double fps) +{ + m_project->renderTask()->renderPreferences().setFps(fps); +} + +void SlowmoRenderer_sV::setInputTarget(QString inFilename) +{ + m_project->loadFrameSource(new VideoFrameSource_sV(m_project, inFilename)); + + connect(m_project->frameSource(), SIGNAL(signalNextTask(QString,int)), this, SLOT(slotNewFrameSourceTask(QString,int))); + connect(m_project->frameSource(), SIGNAL(signalAllTasksFinished()), this, SLOT(slotFrameSourceTasksFinished())); + + //m_project->frameSource()->initialize(); + m_project->frameSource()->loadOrigFrames(); + // m_nodes->setMaxY(m_frameSource->maxTime()); +// std::cerr << "max time : " << m_project->frameSource()->maxTime() << std::endl; +} + +void SlowmoRenderer_sV::setVideoRenderTarget(QString filename, QString codec) +{ +#ifdef USE_FFMPEG +#if 0 + #warning "using QTKit version" + newVideoRenderTarget *vrt = new newVideoRenderTarget(m_project->renderTask()); +#else + #warning "using fork version" + exportVideoRenderTarget *vrt = new exportVideoRenderTarget(m_project->renderTask()); +#endif +#else + #warning "should not use this" + VideoRenderTarget_sV *vrt = new VideoRenderTarget_sV(m_project->renderTask()); +#endif + vrt->setTargetFile(QString(filename)); + vrt->setVcodec(QString(codec)); + m_project->renderTask()->setRenderTarget(vrt); + m_renderTargetSet = true; +} + +void SlowmoRenderer_sV::setImagesRenderTarget(QString filenamePattern, QString directory) +{ + ImagesRenderTarget_sV *irt = new ImagesRenderTarget_sV(m_project->renderTask()); + irt->setFilenamePattern(QString(filenamePattern)); + irt->setTargetDir(QString(directory)); + m_project->renderTask()->setRenderTarget(irt); + m_renderTargetSet = true; +} + +void SlowmoRenderer_sV::setInterpolation(InterpolationType interpolation) +{ + m_project->renderTask()->renderPreferences().interpolation = interpolation; +} + +void SlowmoRenderer_sV::setMotionblur(MotionblurType motionblur) +{ + m_project->renderTask()->renderPreferences().motionblur = motionblur; +} + +void SlowmoRenderer_sV::setSize(bool original) +{ + if (original) { + m_project->renderTask()->renderPreferences().size = FrameSize_Orig; + } else { + m_project->renderTask()->renderPreferences().size = FrameSize_Small; + } +} + +void SlowmoRenderer_sV::setV3dLambda(float lambda) +{ + m_project->preferences()->flowV3DLambda() = lambda; +} + +void SlowmoRenderer_sV::start() +{ + m_project->renderTask()->slotContinueRendering(); +} +void SlowmoRenderer_sV::abort() +{ + m_project->renderTask()->slotStopRendering(); +} + + +void SlowmoRenderer_sV::slotProgressInfo(int progress) +{ + m_lastProgress = progress; +} +void SlowmoRenderer_sV::slotTaskSize(QString desc, int size) +{ + std::cout << desc.toStdString() << std::endl; + m_taskSize = size; +} + +void SlowmoRenderer_sV::slotFinished(QString time) +{ + std::cout << std::endl << "Rendering finished. Time taken: " << time.toStdString() << std::endl; +} + + +void SlowmoRenderer_sV::printProgress() +{ + std::cout << m_lastProgress << "/" << m_taskSize << std::endl; +} + +bool SlowmoRenderer_sV::isComplete(QString &message) const +{ + bool b = true; + if (!m_renderTargetSet) { + b = false; + message.append("No render target set.\n"); + } + return b; +} + +void SlowmoRenderer_sV::slotNewFrameSourceTask(const QString taskDescription, int taskSize) +{ + std::cout << "slotNewFrameSourceTask"; +} + +void SlowmoRenderer_sV::slotFrameSourceTasksFinished() +{ + std::cout << "slotFrameSourceTasksFinished"; +} + +
View file
slowmoVideo-0.6.tar.xz/src/slowmoRenderer/slowmoRenderer_sV.h
Added
@@ -0,0 +1,85 @@ +/* +This file is part of slowmoVideo. +Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +*/ + +#ifndef SLOWMORENDERER_SV_H +#define SLOWMORENDERER_SV_H + +#include "lib/defs_sV.hpp" +#include <QtCore/QObject> +#include <QtCore/QCoreApplication> +#include <string> + +class Project_sV; + +class Error { +public: + Error(std::string message); + std::string message; +}; + +/** + \brief Just for rendering. + */ +class SlowmoRenderer_sV : public QObject +{ + Q_OBJECT +public: + SlowmoRenderer_sV(); + ~SlowmoRenderer_sV(); + + void load(QString filename) noexcept(false); + void save(QString filename); + void create() noexcept(false); + void start(); + void abort(); + + void setTimeRange(QString start, QString end); + void setFps(double fps); + void setVideoRenderTarget(QString filename, QString codec); + void setImagesRenderTarget(QString filenamePattern, QString directory); + void setInputTarget(QString inFilename); + void setInterpolation(InterpolationType interpolation); + void setMotionblur(MotionblurType motionblur); + void setSize(bool original); + void setV3dLambda(float lambda); + void setSpeed(double slowfactor); + + + void printProgress(); + + /// Checks if all necessary parameters (e.g. paths) are set + /// \param message Will contain an error message if the function returned \c false + bool isComplete(QString &message) const; + + +private: + Project_sV *m_project; + + int m_taskSize; + int m_lastProgress; + + QString m_start; + QString m_end; + + bool m_renderTargetSet; + + +private slots: + void slotProgressInfo(int progress); + void slotTaskSize(QString desc, int size); + void slotFinished(QString time); + + void slotNewFrameSourceTask(const QString taskDescription, int taskSize); + void slotFrameSourceTasksFinished(); + +}; + + +#endif // SLOWMORENDERER_SV_H
View file
slowmoVideo-0.6.tar.xz/src/slowmoUI
Added
+(directory)
View file
slowmoVideo-0.6.tar.xz/src/slowmoUI/CMakeLists.txt
Added
@@ -0,0 +1,163 @@ + +# Building Qt+UI apps: +# http://www.qtcentre.org/wiki/index.php?title=Compiling_Qt4_apps_with_CMake +# http://www.cmake.org/pipermail/cmake/2008-September/023908.html + + + +include_directories(${slowmoVideo_SOURCE_DIR}) + +set(SRCS + main.cpp + mainwindow.cpp + canvas.cpp + canvasTools.cpp + flowEditCanvas.cpp + frameMonitor.cpp + renderPreview.cpp + dialogues/newProjectDialog.cpp + dialogues/preferencesDialog.cpp + dialogues/projectPreferencesDialog.cpp + dialogues/progressDialog.cpp + dialogues/renderingDialog.cpp + dialogues/shutterFunctionDialog.cpp + dialogues/shutterFunctionFrame.cpp + dialogues/flowExaminer.cpp + dialogues/tagAddDialog.cpp + dialogues/aboutDialog.cpp + notificator.cpp + logbrowserdialog.cpp +) + +# notification +if (APPLE) +find_library(CORE_FOUNDATION NAMES CoreFoundation) +find_library(FOUNDATION NAMES Foundation) +find_library(APPLICATION_SERVICES NAMES ApplicationServices) +find_library(CORE_SERVICES NAMES CoreServices) +find_library(COCOA NAMES Cocoa) + +SET(OSX_EXTRA_LIBS ${FOUNDATION} ${CORE_FOUNDATION} ${APPLICATION_SERVICES}) +message(STATUS "OSX Additional libraries: ${OSX_EXTRA_LIBS}") + +set(SRCS + ${SRCS} + macnotificationhandler.mm +) +endif() + +set(SRCS_UI + mainwindow.ui + canvas.ui + frameMonitor.ui + renderPreview.ui + flowEditCanvas.ui + dialogues/newProjectDialog.ui + dialogues/preferencesDialog.ui + dialogues/projectPreferencesDialog.ui + dialogues/progressDialog.ui + dialogues/renderingDialog.ui + dialogues/shutterFunctionDialog.ui + dialogues/flowExaminer.ui + dialogues/tagAddDialog.ui + dialogues/aboutDialog.ui +) + +if(APPLE) + set(BUNDLE "slowmoUI") + set(ICONS_DIR "${${PROJECT_NAME}_SOURCE_DIR}/slowmoVideo/slowmoUI/res") + message( "OS X build" ) + set(MACOSX_BUNDLE_INFO_STRING "${BUNDLE} ${PROJECT_VERSION}") + set(MACOSX_BUNDLE_BUNDLE_VERSION "${BUNDLE} ${PROJECT_VERSION}") + set(MACOSX_BUNDLE_LONG_VERSION_STRING "${BUNDLE} ${PROJECT_VERSION}") + set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${PROJECT_VERSION}") + set(MACOSX_BUNDLE_COPYRIGHT ${COPYRIGHT} ) + set(MACOSX_BUNDLE_ICON_FILE "slowmoUI.icns") + set(MACOSX_BUNDLE_GUI_IDENTIFIER ${IDENTIFIER} ) + set(MACOSX_BUNDLE_BUNDLE_NAME "${BUNDLE}") + + set(MACOSX_BUNDLE_RESOURCES "${CMAKE_CURRENT_BINARY_DIR}/${BUNDLE}.app/Contents/Resources") + set(MACOSX_BUNDLE_ICON "${ICONS_DIR}/${MACOSX_BUNDLE_ICON_FILE}") + SET_SOURCE_FILES_PROPERTIES( + ${MACOSX_BUNDLE_ICON} + PROPERTIES MACOSX_PACKAGE_LOCATION Resources) + message(STATUS "slowmoUI Bundle will be : ${MACOSX_BUNDLE} ") + + set( SRCS ${SRCS} ${MACOSX_BUNDLE_ICON} ) + + set(INFO_PLIST_FILENAME ${CMAKE_CURRENT_BINARY_DIR}/Info.plist) + configure_file(${CMAKE_SOURCE_DIR}/slowmoVideo/slowmoUI/res/Info.plist.in ${INFO_PLIST_FILENAME}) + set_target_properties(${PROGNAME} PROPERTIES + MACOSX_BUNDLE_INFO_PLIST ${INFO_PLIST_FILENAME} ) + #ADD_CUSTOM_COMMAND(TARGET slowmoUI + # POST_BUILD + # COMMAND cp Info.plist slowmoUI.app/Contents/Info.plist + # COMMENT "Updating Info.plist" + # WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} ) + +endif() + +# Without these includes the promoted widgets fail to compile +# since the headers are not found. (For whatever reason.) +include_directories(dialogues) +include_directories(.) +include_directories(..) + +# Embed images in the binary +set(SRC_RES resources.qrc) +qt5_add_resources(RES_OUT ${SRC_RES}) + +# Generate header files from the .ui files + +# Include the generated header files +include_directories(${CMAKE_BINARY_DIR}/slowmoVideo/slowmoUI) + + +link_directories(${FFMPEG_LIBRARY_DIR}) +add_executable(slowmoUI WIN32 MACOSX_BUNDLE ${SRCS} ${RES_OUT}) +qt5_use_modules(slowmoUI Script Widgets Concurrent Gui Core ) +target_link_libraries(slowmoUI sVproj sVvis sVgui sVflow sVflowtools ${OSX_EXTRA_LIBS}) + +#install(TARGETS ${slowmoUI} +# BUNDLE DESTINATION . COMPONENT Runtime +# RUNTIME DESTINATION ${BIN_INSTALL_DIR} COMPONENT Runtime) + +if (UNIX AND NOT APPLE) +# create desktop file for KDE/Gnome +# desktop file section + file( WRITE "${PROJECT_BINARY_DIR}/slowmoUI.desktop" +"#!/usr/bin/env xdg-open +Desktop Entry +Type=Application +Comment=Slow Motion Video +Exec=${CMAKE_INSTALL_PREFIX}/bin/slowmoUI +GenericName=slowmoVideo +Icon=${CMAKE_INSTALL_PREFIX}/share/icons/AppIcon +MimeType= +Name=slowmoUI +Terminal=false +Categories=Qt;AudioVideo;Video;\n") + + #install ( FILES icons/slowmoUI.png DESTINATION share/icons ) + install ( FILES res/AppIcon.png DESTINATION share/icons ) + install ( FILES ${PROJECT_BINARY_DIR}/slowmoUI.desktop DESTINATION share/applications + PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE +) +endif() + +include(DeployQt5) + + +#set( PLUGINS "qjpeg;qtiff" ) +set( PLUGINS qjpeg ) +if (APPLE) + install(TARGETS slowmoUI DESTINATION ".") + install_qt5_executable(slowmoUI.app "${PLUGINS}" ) +elseif(WIN32) + install(TARGETS slowmoUI DESTINATION ".") + install_qt5_executable(slowmoUI.exe "${PLUGINS}" ) +else() + install(TARGETS slowmoUI DESTINATION ${DEST}) +# install_qt5_executable(slowmoUI "${PLUGINS}" ) +endif() +
View file
slowmoVideo-0.6.tar.xz/src/slowmoUI/canvas.cpp
Added
@@ -0,0 +1,1342 @@ +/* +slowmoUI is a user interface for slowmoVideo. +Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +*/ + +#include "canvas.h" +#include "canvasTools.h" +#include "ui_canvas.h" + +#include "mainwindow.h" +#include "tagAddDialog.h" +#include "shutterFunctionDialog.h" +#include "project/shutterFunction_sV.h" +#include "project/shutterFunctionList_sV.h" +#include "lib/bezierTools_sV.h" + +#include "project/projectPreferences_sV.h" +#include "project/abstractFrameSource_sV.h" + +#include <cmath> +#include <typeinfo> + +#include <QtCore/QDebug> + +#include <QtCore/QPoint> +#include <QtCore/QPointF> +#include <QtCore/QSignalMapper> + +#include <QtGui/QColor> +#include <QtGui/QImage> +#include <QtGui/QMouseEvent> +#include <QtGui/QPainter> +#include <QtGui/QPainterPath> +#include <QMenu> +#include <QInputDialog> +#include <QMessageBox> + + +//#define VALIDATE_BEZIER +#ifdef VALIDATE_BEZIER +#include "lib/bezierTools_sV.h" +#endif + +//#define DEBUG_C +#ifdef DEBUG_C +#include <iostream> +#endif + +QColor Canvas::selectedCol ( 0, 175, 255, 100); +QColor Canvas::hoverCol (255, 175, 0, 200); +QColor Canvas::lineCol (255, 255, 255); +QColor Canvas::selectedLineCol(255, 175, 0, 200); +QColor Canvas::nodeCol (240, 240, 240); +QColor Canvas::gridCol (255, 255, 255, 30); +QColor Canvas::fatGridCol (255, 255, 255, 60); +QColor Canvas::minGridCol (200, 200, 255, 150); +QColor Canvas::handleLineCol(255, 255, 255, 128); +QColor Canvas::srcTagCol ( 30, 245, 0, 150); +QColor Canvas::outTagCol ( 30, 245, 0, 150); +QColor Canvas::backgroundCol( 34, 34, 34); +QColor Canvas::shutterRegionCol(175, 25, 75, 100); +QColor Canvas::shutterRegionBoundCol(240, 0, 60, 150); + +/// \todo move with MMB +/// \todo replay curve + +Canvas::Canvas(Project_sV *project, QWidget *parent) : + QWidget(parent), + ui(new Ui::Canvas), + m_project(project), + m_mouseWithinWidget(false), + m_distLeft(90), + m_distBottom(50), + m_distRight(20), + m_distTop(32), + m_t0(0,0), + m_tmax(10,10), + m_secResX(100), + m_secResY(100), + m_showHelp(false), + m_nodes(project->nodes()), + m_tags(project->tags()), + m_mode(ToolMode_Select) +{ + ui->setupUi(this); + m_shutterFunctionDialog = nullptr; + + // Enable mouse tracking (not only when a mouse button is pressed) + this->setMouseTracking(true); + + setContextMenuPolicy(Qt::DefaultContextMenu); + setFocusPolicy(Qt::StrongFocus); + + m_states.prevMousePos = QPoint(0,0); + m_states.contextmenuMouseTime = QPointF(0,0); + m_states.initialContextObject = nullptr; + + Q_ASSERT(m_secResX > 0); + Q_ASSERT(m_secResY > 0); + + m_aDeleteNode = new QAction(tr("&Delete node"), this); + m_aSnapInNode = new QAction(tr("&Snap in node"), this); + m_aDeleteTag = new QAction(tr("&Delete tag"), this); + m_aRenameTag = new QAction(tr("&Rename tag"), this); + m_aSetTagTime = new QAction(tr("Set tag &time"), this); + m_hackMapper = new QSignalMapper(this); + m_hackMapper->setMapping(m_aRenameTag, &m_toRenameTag); m_toRenameTag.reason = TransferObject::ACTION_RENAME; + m_hackMapper->setMapping(m_aDeleteTag, &m_toDeleteTag); m_toDeleteTag.reason = TransferObject::ACTION_DELETE; + m_hackMapper->setMapping(m_aDeleteNode, &m_toDeleteNode); m_toDeleteNode.reason = TransferObject::ACTION_DELETE; + m_hackMapper->setMapping(m_aSnapInNode, &m_toSnapInNode); m_toSnapInNode.reason = TransferObject::ACTION_SNAPIN; + m_hackMapper->setMapping(m_aSetTagTime, &m_toSetTagTime); m_toSetTagTime.reason = TransferObject::ACTION_SETTIME; + + m_curveTypeMapper = new QSignalMapper(this); + m_aLinear = new QAction(tr("&Linear curve"), this); + m_aBezier = new QAction(trUtf8("&Bézier curve"), this); + m_curveTypeMapper->setMapping(m_aLinear, CurveType_Linear); + m_curveTypeMapper->setMapping(m_aBezier, CurveType_Bezier); + + m_aCustomSpeed = new QAction(tr("Set &custom speed"), this); + m_aShutterFunction = new QAction(tr("Set/edit shutter &function"), this); + + m_speedsMapper = new QSignalMapper(this); + double arr = {1, .5, 0, -.5, -1}; +#define N_SPEEDS 5 + for (int i = 0; i < N_SPEEDS; i++) { + m_aSpeeds.push_back(new QAction(trUtf8("Set speed to %1×").arg(arri, 0, 'f', 1), this)); + m_speedsMapper->setMapping(m_aSpeeds.back(), QString("%1").arg(arri,0,'f',1)); + } + + m_handleMapper = new QSignalMapper(this); + m_aResetLeftHandle = new QAction(tr("Reset left handle"), this); + m_aResetRightHandle = new QAction(tr("Reset right handle"), this); + m_handleMapper->setMapping(m_aResetLeftHandle, "left"); + m_handleMapper->setMapping(m_aResetRightHandle, "right"); + + + connect(m_aSnapInNode, SIGNAL(triggered()), m_hackMapper, SLOT(map())); + connect(m_aDeleteNode, SIGNAL(triggered()), m_hackMapper, SLOT(map())); + connect(m_aDeleteTag, SIGNAL(triggered()), m_hackMapper, SLOT(map())); + connect(m_aRenameTag, SIGNAL(triggered()), m_hackMapper, SLOT(map())); + connect(m_aSetTagTime, SIGNAL(triggered()), m_hackMapper, SLOT(map())); + connect(m_hackMapper, SIGNAL(mapped(QObject*)), this, SLOT(slotRunAction(QObject*))); + connect(m_aLinear, SIGNAL(triggered()), m_curveTypeMapper, SLOT(map())); + connect(m_aBezier, SIGNAL(triggered()), m_curveTypeMapper, SLOT(map())); + connect(m_curveTypeMapper, SIGNAL(mapped(int)), this, SLOT(slotChangeCurveType(int))); + connect(m_aResetLeftHandle, SIGNAL(triggered()), m_handleMapper, SLOT(map())); + connect(m_aResetRightHandle, SIGNAL(triggered()), m_handleMapper, SLOT(map())); + connect(m_handleMapper, SIGNAL(mapped(QString)), this, SLOT(slotResetHandle(QString))); + connect(m_aCustomSpeed, SIGNAL(triggered()), this, SLOT(slotSetSpeed())); + connect(m_speedsMapper, SIGNAL(mapped(QString)), this, SLOT(slotSetSpeed(QString))); + connect(m_aShutterFunction, SIGNAL(triggered()), this, SLOT(slotSetShutterFunction())); + for (auto it = m_aSpeeds.begin(); it != m_aSpeeds.end(); ++it) { + connect(*it, SIGNAL(triggered()), m_speedsMapper, SLOT(map())); + } +} + +Canvas::~Canvas() +{ + delete ui; + if (m_shutterFunctionDialog != nullptr) { + delete m_shutterFunctionDialog; + } + + while (!m_aSpeeds.empty()) { + delete m_aSpeeds.back(); + m_aSpeeds.pop_back(); + } + delete m_speedsMapper; + delete m_hackMapper; + + delete m_aSnapInNode; + delete m_aDeleteNode; + delete m_aDeleteTag; + delete m_aRenameTag; +} + +void Canvas::load(Project_sV *project) +{ + if (m_shutterFunctionDialog != nullptr) { + m_shutterFunctionDialog->close(); + delete m_shutterFunctionDialog; + m_shutterFunctionDialog = nullptr; + } + + m_project = project; + m_t0 = m_project->preferences()->viewport_t0(); + m_secResX = m_project->preferences()->viewport_secRes().x(); + m_secResY = m_project->preferences()->viewport_secRes().y(); + Q_ASSERT(m_secResX > 0); + Q_ASSERT(m_secResY > 0); + qDebug() << "Canvas: Project loaded from " << project; + m_nodes = project->nodes(); + m_tags = project->tags(); + qDebug() << "Frame source: " << project->frameSource(); + m_tmax.setY(project->frameSource()->maxTime()); + qDebug() << "tMaxY set to " << m_tmax.y(); + + + repaint(); +} + +void Canvas::showHelp(bool show) +{ + m_showHelp = show; + repaint(); + + m_settings.setValue("ui/displayHelp", show); + m_settings.sync(); +} + +void Canvas::toggleHelp() +{ + showHelp(!m_showHelp); +} + +const QPointF Canvas::prevMouseTime() const +{ + return convertCanvasToTime(m_states.prevMousePos).toQPointF(); +} + +const float Canvas::prevMouseInFrame() const +{ + return convertCanvasToTime(m_states.prevMousePos).toQPointF().y() * m_project->frameSource()->fps()->fps(); +} + + +bool Canvas::selectAt(const QPoint &pos, bool addToSelection) +{ + bool selected = false; + int ti = m_nodes->find(convertCanvasToTime(pos).x()); + qDebug() << "Nearest node index: " << ti; + if (ti != -1 && m_nodes->size() > ti) { + QPoint p = convertTimeToCanvas(m_nodes->at(ti)); + qDebug() << "Mouse pos: " << pos << ", node pos: " << p; + if ( + abs(p.x() - pos.x()) <= NODE_RADIUS+SELECT_RADIUS+4 && + abs(p.y() - pos.y()) <= NODE_RADIUS+SELECT_RADIUS+4 + ) { + qDebug() << "Selected: " << pos.x() << "/" << pos.y(); + + + if (!m_nodes->at(ti).selected() && !addToSelection) { + m_nodes->unselectAll(); + } + + if (addToSelection) { + (*m_nodes)ti.select(!m_nodes->at(ti).selected()); + } else { + (*m_nodes)ti.select(true); + } + selected = true; + } + } + return selected; +} + +bool Canvas::insideCanvas(const QPoint &pos) +{ + return pos.x() >= m_distLeft && + pos.y() >= m_distTop && + pos.x() < width()-m_distRight && + pos.y() < height()-m_distBottom; +} + +QRect Canvas::leftDrawingRect(int y, const int height, const int min, const int max) const +{ + if (y < min) { y = min; } + if (max > 0 && y > max-height) { y = max-height; } + return QRect(8, y-6, m_distLeft-2*8, 50); +} +QRect Canvas::bottomDrawingRect(int x, const int width, const int min, const int max, bool rightJustified) const +{ + if (rightJustified) { + if (max > 0 && x > max) { x = max; } + if (min > 0 && x< min+width) { x = min+width; } + return QRect(x-width, height()-1 - (m_distBottom-8), width, m_distBottom-2*8); + } else { + if (max > 0 && x > max-width) { x = max-width; } + if (min > 0 && x < min) { x = min; } + return QRect(x, height()-1 - (m_distBottom-8), width, m_distBottom-2*8); + } +} + +void Canvas::paintEvent(QPaintEvent *) +{ + QPainter davinci(this); + davinci.setRenderHint(QPainter::Antialiasing, false); + davinci.fillRect(0, 0, width(), height(), backgroundCol); + + QList<NodeList_sV::PointerWithDistance> nearObjects = m_nodes->objectsNear( + convertCanvasToTime(m_states.prevMousePos).toQPointF(), + delta(SELECT_RADIUS)); + if (m_states.prevModifiers.testFlag(Qt::ShiftModifier)) { + while (nearObjects.size() > 0 && nearObjects.at(0).type == NodeList_sV::PointerWithDistance::Node) { + nearObjects.removeFirst(); + } + } + + bool drawLine; + // x grid + for (int tx = ceil(m_t0.x()); true; tx++) { + QPoint pos = convertTimeToCanvas(Node_sV(tx, m_t0.y())); + if (insideCanvas(pos)) { + drawLine = m_secResX >= 7.5; + if (tx%60 == 0) { + davinci.setPen(minGridCol); + drawLine = true; + } else if (tx%10 == 0) { + davinci.setPen(fatGridCol); + drawLine = m_secResX >= .75; + } else { + davinci.setPen(gridCol); + } + + if (drawLine) { + davinci.drawLine(pos.x(), pos.y(), pos.x(), m_distTop); + } + } else { + break; + } + } + // y grid + for (int ty = ceil(m_t0.y()); true; ty++) { + QPoint pos = convertTimeToCanvas(Node_sV(m_t0.x(), ty)); + if (insideCanvas(pos)) { + drawLine = m_secResY >= 7.5; + if (ty%60 == 0) { + davinci.setPen(minGridCol); + drawLine = true; + } else if (ty%10 == 0) { + davinci.setPen(fatGridCol); + drawLine = m_secResX >= .75; + } else { + davinci.setPen(gridCol); + } + + if (drawLine) { + davinci.drawLine(pos.x(), pos.y(), width()-1 - m_distRight, pos.y()); + } + } else { + break; + } + } + { + QPoint pos = convertTimeToCanvas(Node_sV(m_t0.x(), m_tmax.y())); + if (insideCanvas(pos)) { + davinci.setPen(QPen(QBrush(lineCol), 2)); + davinci.drawLine(pos.x(), pos.y(), width()-1-m_distRight, pos.y()); + } + } + + drawModes(davinci, 8, width()-1 - m_distRight); + + // Frames/seconds + davinci.setPen(lineCol); + if (m_mouseWithinWidget && insideCanvas(m_states.prevMousePos)) { + QString timeText, speedText; + Node_sV time = convertCanvasToTime(m_states.prevMousePos); + + const int mX = m_states.prevMousePos.x(); + const int mY = m_states.prevMousePos.y(); + + davinci.drawLine(mX, m_distTop, mX, height()-1 - m_distBottom); + timeText = CanvasTools::outputTimeLabel(this, time); + speedText = CanvasTools::outputSpeedLabel(time, m_project); + // Ensure that the text does not go over the right border + + davinci.drawText(bottomDrawingRect(mX-20, 160, m_distLeft, -180+width()-m_distRight-50), Qt::AlignRight, timeText); + davinci.drawText(bottomDrawingRect(mX+20, 160, m_distLeft+180, width()-m_distRight-50, false), Qt::AlignLeft, speedText); + davinci.drawLine(m_distLeft, mY, mX, mY); + if (time.y() < 60) { + timeText = QString("f %1\n%2 s") + .arg(time.y()*m_project->frameSource()->fps()->fps(), 2, 'f', 2) + .arg(time.y()); + } else { + timeText = QString("f %1\n%2 min\n+%3 s") + .arg(time.y()*m_project->frameSource()->fps()->fps(), 2, 'f', 2) + .arg(int(time.y()/60)) + .arg(time.y()-60*int(time.y()/60), 0, 'f', 2); + } + davinci.drawText(leftDrawingRect(mY, 48, m_distTop+24, height()-m_distBottom), Qt::AlignRight, timeText); + } + { + Node_sV node; QString timeText ; + + // yMax + node = convertCanvasToTime(QPoint(m_distLeft, m_distTop)); + timeText = QString("f %1").arg(node.y(), 0, 'f', 1); + davinci.drawText(leftDrawingRect(m_distTop), Qt::AlignRight, timeText); + + // yMin + node = convertCanvasToTime(QPoint(m_distLeft, height()-1 - m_distBottom)); + timeText = QString("f %1").arg(node.y(), 0, 'f', 1); + davinci.drawText(leftDrawingRect(height()-m_distBottom-8), Qt::AlignRight, timeText); + + // xMin + node = convertCanvasToTime(QPoint(m_distLeft, height()-1 - m_distBottom)); + timeText = QString("f %1").arg(node.x(), 0, 'f', 1); + davinci.drawText(bottomDrawingRect(m_distLeft+8), Qt::AlignRight, timeText); + + // xMax + node = convertCanvasToTime(QPoint(width()-1 - m_distRight, height()-1 - m_distBottom)); + timeText = QString("f %1").arg(node.x(), 0, 'f', 1); + davinci.drawText(bottomDrawingRect(width()-1-m_distRight), Qt::AlignRight, timeText); + + + } + int bottom = height()-1 - m_distBottom; + davinci.drawLine(m_distLeft, bottom, width()-1 - m_distRight, bottom); + davinci.drawLine(m_distLeft, bottom, m_distLeft, m_distTop); + + // Shutter Lengths (for motion blur) + davinci.setRenderHint(QPainter::Antialiasing, false); + const Node_sV *leftNode = NULL; + const Node_sV *rightNode = NULL; + const float outFps = m_project->preferences()->canvas_xAxisFPS().fps(); + const float sourceFps = m_project->frameSource()->fps()->fps(); + for (int i = 0; i < m_nodes->size(); i++) { + rightNode = &m_nodes->at(i); + QPoint p = convertTimeToCanvas(*rightNode); + + if (leftNode != NULL) { + ShutterFunction_sV *shutterFunction = m_project->shutterFunctions()->function(leftNode->shutterFunctionID()); + if (shutterFunction != NULL) { + + QPoint pp = convertTimeToCanvas(*leftNode); + for (int x = pp.x(); x < p.x(); x++) { + qreal progressOnCurve = ((qreal)x - pp.x()) / (p.x() - pp.x()); + + QPointF time; + if (leftNode->rightCurveType() == CurveType_Bezier && rightNode->leftCurveType() == CurveType_Bezier) { + time = BezierTools_sV::interpolateAtX(convertCanvasToTime(QPoint(x, 0)).x(), + leftNode->toQPointF(), leftNode->toQPointF()+leftNode->rightNodeHandle(), + rightNode->toQPointF()+rightNode->leftNodeHandle(), rightNode->toQPointF()); + } else { + time = leftNode->toQPointF() + (rightNode->toQPointF() - leftNode->toQPointF()) * progressOnCurve; + } + + qreal outTime = time.x(); + qreal sourceTime = time.y(); + qreal sourceFrame = sourceTime * sourceFps; + + float dy; + if (outTime + 1/outFps <= m_nodes->endTime()) { + dy = m_nodes->sourceTime(outTime + 1/outFps) - sourceTime; + } else { + dy = sourceTime - m_nodes->sourceTime(outTime - 1/outFps); + } + float shutter = shutterFunction->evaluate( + progressOnCurve, // x on 0,1 + outTime, // t + outFps, // FPS + sourceFrame, // y + dy // dy to next frame + ); + QPoint sourceShutterTimeStart = QPoint(x, convertTimeToCanvas(time).y()); + QPoint sourceShutterTimeEnd = QPoint(x, convertTimeToCanvas(time + QPointF(0, shutter * outFps/sourceFps)).y()); + if (shutter > 0) { + davinci.setPen(shutterRegionCol); + davinci.drawLine(sourceShutterTimeStart, sourceShutterTimeEnd); + } + davinci.setPen(shutterRegionBoundCol); + davinci.drawPoint(x, sourceShutterTimeEnd.y() - 1); + } + + } + } + + leftNode = &m_nodes->at(i); + } + + // Tags + davinci.setRenderHint(QPainter::Antialiasing, false); + for (int i = 0; i < m_tags->size(); i++) { + Tag_sV tag = m_tags->at(i); + if (tag.axis() == TagAxis_Source) { + QPoint p = convertTimeToCanvas(Node_sV(m_t0.x(), tag.time())); + if (insideCanvas(p)) { + davinci.setPen(srcTagCol); + davinci.drawLine(m_distLeft, p.y(), width()-m_distRight, p.y()); + davinci.drawText(m_distLeft+10, p.y()-1, tag.description()); + } + } else { + QPoint p = convertTimeToCanvas(Node_sV(tag.time(), m_t0.y())); + if (insideCanvas(p)) { + davinci.setPen(outTagCol); + davinci.drawLine(p.x(), height()-1 - m_distBottom, p.x(), m_distTop); + davinci.drawText(p.x()+2, m_distTop, tag.description()); + } + } + } + + // Nodes + davinci.setPen(lineCol); + davinci.setRenderHint(QPainter::Antialiasing, true); + const Node_sV *prev = NULL; + const Node_sV *curr = NULL; + for (int i = 0; i < m_nodes->size(); i++) { + curr = &m_nodes->at(i); + + QPoint p = convertTimeToCanvas(*curr); + + if (curr->selected()) { + davinci.setPen(QPen(QBrush(selectedCol), 2.0)); + davinci.fillRect(p.x()-NODE_RADIUS, p.y()-NODE_RADIUS, 2*NODE_RADIUS+1, 2*NODE_RADIUS+1, selectedCol); + } + davinci.setPen(nodeCol); + if (nearObjects.size() > 0 && curr == nearObjects.at(0).ptr) { + davinci.setPen(hoverCol); + } + davinci.drawRect(p.x()-NODE_RADIUS, p.y()-NODE_RADIUS, 2*NODE_RADIUS+1, 2*NODE_RADIUS+1); + if (prev != NULL) { + if (m_project->nodes()->segments()->at(i-1).selected()) { + davinci.setPen(selectedLineCol); + } else { + davinci.setPen(lineCol); + } + if (prev->rightCurveType() == CurveType_Bezier && curr->leftCurveType() == CurveType_Bezier) { + QPainterPath path; + path.moveTo(convertTimeToCanvas(*prev)); + path.cubicTo( + convertTimeToCanvas(prev->toQPointF() + prev->rightNodeHandle()), + convertTimeToCanvas(curr->toQPointF() + curr->leftNodeHandle()), + convertTimeToCanvas(*curr)); + davinci.drawPath(path); +#ifdef VALIDATE_BEZIER + for (int x = convertTimeToCanvas(*prev).x(); x < p.x(); x++) { + QPointF py = BezierTools_sV::interpolateAtX(convertCanvasToTime(QPoint(x, 0)).x(), + prev->toQPointF(), prev->toQPointF()+prev->rightNodeHandle(), + curr->toQPointF()+curr->leftNodeHandle(), curr->toQPointF()); + qreal y = convertTimeToCanvas(py).y(); +// qDebug() << convertCanvasToTime(QPoint(x, 0)).x() << ": " << x << y; + davinci.drawPoint(x, y); + } +#endif + } else { + davinci.drawLine(convertTimeToCanvas(*prev), p); + } + } + + // Handles + if (i > 0 && curr->leftCurveType() != CurveType_Linear && prev->rightCurveType() != CurveType_Linear) { + davinci.setPen(handleLineCol); + if (nearObjects.size() > 0 && &curr->leftNodeHandle() == nearObjects.at(0).ptr) { + davinci.setPen(hoverCol); + } + QPoint h = convertTimeToCanvas(curr->toQPointF() + curr->leftNodeHandle()); + davinci.drawLine(convertTimeToCanvas(*curr), h); + davinci.drawEllipse(QPoint(h.x(), h.y()), HANDLE_RADIUS, HANDLE_RADIUS); + + davinci.setPen(handleLineCol); + if (nearObjects.size() > 0 && &prev->rightNodeHandle() == nearObjects.at(0).ptr) { + davinci.setPen(hoverCol); + } + h = convertTimeToCanvas(prev->toQPointF() + prev->rightNodeHandle()); + davinci.drawLine(convertTimeToCanvas(*prev), h); + davinci.drawEllipse(QPoint(h.x(), h.y()), HANDLE_RADIUS, HANDLE_RADIUS); + } + + prev = &m_nodes->at(i); + } + + if (m_showHelp) { + MainWindow *mw; + if ((mw = dynamic_cast<MainWindow*>(parentWidget())) != NULL) { + mw->displayHelp(davinci); + } else { + qDebug() << "Cannot show help; wrong parent widget?"; + Q_ASSERT(false); + } + } +} + +void Canvas::drawModes(QPainter &davinci, int t, int r) +{ + qreal opacity = davinci.opacity(); + int w = 16; + int d = 8; + int dR = 0; + + dR += w; + + davinci.setOpacity(.5 + ((m_mode == ToolMode_Select) ? .5 : 0)); + davinci.drawImage(r - dR, t, QImage(":icons/iconSel.png").scaled(16, 16)); + dR += d+w; + + davinci.setOpacity(.5 + ((m_mode == ToolMode_Move) ? .5 : 0)); + davinci.drawImage(r - dR, t, QImage(":icons/iconMov.png").scaled(16, 16)); + + davinci.setOpacity(opacity); +} + +void Canvas::mousePressEvent(QMouseEvent *e) +{ + m_states.reset(); + + m_states.prevMousePos = e->pos(); + m_states.initialMousePos = e->pos(); + + m_states.prevModifiers = e->modifiers(); + m_states.initialModifiers = e->modifiers(); + m_states.initialButtons = e->buttons(); + + m_states.initialContextObject = objectAt(e->pos(), e->modifiers()); + m_states.initial_t0 = m_t0; + + if (m_states.initialContextObject != nullptr) { + qDebug() << "Mouse pressed. Context: " << typeid(*m_states.initialContextObject).name(); + } +} + +void Canvas::mouseMoveEvent(QMouseEvent *e) +{ + m_mouseWithinWidget = true; + + m_states.travel((m_states.prevMousePos - e->pos()).manhattanLength()); + m_states.prevMousePos = e->pos(); + m_states.prevModifiers = e->modifiers(); + + if (e->buttons().testFlag(Qt::LeftButton)) { + + Node_sV diff = convertCanvasToTime(e->pos()) - convertCanvasToTime(m_states.initialMousePos); +#ifdef DEBUG_C + qDebug() << m_states.initialMousePos << "to" << e->pos() << "; Diff: " << diff; +#endif + + if (m_mode == ToolMode_Select) { + if (dynamic_cast<const NodeHandle_sV*>(m_states.initialContextObject) != nullptr) { + auto *handle = dynamic_cast<const NodeHandle_sV*>(m_states.initialContextObject); + int index = m_nodes->indexOf(handle->parentNode()); + if (index < 0) { + qDebug () << "FAIL!"; + } +#ifdef DEBUG_C + qDebug() << "Moving handle" << handle << " of node " << handle->parentNode() + << QString(" (%1)").arg(index); + qDebug() << "Parent node x: " << handle->parentNode()->x(); + qDebug() << "Handle x: " << handle->x(); +#endif + + if (index >= 0) { + m_nodes->moveHandle( + handle, + convertCanvasToTime(e->pos())-m_nodes->at(index) + ); + } else { + for (int i = 0; i < m_nodes->size(); i++) { + qDebug() << "Node " << i << " is at " << &m_nodes->at(i); + } + } + } else if (dynamic_cast<const Node_sV*>(m_states.initialContextObject) != nullptr) { + auto *node = (const Node_sV*) m_states.initialContextObject; + + if (!m_states.nodesMoved) { + qDebug() << "Moving node " << node; + } + if (!m_states.moveAborted) { + if (m_states.countsAsMove()) { + if (!node->selected()) { + if (!m_states.selectAttempted) { + m_states.selectAttempted = true; + m_nodes->select(node, !e->modifiers().testFlag(Qt::ControlModifier)); + } + } + if (e->modifiers().testFlag(Qt::ControlModifier)) { + if (qAbs(diff.x()) < qAbs(diff.y())) { + diff.setX(0); + } else { + diff.setY(0); + } + } + //qDebug() << "move selected"; + bool snap = (e->modifiers() & Qt::ShiftModifier); + //TODO qDebug() << "is snap ? " << snap; + m_nodes->moveSelected(diff,snap); + } + } + m_states.nodesMoved = true; + } else { + // Cannot move this object, so move the canvas instead. +// if (m_states.initialContextObject != NULL) { +// qDebug() << "Trying to move " << typeid(*m_states.initialContextObject).name() << ": Not supported yet!"; +// } + + m_t0 = m_states.initial_t0 - diff; + if (m_t0.y() < 0) { m_t0.setY(0); } + if (m_t0.x() < 0) { m_t0.setX(0); } + if (m_t0.y() > m_tmax.y()) { m_t0.setY(m_tmax.y()); } + + } + + } else if (m_mode == ToolMode_Move) { + if (!m_states.moveAborted) { + m_nodes->shift(convertCanvasToTime(m_states.initialMousePos).x(), diff.x()); + } + m_states.nodesMoved = true; + } + } + + // Emit the source time at the mouse position + emit signalMouseInputTimeChanged( + convertCanvasToTime(m_states.prevMousePos).y() + * m_project->frameSource()->fps()->fps() + ); + + + // Emit the source time at the intersection of the out time and the curve + qreal timeOut = convertCanvasToTime(m_states.prevMousePos).x(); + if (m_nodes->size() > 1 && m_nodes->startTime() <= timeOut && timeOut <= m_nodes->endTime()) { + +#ifdef DEBUG_C + std::cout.precision(32); + std::cout << "start: " << m_nodes->startTime() << ", out: " << timeOut << ", end: " << m_nodes->endTime() << std::endl; +#endif + + if (m_nodes->find(timeOut) >= 0) { + emit signalMouseCurveSrcTimeChanged( + m_nodes->sourceTime(timeOut) + * m_project->frameSource()->fps()->fps()); + } + } + + repaint(); +} + +void Canvas::mouseReleaseEvent(QMouseEvent *event) +{ + if (m_states.initialButtons.testFlag(Qt::LeftButton)) { + if (!m_states.moveAborted) { + switch (m_mode) { + case ToolMode_Select: + if (m_states.countsAsMove()) { + m_nodes->confirmMove(); + qDebug() << "Move confirmed."; + emit nodesChanged(); + } else { + if (m_states.initialMousePos.x() >= m_distLeft && m_states.initialMousePos.y() < this->height()-m_distBottom + && !m_states.selectAttempted) { + + // Try to select a node below the mouse. If there is none, add a point. + if (m_states.initialContextObject == nullptr || dynamic_cast<const Node_sV*>(m_states.initialContextObject) == nullptr) { + if (m_mode == ToolMode_Select) { + // check snap to grid + //qDebug()<< event->modifiers(); + bool snap = (event->modifiers() & Qt::ShiftModifier); + //qDebug() << "snap to frame ? " << snap; + + Node_sV p = convertCanvasToTime(m_states.initialMousePos,snap); + //qDebug() << "adding node"; + m_nodes->add(p); + emit nodesChanged(); + } else { + qDebug() << "Not adding node. Mode is " << m_mode; + } + + } else if (dynamic_cast<const Node_sV*>(m_states.initialContextObject) != nullptr) { + m_nodes->select((const Node_sV*) m_states.initialContextObject, !m_states.initialModifiers.testFlag(Qt::ControlModifier)); + } + repaint(); + + } else { + qDebug() << "Not inside bounds."; + } + } + break; + case ToolMode_Move: + m_nodes->confirmMove(); + qDebug() << "Move confirmed."; + emit nodesChanged(); + break; + } + } + } else if (m_states.initialButtons.testFlag(Qt::RightButton) || m_states.initialButtons.testFlag(Qt::MiddleButton)) { + QList<NodeList_sV::PointerWithDistance> nearObjects = m_project->objectsNear(convertCanvasToTime(m_states.initialMousePos).toQPointF(), delta(10)); + +#if _NEARBY_DBG + qDebug() << "Nearby objects:"; + for (int i = 0; i < nearObjects.size(); i++) { + qDebug() << typeid(*(nearObjects.at(i).ptr)).name() << " at distance " << nearObjects.at(i).dist; + } +#endif + } + +} + +void Canvas::contextMenuEvent(QContextMenuEvent *e) +{ + qDebug() << "Context menu requested"; + m_states.contextmenuMouseTime = convertCanvasToTime(e->pos()).toQPointF(); + + QMenu menu; + QMenu speedMenu(trUtf8("Segment replay &speed …"), &menu); + + const CanvasObject_sV *obj = objectAt(e->pos(), m_states.prevModifiers); + + if (dynamic_cast<const Node_sV*>(obj)) { + auto *node = (Node_sV *) obj; + m_toDeleteNode.objectPointer = node; + m_toSnapInNode.objectPointer = node; + + int nodeIndex = m_nodes->indexOf(node); + + menu.addAction(QString(tr("Node %1")).arg(nodeIndex))->setEnabled(false); + menu.addAction(m_aDeleteNode); +// menu.addAction(m_aSnapInNode); // \todo Activate Snap in + menu.addSeparator()->setText(tr("Handle actions")); + menu.addAction(m_aResetLeftHandle); + menu.addAction(m_aResetRightHandle); + + } else if (dynamic_cast<const Segment_sV*>(obj) != nullptr) { + const Segment_sV* segment = (const Segment_sV*) obj; + int leftNode = segment->leftNodeIndex(); + + menu.addAction(QString(tr("Segment between node %1 and %2")).arg(leftNode).arg(leftNode+1))->setEnabled(false); + menu.addAction(m_aLinear); + menu.addAction(m_aBezier); + menu.addAction(m_aShutterFunction); + + speedMenu.addAction(m_aCustomSpeed); + std::vector<QAction*>::iterator it = m_aSpeeds.begin(); + while (it != m_aSpeeds.end()) { + speedMenu.addAction(*it); + it++; + } + menu.addMenu(&speedMenu); + + } else if (dynamic_cast<const Tag_sV*>(obj) != NULL) { + Tag_sV* tag = (Tag_sV*) obj; + m_toDeleteTag.objectPointer = tag; + m_toRenameTag.objectPointer = tag; + m_toSetTagTime.objectPointer = tag; + + menu.addAction(QString(tr("Tag %1")).arg(tag->description())); + menu.addAction(m_aDeleteTag); + menu.addAction(m_aRenameTag); + menu.addAction(m_aSetTagTime); + + } else { + if (obj != NULL) { + qDebug() << "No context menu available for object of type " << typeid(*obj).name(); + } + return; + } + menu.exec(e->globalPos()); +} + +void Canvas::leaveEvent(QEvent *) +{ + m_mouseWithinWidget = false; + repaint(); +} + +void Canvas::keyPressEvent(QKeyEvent *event) +{ + if (dynamic_cast<const Node_sV*>(m_states.initialContextObject) != nullptr) { + const Node_sV *node = (const Node_sV*) m_states.initialContextObject; + + //qDebug() << "node : " << node->x() << "," << node->y(); + qDebug() << "canvas node : " << convertTimeToCanvas(*node); + //qDebug() << "mouse " << m_states.prevMousePos << " vs " << m_states.initialMousePos; + if (!m_states.nodesMoved) { + qDebug() << "should be Moving node " << node; + Node_sV diff; + + switch (event->key()) { + case Qt::Key_Up: + //qDebug() << "key up"; + diff = convertCanvasToTime(QPoint(0,-1))-convertCanvasToTime(QPoint(0,0)); + break; + case Qt::Key_Down: + //qDebug() << "key down"; + diff = convertCanvasToTime(QPoint(0,1))-convertCanvasToTime(QPoint(0,0)); + break; + case Qt::Key_Right: + //qDebug() << "key right"; + diff = convertCanvasToTime(QPoint(1,0))-convertCanvasToTime(QPoint(0,0)); + break; + case Qt::Key_Left: + //qDebug() << "key left"; + diff = convertCanvasToTime(QPoint(-1,0))-convertCanvasToTime(QPoint(0,0)); + break; + } + //qDebug() << "moving of " << diff; + m_nodes->moveSelected(diff); + //TODO: update other windows ? + //TODO: confirm move ? + // from mouserelease + + /*if (m_states.countsAsMove()) */{ + m_nodes->confirmMove(); + //qDebug() << "key Move confirmed."; + emit nodesChanged(); + + repaint(); + } +#if 1 + // from mouse move ? + // Emit the source time at the mouse position + emit signalMouseInputTimeChanged(node->y() + * m_project->frameSource()->fps()->fps() + ); + + //TODO: get right time ! + // Emit the source time at the intersection of the out time and the curve + qreal timeOut = node->x(); + if (m_nodes->size() > 1 && m_nodes->startTime() <= timeOut && timeOut <= m_nodes->endTime()) { + +#ifdef DEBUG_C + std::cout.precision(32); + std::cout << "start: " << m_nodes->startTime() << ", out: " << timeOut << ", end: " << m_nodes->endTime() << std::endl; +#endif + + if (m_nodes->find(timeOut) >= 0) { + emit signalMouseCurveSrcTimeChanged( + timeOut/*m_nodes->sourceTime(timeOut)*/ + * m_project->frameSource()->fps()->fps()); + } + } +#endif // mouse ? + + + } + //event->ignore(); + } + QWidget::keyPressEvent(event); +} + +void Canvas::wheelEvent(QWheelEvent *e) +{ + // Mouse wheel movement in degrees + int deg = e->delta()/8; + + if (e->modifiers().testFlag(Qt::ControlModifier)) { + zoom(deg > 0, e->pos()); + } else if (e->modifiers().testFlag(Qt::ShiftModifier)) { + // Horizontal scrolling + m_t0 -= Node_sV(SCROLL_FACTOR*convertDistanceToTime(QPoint(deg, 0)).x(),0); + if (m_t0.x() < 0) { m_t0.setX(0); } + } else { + //Vertical scrolling + m_t0 += Node_sV(0, SCROLL_FACTOR*convertDistanceToTime(QPoint(deg, 0)).x()); + if (m_t0.y() < 0) { m_t0.setY(0); } + if (m_t0.y() > m_tmax.y()) { m_t0.setY(m_tmax.y()); } + } + + + m_project->preferences()->viewport_t0() = m_t0.toQPointF(); + m_project->preferences()->viewport_secRes().rx() = m_secResX; + m_project->preferences()->viewport_secRes().ry() = m_secResY; + + Q_ASSERT(m_secResX > 0); + Q_ASSERT(m_secResY > 0); + Q_ASSERT(m_t0.x() >= 0); + Q_ASSERT(m_t0.y() >= 0); + + repaint(); +} +void Canvas::zoom(bool in, QPoint pos) +{ + Node_sV n0 = convertCanvasToTime(pos); + + // Update the line resolution + if (in) { + m_secResX *= ZOOM_FACTOR; + } else { + m_secResX /= ZOOM_FACTOR; + } + if (m_secResX < .05) { m_secResX = .05; } + // Y resolution is the same as X resolution (at least at the moment) + m_secResY = m_secResX; +// qDebug() << "Resolution: " << m_secResX; + + // Adjust t0 such that the mouse points to the same time as before + Node_sV nDiff = convertCanvasToTime(pos) - convertCanvasToTime(QPoint(m_distLeft, height()-1-m_distBottom)); + m_t0 = n0 - nDiff; + if (m_t0.x() < 0) { m_t0.setX(0); } + if (m_t0.y() < 0) { m_t0.setY(0); } + + Q_ASSERT(m_secResX > 0); + Q_ASSERT(m_secResY > 0); + Q_ASSERT(m_t0.x() >= 0); + Q_ASSERT(m_t0.y() >= 0); + repaint(); +} +void Canvas::slotZoomIn() +{ + zoom(true, QCursor::pos()); +} +void Canvas::slotZoomOut() +{ + zoom(false, QCursor::pos()); +} + + + +const CanvasObject_sV* Canvas::objectAt(QPoint pos, Qt::KeyboardModifiers modifiers) const +{ + QList<NodeList_sV::PointerWithDistance> nearObjects = + m_project->objectsNear(convertCanvasToTime(pos).toQPointF(), convertDistanceToTime(QPoint(SELECT_RADIUS,0)).x()); + + if (modifiers.testFlag(Qt::ShiftModifier)) { + // Ignore nodes with Shift pressed + while (nearObjects.size() > 0 && dynamic_cast<const Node_sV*>(nearObjects.at(0).ptr) != NULL) { + nearObjects.removeFirst(); + } + } + + if (nearObjects.size() > 0) { + return nearObjects.at(0).ptr; + } else { + return nullptr; + } +} + + + +////////// Conversion Time <--> Screen pixels + +Node_sV Canvas::convertCanvasToTime(const QPoint &p, bool snap) const +{ + Q_ASSERT(m_secResX > 0); + Q_ASSERT(m_secResY > 0); + + QPointF tDelta = convertDistanceToTime(QPoint( + p.x()-m_distLeft, + height()-1 - m_distBottom - p.y() + )); + QPointF tFinal = tDelta + m_t0.toQPointF(); + //qDebug() << "convert: " << tFinal; + if (snap) { + tFinal.setX(int(tFinal.x())); + } + return Node_sV(tFinal.x(), tFinal.y()); +} +QPoint Canvas::convertTimeToCanvas(const Node_sV &p) const +{ + return convertTimeToCanvas(p.toQPointF()); +} +QPoint Canvas::convertTimeToCanvas(const QPointF &p) const +{ + QPoint tDelta = convertTimeToDistance(QPointF( + p.x()-m_t0.x(), + p.y()-m_t0.y() + )); + QPoint out( + tDelta.x() + m_distLeft, + height()-1 - m_distBottom - tDelta.y() + ); + return out; +} +QPointF Canvas::convertDistanceToTime(const QPoint &p) const +{ + QPointF out( + float(p.x()) / m_secResX, + float(p.y()) / m_secResY + ); + return out; +} +QPoint Canvas::convertTimeToDistance(const QPointF &time) const +{ + QPoint out( + time.x()*m_secResX, + time.y()*m_secResY + ); + return out; +} +float Canvas::delta(int px) const +{ + return convertDistanceToTime(QPoint(px, 0)).x(); +} + + + +////////// Slots + +void Canvas::slotAbort(Canvas::Abort abort) +{ + qDebug() << "Signal: " << abort; + switch (abort) { + case Abort_General: + m_states.moveAborted = true; + m_nodes->abortMove(); + repaint(); + break; + case Abort_Selection: + m_nodes->unselectAll(); + repaint(); + break; + } + +} + +void Canvas::slotAddTag() +{ + if (m_mouseWithinWidget) { + TagAddDialog dialog(m_project->preferences()->lastSelectedTagAxis(), this); + + if (dialog.exec() == QDialog::Accepted) { + Tag_sV tag = dialog.buildTag(convertCanvasToTime(m_states.prevMousePos).toQPointF()); + m_project->preferences()->lastSelectedTagAxis() = tag.axis(); + + m_tags->push_back(tag); + qDebug() << "Tag added. Number is now: " << m_tags->size(); + repaint(); + + } else { + qDebug() << "Tag dialog not accepted."; + } + } else { + qDebug() << "Mouse outside widget."; + } +} + +void Canvas::slotDeleteNodes() +{ + qDebug() << "Will delete"; + uint nDel = m_nodes->deleteSelected(); + qDebug() << nDel << " deleted."; + if (nDel > 0) { + repaint(); + emit nodesChanged(); + } +} + +void Canvas::slotSetToolMode(ToolMode mode) +{ + m_mode = mode; + qDebug() << "Mode set to: " << mode; + repaint(); +} + + + + +void Canvas::slotRunAction(QObject *o) +{ + TransferObject *to = (TransferObject*) o; + + qDebug() << "Desired action: " << toString(to->reason); + + if (dynamic_cast<Tag_sV*>(to->objectPointer) != nullptr) { + + /// Tag actions /// + + Tag_sV* tag = (Tag_sV*) to->objectPointer; + qDebug() << " ... on Tag " << tag->description(); + switch (to->reason) { + case TransferObject::ACTION_DELETE: + for (int i = 0; i < m_tags->size(); ++i) { + if (&m_tags->at(i) == tag) { + qDebug() << "Tag found, removing: " << m_tags->at(i).description(); + m_tags->removeAt(i); + break; + } + } + break; + case TransferObject::ACTION_RENAME: + { + bool ok; + QString newName = QInputDialog::getText(this, tr("New tag name"), tr("Tag:"), QLineEdit::Normal, tag->description(), &ok, 0, Qt::ImhNone ); + if (ok) { + tag->setDescription(newName); + } + break; + } + case TransferObject::ACTION_SETTIME: + { + bool ok; + double d = QInputDialog::getDouble(this, tr("New tag time"), tr("Time:"), tag->time(), 0, 424242, 5, &ok); + if (ok) { + tag->setTime(d); + } + break; + } + default: + qDebug() << "Unknown action on Tag: " << toString(to->reason); + Q_ASSERT(false); + break; + } + } else if (dynamic_cast<Node_sV*>(to->objectPointer)) { + + /// Node actions /// + + Node_sV const* node = (Node_sV const*) to->objectPointer; + qDebug() << " ... on node " << *node; + switch (to->reason) { + case TransferObject::ACTION_DELETE: + m_nodes->deleteNode(m_nodes->indexOf(node)); + break; + default: + qDebug() << "Unknown action on Node: " << toString(to->reason); + Q_ASSERT(false); + break; + } + } + + repaint(); +} + +void Canvas::slotChangeCurveType(int curveType) +{ + qDebug() << "Changing curve type to " << toString((CurveType)curveType) << " at " << convertCanvasToTime(m_states.prevMousePos).x(); + m_nodes->setCurveType(convertCanvasToTime(m_states.prevMousePos).x(), (CurveType) curveType); + emit nodesChanged(); +} +void Canvas::slotResetHandle(const QString &position) +{ + if (dynamic_cast<const Node_sV*>(m_states.initialContextObject) != nullptr) { + auto *node = const_cast<Node_sV*>(dynamic_cast<const Node_sV*>(m_states.initialContextObject)); + if (position == "left") { + node->setLeftNodeHandle(0, 0); + } else { + node->setRightNodeHandle(0, 0); + } + emit nodesChanged(); + } else { + qDebug() << "Object at mouse position is " << m_states.initialContextObject << ", cannot reset the handle."; + } +} + +/** + * + */ +void Canvas::setCurveSpeed(double speed) +{ + QString message; + + qDebug() << "Setting curve to " << speed << "x speed."; + int errcode = m_nodes->setSpeed(convertCanvasToTime(m_states.prevMousePos).x(), speed); + //TODO: should find a better way ... (try/catch ?) + switch (errcode) { + case -1: + message = tr("%1 x speed would shoot over maximum time. Correcting.").arg(speed); + QMessageBox(QMessageBox::Warning, tr("Warning"), message, QMessageBox::Ok).exec(); + break; + case -2: + message = tr("%1 x speed goes below 0. Correcting.").arg(speed); + QMessageBox(QMessageBox::Warning, tr("Warning"), message, QMessageBox::Ok).exec(); + break; + case -3: + message = tr("New node would be too close, not adding it."); + QMessageBox(QMessageBox::Warning, tr("Warning"), message, QMessageBox::Ok).exec(); + break; + case -4 : + message = tr("Outside segment."); + QMessageBox(QMessageBox::Warning, tr("Warning"), message, QMessageBox::Ok).exec(); + break; + } + emit nodesChanged(); + repaint(); +} + + +void Canvas::slotSetSpeed() +{ + bool ok = true; + + double d = m_settings.value("canvas/replaySpeed", 1.0).toDouble(); + qDebug() << "Getting: " << d; + d = QInputDialog::getDouble(this, tr("Replay speed for current segment"), tr("Speed:"), d, -1000, 1000, 3, &ok); + if (ok) { + setCurveSpeed(d); + m_settings.setValue("canvas/replaySpeed", d); + qDebug() << "Setting: " << d; + } +} +void Canvas::slotSetSpeed(QString s) +{ + bool ok = true; + double d = s.toDouble(&ok); + if (ok) { + setCurveSpeed(d); + } else { + qDebug() << "Not ok: " << s; + } +} +void Canvas::slotSetShutterFunction() +{ + int left = m_nodes->find(m_states.contextmenuMouseTime.x()); + if (left == m_nodes->size()-1) { + left = m_nodes->size()-2; + } + + if (m_shutterFunctionDialog == nullptr) { + m_shutterFunctionDialog = new ShutterFunctionDialog(m_project, this); + connect(this, SIGNAL(nodesChanged()), m_shutterFunctionDialog, SLOT(slotNodesUpdated())); + } + + m_shutterFunctionDialog->setSegment(left); + if (!m_shutterFunctionDialog->isVisible()) { + m_shutterFunctionDialog->show(); + } + +} + +QDebug operator <<(QDebug qd, const Canvas::ToolMode &mode) +{ + switch(mode) { + case Canvas::ToolMode_Select: + qd << "Select tool"; + break; + case Canvas::ToolMode_Move: + qd << "Move tool"; + break; + } + return qd.maybeSpace(); +} + +QDebug operator <<(QDebug qd, const Canvas::Abort &abort) +{ + switch(abort) { + case Canvas::Abort_General: + qd << "Abort General"; + break; + case Canvas::Abort_Selection: + qd << "Abort Selection"; + break; + } + return qd.maybeSpace(); +} + +QString toString(TransferObject::Reason reason) +{ + switch (reason) { + case TransferObject::ACTION_DELETE : + return "Delete"; + case TransferObject::ACTION_SNAPIN : + return "Snap in"; + case TransferObject::ACTION_RENAME : + return "Rename"; + case TransferObject::ACTION_SETTIME : + return "Set time"; + default : + Q_ASSERT(false); + return "Unknown action"; + } +}
View file
slowmoVideo-0.6.tar.xz/src/slowmoUI/canvas.h
Added
@@ -0,0 +1,255 @@ +/* +slowmoUI is a user interface for slowmoVideo. +Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +*/ + +#ifndef CANVAS_H +#define CANVAS_H + +#include "../project/node_sV.h" +#include "../project/nodeList_sV.h" +#include "../project/project_sV.h" +#include "../project/tag_sV.h" + +#include <QWidget> +#include <QList> +#include <QSettings> + + + +#define NODE_RADIUS 6 +#define SELECT_RADIUS 12 +#define HANDLE_RADIUS 4 +#define MOVE_THRESHOLD 3 +#define SCROLL_FACTOR 3 +#define ZOOM_FACTOR 1.414 + + + +class QColor; +class QPoint; +class CanvasTools; +class ShutterFunctionDialog; + +namespace Ui { + class Canvas; +} + + + +/** + This class is for building helper objects for the signals&slots mechanism + for passing pointers to objects which are not QObjects. + */ +class TransferObject : public QObject { + Q_OBJECT + +public: + CanvasObject_sV* objectPointer; + enum Reason { + ACTION_DELETE, + ACTION_RENAME, + ACTION_SETTIME, + ACTION_SNAPIN + } reason; + + + TransferObject() : objectPointer(NULL), reason(ACTION_SNAPIN) {} + TransferObject(CanvasObject_sV* objectPointer, Reason reason) : + objectPointer(objectPointer), reason(reason) {} +}; + + +class Project_sV; + +/** + \brief Canvas for drawing motion curves. + + \todo Frame lines on high zoom + \todo Custom speed factor to next node + */ +class Canvas : public QWidget +{ + Q_OBJECT + + friend class CanvasTools; + +public: + explicit Canvas(Project_sV *project, QWidget *parent = 0); + ~Canvas(); + + enum ToolMode { ToolMode_Select, ToolMode_Move }; + enum Abort { Abort_General, Abort_Selection }; + + static QColor lineCol; + static QColor selectedLineCol; + static QColor nodeCol; + static QColor gridCol; + static QColor fatGridCol; + static QColor minGridCol; + static QColor selectedCol; + static QColor hoverCol; + static QColor srcTagCol; + static QColor outTagCol; + static QColor handleLineCol; + static QColor backgroundCol; + static QColor shutterRegionCol; + static QColor shutterRegionBoundCol; + + void load(Project_sV *project); + + void showHelp(bool show); + void toggleHelp(); + + const QPointF prevMouseTime() const; + const float prevMouseInFrame() const; + +public slots: + void slotAbort(Canvas::Abort abort); + void slotAddTag(); + void slotDeleteNodes(); + void slotSetToolMode(Canvas::ToolMode mode); + +signals: + void signalMouseInputTimeChanged(qreal frame); + void signalMouseCurveSrcTimeChanged(qreal frame); + void nodesChanged(); + +protected: + void paintEvent(QPaintEvent *); + void mouseMoveEvent(QMouseEvent *); + void mousePressEvent(QMouseEvent *); + void mouseReleaseEvent(QMouseEvent *); + void wheelEvent(QWheelEvent *); + void keyPressEvent(QKeyEvent *event); + void leaveEvent(QEvent *); + void contextMenuEvent(QContextMenuEvent *); + +private: + Ui::Canvas *ui; + QSettings m_settings; + Project_sV *m_project; + ShutterFunctionDialog *m_shutterFunctionDialog; + bool m_mouseWithinWidget; + int m_distLeft; + int m_distBottom; + int m_distRight; + int m_distTop; + Node_sV m_t0; ///< Viewport, bottom left + Node_sV m_tmax; ///< Upper bounds for the viewport (so the user does not get lost by zooming too far up) + float m_secResX; ///< How many pixels wide is one output second? + float m_secResY; ///< How many pixels wide is one input second? + + bool m_showHelp; + + NodeList_sV *m_nodes; + QList<Tag_sV> *m_tags; + + ToolMode m_mode; + /** + Saves states about mouse events. + The prev... variables are updated when the mouse moves, + the initial... variables only on mouse clicks. + */ + struct { + bool nodesMoved; + bool selectAttempted; + bool moveAborted; + + QPoint prevMousePos; + QPoint initialMousePos; + QPointF contextmenuMouseTime; + Node_sV initial_t0; + + Qt::KeyboardModifiers prevModifiers; + Qt::KeyboardModifiers initialModifiers; + + Qt::MouseButtons initialButtons; + + const CanvasObject_sV *initialContextObject; + + void reset() { + moveAborted = false; + nodesMoved = false; + selectAttempted = false; + initialContextObject = NULL; + travelledDistance = 0; + } + void travel(int length) { travelledDistance += length; } + bool countsAsMove() { return travelledDistance >= MOVE_THRESHOLD; } + + private: + int travelledDistance; + } m_states; + + /* + The transfer objects to each action defines the action to take + when the slot is called, and additionally stores a pointer to the + object it was called on (the object is known in the context menu event). + */ + QAction *m_aDeleteNode; TransferObject m_toDeleteNode; + QAction *m_aSnapInNode; TransferObject m_toSnapInNode; + QAction *m_aDeleteTag; TransferObject m_toDeleteTag; + QAction *m_aRenameTag; TransferObject m_toRenameTag; + QAction *m_aSetTagTime; TransferObject m_toSetTagTime; + QSignalMapper *m_hackMapper; + + QSignalMapper *m_curveTypeMapper; + QSignalMapper *m_handleMapper; + QSignalMapper *m_speedsMapper; + QAction *m_aLinear; + QAction *m_aBezier; + QAction *m_aResetLeftHandle; + QAction *m_aResetRightHandle; + QAction *m_aCustomSpeed; + QAction *m_aShutterFunction; + std::vector<QAction *> m_aSpeeds; + + Node_sV convertCanvasToTime(const QPoint &p, bool snap = false) const; + QPoint convertTimeToCanvas(const Node_sV &p) const; + QPoint convertTimeToCanvas(const QPointF &p) const; + QPointF convertDistanceToTime(const QPoint &p) const; + QPoint convertTimeToDistance(const QPointF &time) const; + + /** \return The distance in px converted to time */ + float delta(int px) const; + + bool insideCanvas(const QPoint& pos); + + bool selectAt(const QPoint& pos, bool addToSelection = false); + + void drawModes(QPainter &davinci, int top, int right); + + const CanvasObject_sV* objectAt(QPoint pos, Qt::KeyboardModifiers modifiers) const; + + void setCurveSpeed(double speed); + +private slots: + void slotRunAction(QObject *o); + void slotChangeCurveType(int curveType); + void slotResetHandle(const QString &position); + void slotSetSpeed(); + void slotSetSpeed(QString s); + void slotSetShutterFunction(); + void slotZoomIn(); + void slotZoomOut(); + +private: + void zoom(bool in, QPoint pos); + + QRect leftDrawingRect(int y, const int height = 12, const int min = -1, const int max = -1) const; + QRect bottomDrawingRect(int x, const int width = 160, const int min = -1, const int max = -1, bool rightJustified = true) const; + +}; + +QDebug operator<<(QDebug qd, const Canvas::ToolMode &mode); +QDebug operator<<(QDebug qd, const Canvas::Abort &abort); + +QString toString(TransferObject::Reason reason); + +#endif // CANVAS_H
View file
slowmoVideo-0.6.tar.xz/src/slowmoUI/canvas.ui
Changed
(renamed from src/slowmoVideo/slowmoUI/canvas.ui)
View file
slowmoVideo-0.6.tar.xz/src/slowmoUI/canvasTools.cpp
Changed
(renamed from src/slowmoVideo/slowmoUI/canvasTools.cpp)
View file
slowmoVideo-0.6.tar.xz/src/slowmoUI/canvasTools.h
Changed
(renamed from src/slowmoVideo/slowmoUI/canvasTools.h)
View file
slowmoVideo-0.6.tar.xz/src/slowmoUI/dialogues
Added
+(directory)
View file
slowmoVideo-0.6.tar.xz/src/slowmoUI/dialogues/aboutDialog.cpp
Changed
(renamed from src/slowmoVideo/slowmoUI/dialogues/aboutDialog.cpp)
View file
slowmoVideo-0.6.tar.xz/src/slowmoUI/dialogues/aboutDialog.h
Changed
(renamed from src/slowmoVideo/slowmoUI/dialogues/aboutDialog.h)
View file
slowmoVideo-0.6.tar.xz/src/slowmoUI/dialogues/aboutDialog.ui
Added
@@ -0,0 +1,173 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>AboutDialog</class> + <widget class="QDialog" name="AboutDialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>903</width> + <height>354</height> + </rect> + </property> + <property name="windowTitle"> + <string>About</string> + </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="1" column="1"> + <widget class="QLabel" name="label"> + <property name="font"> + <font> + <family>Gentium Basic</family> + <pointsize>19</pointsize> + <weight>75</weight> + <bold>true</bold> + </font> + </property> + <property name="text"> + <string>About slowmoVideo</string> + </property> + </widget> + </item> + <item row="3" column="0" colspan="2"> + <widget class="QLabel" name="label_2"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Bitstream Vera Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-style:italic;">slowmoVideo</span> is developed by Simon A. Eugster (aka. Granjow, co-author of Kdenlive) and licensed under GPLv3.</p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-style:italic;">slowmoVideo</span> allows to change the speed of a video clip based upon a curve. If the speed becomes higher than 1×, an exposure (shutter) effect simulates motion blur. For lower speed, frames are interpolated with optical flow.</p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Thanks for contributing:</p> +<ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Mirko Götze <span style=" font-style:italic;">&lt;mail@mgo80.de&gt;</span> for converting <span style=" font-weight:600;">Cg to GLSL</span> (Removing the nVidia dependency)</li> +<li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Morten Sylvest Olsen <span style=" font-style:italic;">&lt;mso@kapowsoftware.com&gt;</span> for the <span style=" font-weight:600;">V3D speedup</span> and removing the unnecessary window</li> +<li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Elias Vanderstuyft for displaying the <span style=" font-weight:600;">shutter function</span> on the canvas</li> +<li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Christian Frisson <span style=" font-style:italic;">&lt;christian.frisson@umons.ac.be&gt;</span> for<span style=" font-weight:600;"> OpenCV on MXE</span> (allowed me to compile slowmoVideo for Windows)</li> +<li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Per <span style=" font-style:italic;">&lt;per@stuffmatic.com&gt;</span> for the<span style=" font-weight:600;"> OpenCV</span> code (slowmoVideo can run on CPU only with it)</li></ul> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Visit <a href="http://slowmoVideo.granjow.net"><span style=" text-decoration: underline; color:#0057ae;">slowmoVideo.granjow.net</span></a> for more information.</p></body></html></string> + </property> + <property name="textFormat"> + <enum>Qt::RichText</enum> + </property> + <property name="wordWrap"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="1" column="0"> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="2" column="0"> + <spacer name="verticalSpacer_2"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="0" column="0"> + <spacer name="verticalSpacer_3"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>10</height> + </size> + </property> + </spacer> + </item> + <item row="7" column="0" colspan="2"> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QLabel" name="lblVersion"> + <property name="font"> + <font> + <pointsize>8</pointsize> + </font> + </property> + <property name="text"> + <string notr="true">version number goes here.</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="label_3"> + <property name="font"> + <font> + <pointsize>8</pointsize> + </font> + </property> + <property name="text"> + <string>(c) 2012–2020 Simon A. Eugster</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + </widget> + </item> + </layout> + </item> + <item row="5" column="0"> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <item> + <widget class="QFrame" name="iconFrame"> + <property name="frameShape"> + <enum>QFrame::NoFrame</enum> + </property> + <property name="frameShadow"> + <enum>QFrame::Raised</enum> + </property> + </widget> + </item> + <item> + <spacer name="verticalSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + </layout> + </widget> + <resources/> + <connections/> +</ui>
View file
slowmoVideo-0.6.tar.xz/src/slowmoUI/dialogues/flowExaminer.cpp
Added
@@ -0,0 +1,172 @@ +#include "flowExaminer.h" +#include "ui_flowExaminer.h" +#include "project/project_sV.h" +#include "project/abstractFrameSource_sV.h" +#include "lib/flowVisualization_sV.h" + +#include <QtCore/QDebug> +#include <QtGui/QPainter> +#include <QKeyEvent> + +FlowExaminer::FlowExaminer(Project_sV *project, QWidget *parent) : + QDialog(parent), + ui(new Ui::FlowExaminer), + m_project(project), + m_flowLR(NULL), + m_flowRL(NULL) +{ + ui->setupUi(this); +// ui->leftFrame->trackMouse(true); +// ui->rightFrame->trackMouse(true); + + connect(ui->leftFrame, SIGNAL(signalMouseMoved(float,float)), this, SLOT(slotMouseMoved(float,float))); + connect(ui->rightFrame, SIGNAL(signalMouseMoved(float,float)), this, SLOT(slotMouseMoved(float,float))); + connect(ui->bClose, SIGNAL(clicked()), this, SLOT(close())); + + connect(ui->amplification, SIGNAL(valueChanged(int)),this, SLOT(newAmplification(int))); + + connect(this, SIGNAL(frameChanged()),this, SLOT(updateFlow())); +} + +FlowExaminer::~FlowExaminer() +{ + delete ui; + if (m_flowLR != NULL) { + delete m_flowLR; + } + if (m_flowRL != NULL) { + delete m_flowRL; + } +} + +/// \todo Make flow visualization configurable +void FlowExaminer::examine(int leftFrame) +{ + frame = leftFrame; + frame= 0; + loadFlow();; +} + +void FlowExaminer::loadFlow() +{ + if (m_flowLR != NULL) { + delete m_flowLR; + m_flowLR = NULL; + } + if (m_flowRL != NULL) { + delete m_flowRL; + m_flowRL = NULL; + } + try { + m_flowLR = m_project->requestFlow(frame, frame+1, FrameSize_Orig); + m_flowRL = m_project->requestFlow(frame+1, frame, FrameSize_Orig); + ui->leftFrame->loadImage(m_project->frameSource()->frameAt(frame, FrameSize_Orig)); + ui->rightFrame->loadImage(m_project->frameSource()->frameAt(frame+1, FrameSize_Orig)); + ui->leftFlow->loadImage(FlowVisualization_sV::colourizeFlow(m_flowLR, FlowVisualization_sV::HSV,m_boost)); + ui->rightFlow->loadImage(FlowVisualization_sV::colourizeFlow(m_flowRL, FlowVisualization_sV::HSV,m_boost)); + emit updateFlow(); + } catch (FlowBuildingError &err) { } + + //repaint(); +} + +void FlowExaminer::updateFlow() +{ + ui->leftFrame->update(); + ui->rightFrame->update(); + ui->leftFlow->update(); + ui->rightFlow->update(); +} + +void FlowExaminer::newAmplification(int val) +{ + //qDebug() << "newAmplification: " << val; + Q_ASSERT(val > 0); + m_boost = (float)val; + // reload flow with new gain + loadFlow(); +} + + +/// \todo Show vectors etc. +void FlowExaminer::slotMouseMoved(float x, float y) +{ + if (QObject::sender() == ui->leftFrame) { + qDebug() << "Should display something in the right frame now."; + if (m_flowLR != NULL) { + float moveX = m_flowLR->x(x,y); + float moveY = m_flowLR->y(x,y); + QImage leftOverlay(m_flowLR->width(), m_flowLR->height(), QImage::Format_ARGB32); + QImage rightOverlay(leftOverlay.size(), QImage::Format_ARGB32); + QPainter davinci; + + davinci.begin(&leftOverlay); + davinci.drawLine(x, y, x+moveX, y+moveY); + davinci.end(); + + qDebug() << "Line coordinates: " << x << y << moveX << moveY; + bool ok; + ok = ui->leftFrame->loadOverlay(leftOverlay); + Q_ASSERT(ok); + + davinci.begin(&rightOverlay); + davinci.drawEllipse(x+moveX, y+moveY, 2, 2); + davinci.end(); + + ui->rightFrame->loadOverlay(rightOverlay); + + repaint(); + } else { + qDebug() << "Flow is 0!"; + } + } else if (QObject::sender() == ui->rightFrame) { + qDebug() << "Should display something in the left frame now."; + + } else { + qDebug() << "Unknown sender!"; + Q_ASSERT(false); + } +} + +void FlowExaminer::keyPressEvent(QKeyEvent *event) +{ + //qDebug() << "keypressed : " << event->key(); + switch (event->key()) { + case Qt::Key_Up: + qDebug() << "key up"; + //m_states.prevMousePos += QPoint(0,-1); + break; + case Qt::Key_Down: + qDebug() << "key down"; + //m_states.prevMousePos += QPoint(0,1); + break; + case Qt::Key_Right: + qDebug() << "key right"; + //m_states.prevMousePos += QPoint(1,0); + frame++; + loadFlow(); + break; + case Qt::Key_Left: + qDebug() << "key left"; + //m_states.prevMousePos += QPoint(-1,0); + frame--; + loadFlow(); + break; + } + QWidget::keyPressEvent(event); + //repaint(); +} + +void FlowExaminer::wheelEvent(QWheelEvent *event) +{ + int numDegrees = event->delta() / 8; + int numSteps = numDegrees / 15; + + if (event->orientation() == Qt::Horizontal) { + qDebug() << "wheel : horiz " << numSteps; + } else { + qDebug() << "wheel : vert " << numSteps; + } + qDebug() << "in wheel"; + event->accept(); +}
View file
slowmoVideo-0.6.tar.xz/src/slowmoUI/dialogues/flowExaminer.h
Added
@@ -0,0 +1,49 @@ +#ifndef FLOWEXAMINER_H +#define FLOWEXAMINER_H + +#include <QDialog> + +namespace Ui { + class FlowExaminer; +} +class Project_sV; +class FlowField_sV; + +class FlowExaminer : public QDialog +{ + Q_OBJECT + +public: + explicit FlowExaminer(Project_sV *project, QWidget *parent = 0); + ~FlowExaminer(); + + void examine(int leftFrame); + void loadFlow(); + +private: + Ui::FlowExaminer *ui; + + Project_sV *m_project; + FlowField_sV *m_flowLR; + FlowField_sV *m_flowRL; + + // current frame + int frame; + // color flow amplification + float m_boost; +private slots: + void slotMouseMoved(float x, float y); + void updateFlow(); + +public slots: + void newAmplification(int val); + +protected: + void wheelEvent(QWheelEvent *); + void keyPressEvent(QKeyEvent *event); + +signals: + void frameChanged(); +}; + +#endif // FLOWEXAMINER_H
View file
slowmoVideo-0.6.tar.xz/src/slowmoUI/dialogues/flowExaminer.ui
Added
@@ -0,0 +1,139 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>FlowExaminer</class> + <widget class="QDialog" name="FlowExaminer"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>918</width> + <height>603</height> + </rect> + </property> + <property name="windowTitle"> + <string notr="true">Dialog</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="ImageDisplay" name="leftFrame"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Expanding"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="frameShape"> + <enum>QFrame::StyledPanel</enum> + </property> + <property name="frameShadow"> + <enum>QFrame::Raised</enum> + </property> + </widget> + </item> + <item> + <widget class="ImageDisplay" name="rightFrame"> + <property name="frameShape"> + <enum>QFrame::StyledPanel</enum> + </property> + <property name="frameShadow"> + <enum>QFrame::Raised</enum> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <item> + <widget class="ImageDisplay" name="leftFlow"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Expanding"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="frameShape"> + <enum>QFrame::StyledPanel</enum> + </property> + <property name="frameShadow"> + <enum>QFrame::Raised</enum> + </property> + </widget> + </item> + <item> + <widget class="ImageDisplay" name="rightFlow"> + <property name="frameShape"> + <enum>QFrame::StyledPanel</enum> + </property> + <property name="frameShadow"> + <enum>QFrame::Raised</enum> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_3"> + <item> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Amplification : </string> + </property> + </widget> + </item> + <item> + <widget class="QSlider" name="amplification"> + <property name="maximum"> + <number>40</number> + </property> + <property name="value"> + <number>10</number> + </property> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="tickPosition"> + <enum>QSlider::TicksBelow</enum> + </property> + <property name="tickInterval"> + <number>1</number> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>0</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="bClose"> + <property name="text"> + <string>Close</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + <customwidgets> + <customwidget> + <class>ImageDisplay</class> + <extends>QFrame</extends> + <header>libgui/imageDisplay.h</header> + <container>1</container> + </customwidget> + </customwidgets> + <resources/> + <connections/> +</ui>
View file
slowmoVideo-0.6.tar.xz/src/slowmoUI/dialogues/newProjectDialog.cpp
Added
@@ -0,0 +1,239 @@ +/* +slowmoUI is a user interface for slowmoVideo. +Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +*/ + +#include "newProjectDialog.h" +#include "ui_newProjectDialog.h" + +#include "project/videoFrameSource_sV.h" +#include "project/imagesFrameSource_sV.h" + + +#include <QtCore/QFile> +#include <QtCore/QDir> + +#include <QFileDialog> +#include <QButtonGroup> + +NewProjectDialog::NewProjectDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::NewProjectDialog) +{ + ui->setupUi(this); + + m_buttonGroup = new QButtonGroup(this); + m_buttonGroup->addButton(ui->radioVideo); + m_buttonGroup->addButton(ui->radioImages); + ui->radioVideo->setChecked(true); + + ui->projectDir->setText(m_settings.value("directories/lastProjectDir", QDir::current().absolutePath()).toString()); + m_videoInfo.streamsCount = 0; + + connect(ui->browseInputVideo, SIGNAL(clicked()), this, SLOT(slotSelectVideoFile())); + connect(ui->browseInputImages, SIGNAL(clicked()), this, SLOT(slotSelectImages())); + connect(ui->browseProjectDir, SIGNAL(clicked()), this, SLOT(slotSelectProjectDir())); + connect(ui->inputVideo, SIGNAL(textChanged(QString)), this, SLOT(slotUpdateVideoInfo())); + connect(ui->projectDir, SIGNAL(textChanged(QString)), this, SLOT(slotUpdateButtonStates())); + connect(ui->projectFilename, SIGNAL(textChanged(QString)), this, SLOT(slotUpdateButtonStates())); + + connect(ui->bAbort, SIGNAL(clicked()), this, SLOT(reject())); + connect(ui->bOk, SIGNAL(clicked()), this, SLOT(accept())); + + connect(m_buttonGroup, SIGNAL(buttonClicked(int)), this, SLOT(slotUpdateFrameSourceType())); + + slotUpdateImagesInfo(); + slotUpdateVideoInfo(); + slotUpdateButtonStates(); + slotUpdateFrameSourceType(); +} + +NewProjectDialog::~NewProjectDialog() +{ + delete ui; + delete m_buttonGroup; +} + +Project_sV* NewProjectDialog::buildProject() noexcept(false) +{ + Project_sV *project = new Project_sV(ui->projectDir->text()); + AbstractFrameSource_sV *frameSource = NULL; + if (ui->radioVideo->isChecked()) { + frameSource = new VideoFrameSource_sV(project, ui->inputVideo->text()); + m_settings.setValue("directories/lastInputVideo", QFileInfo(ui->inputVideo->text()).absolutePath()); + } else { + frameSource = new ImagesFrameSource_sV(project, m_images); + m_settings.setValue("directories/lastInputImage", QFileInfo(m_images.last()).absolutePath()); + } + project->loadFrameSource(frameSource); + + m_settings.setValue("directories/lastProjectDir", ui->projectDir->text()); + m_settings.setValue("directories/lastProjectDir", ui->projectDir->text()); + + return project; +} +const QString NewProjectDialog::projectFilename() const +{ + return QString(ui->projectDir->text() + "/" + ui->projectFilename->text() + ".sVproj"); +} + +void NewProjectDialog::slotSelectVideoFile() +{ + QFileDialog dialog(this, tr("Select input video file")); + dialog.setAcceptMode(QFileDialog::AcceptOpen); + dialog.setFileMode(QFileDialog::ExistingFile); + if (ui->inputVideo->text().length() > 0) { + dialog.setDirectory(ui->inputVideo->text()); + } else { + dialog.setDirectory(m_settings.value("directories/lastInputVideo", QDir::homePath()).toString()); + } + if (dialog.exec() == QDialog::Accepted) { + ui->inputVideo->setText(dialog.selectedFiles().at(0)); + ui->txtVideoInfo->clear(); + + slotUpdateVideoInfo(); + + if (m_videoInfo.streamsCount <= 0) { + // No video stream found. Check if the path contains a non-ASCII character and warn if this is the case. + unsigned char ascii; + for (int i = 0; i < ui->inputVideo->text().length(); i++) { + ascii = ui->inputVideo->text().at(i).toLatin1(); + if (ascii == 0 || ascii > 0x7f) { + ui->txtVideoInfo->appendPlainText( + tr("Character %1 is not an ASCII character. This file path will likely not work with ffmpeg.") + .arg(ui->inputVideo->text().at(i))); + break; + } + } + } + } +} + +void NewProjectDialog::slotSelectImages() +{ + QFileDialog dialog(this, tr("Select input images")); + dialog.setAcceptMode(QFileDialog::AcceptOpen); + dialog.setFileMode(QFileDialog::ExistingFiles); + if (m_images.size() > 0) { + dialog.setDirectory(QFileInfo(m_images.last()).absolutePath()); + } else { + dialog.setDirectory(m_settings.value("directories/lastInputImage", QDir::homePath()).toString()); + } + if (dialog.exec() == QDialog::Accepted) { + + m_images = dialog.selectedFiles(); + + ui->inputImages->clear(); + for (int i = 0; i < m_images.size(); i++) { + new QListWidgetItem(m_images.at(i), ui->inputImages); + } + + slotUpdateImagesInfo(); + } +} + +void NewProjectDialog::slotSelectProjectDir() +{ + QFileDialog dialog(this, tr("Select a project directory")); + dialog.setAcceptMode(QFileDialog::AcceptOpen); + dialog.setFileMode(QFileDialog::Directory); + if (ui->projectDir->text().length() > 0) { + dialog.setDirectory(ui->projectDir->text()); + } else { + dialog.setDirectory(m_settings.value("directories/lastProjectDir").toString()); + } + if (dialog.exec() == QDialog::Accepted) { + ui->projectDir->setText(dialog.selectedFiles().at(0)); + slotUpdateButtonStates(); + } +} + +void NewProjectDialog::slotUpdateVideoInfo() +{ + QFile file(ui->inputVideo->text()); + if (file.exists()) { + m_videoInfo = getInfo(ui->inputVideo->text().toStdString().c_str()); + QString text = trUtf8("Number of video streams: %1\nFrames: %2\nSize: %3×%4\n") + .arg(m_videoInfo.streamsCount).arg(m_videoInfo.framesCount) + .arg(m_videoInfo.width).arg(m_videoInfo.height); + text.append(tr("Frame rate: %1/%2").arg(m_videoInfo.frameRateNum).arg(m_videoInfo.frameRateDen)); + ui->txtVideoInfo->setPlainText(text); + } else { + m_videoInfo.streamsCount = 0; + ui->txtVideoInfo->setPlainText(tr("No video stream detected.")); + } + slotUpdateButtonStates(); +} + +void NewProjectDialog::slotUpdateImagesInfo() +{ + m_imagesMsg = ImagesFrameSource_sV::validateImages(m_images); + slotUpdateButtonStates(); +} + +void NewProjectDialog::slotUpdateButtonStates() +{ + bool ok = true; + + if (ui->projectDir->text().length() > 0) { + QDir dir(ui->projectDir->text()); + ui->cbDirectoryCreated->setChecked(!dir.exists()); + ui->projectDir->setStyleSheet(QString("QLineEdit { background-color: %1; }").arg(Colours_sV::colOk.name())); + m_projectDir = ui->projectDir->text(); + } else { + ui->projectDir->setStyleSheet(QString("QLineEdit { background-color: %1; }").arg(Colours_sV::colBad.name())); + ok = false; + } + QFile projectFile(projectFilename()); + if (ui->projectFilename->text().length() > 0 && !projectFile.exists()) { + ui->projectFilename->setStyleSheet(QString("QLineEdit { background-color: %1; }").arg(Colours_sV::colOk.name())); + } else { + ui->projectFilename->setStyleSheet(QString("QLineEdit { background-color: %1; }").arg(Colours_sV::colBad.name())); + ok = false; + } + + if (ui->radioVideo->isChecked()) { + // Validate the video file +#if 0 + // ubuntu can't handle mp4 correctly ? + if (m_videoInfo.streamsCount > 0 && m_videoInfo.framesCount > 0) { +#else + if (m_videoInfo.streamsCount > 0) { +#endif + ui->inputVideo->setStyleSheet(QString("QLineEdit { background-color: %1; }").arg(Colours_sV::colOk.name())); + m_inputFile = ui->inputVideo->text(); + } else { + ui->inputVideo->setStyleSheet(QString("QLineEdit { background-color: %1; }").arg(Colours_sV::colBad.name())); + ok = false; + } + } else if (ui->radioImages->isChecked()) { + // Validate the images + if (m_imagesMsg.length() == 0) { + ui->inputImages->setStyleSheet(QString("QListWidget { background-color: %1; }").arg(Colours_sV::colOk.name())); + ui->txtImageInfo->setText(tr("Image size: %1").arg(toString(QImage(m_images.at(0)).size()))); + } else { + ui->inputImages->setStyleSheet(QString("QListWidget { background-color: %1; }").arg(Colours_sV::colBad.name())); + ui->txtImageInfo->setText(m_imagesMsg); + ok = false; + } + } + + ui->bOk->setEnabled(ok); +} + +void NewProjectDialog::slotUpdateFrameSourceType() +{ + ui->groupImages->setEnabled(ui->radioImages->isChecked()); + ui->groupImages->setVisible(ui->radioImages->isChecked()); + ui->groupVideo->setEnabled(ui->radioVideo->isChecked()); + ui->groupVideo->setVisible(ui->radioVideo->isChecked()); + slotUpdateButtonStates(); + QSize prevSize = size(); + adjustSize(); + resize(prevSize.width(), size().height()); +}
View file
slowmoVideo-0.6.tar.xz/src/slowmoUI/dialogues/newProjectDialog.h
Added
@@ -0,0 +1,65 @@ +/* +slowmoUI is a user interface for slowmoVideo. +Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +*/ + +#ifndef NEWPROJECTDIALOG_H +#define NEWPROJECTDIALOG_H + +#include <QDialog> +#include <QtCore/QStringList> +#include <QSettings> + +#include "project/project_sV.h" + +#include "lib/videoInfo_sV.h" + +namespace Ui { + class NewProjectDialog; +} + +class QButtonGroup; + +class NewProjectDialog : public QDialog +{ + Q_OBJECT + +public: + explicit NewProjectDialog(QWidget *parent = 0); + ~NewProjectDialog(); + + QString m_inputFile; + QString m_projectDir; + + Project_sV* buildProject() noexcept(false); + const QString projectFilename() const; + +private: + Ui::NewProjectDialog *ui; + QButtonGroup *m_buttonGroup; + + VideoInfoSV m_videoInfo; + QStringList m_images; + QString m_imagesMsg; + + QSettings m_settings; + + +private slots: + void slotSelectProjectDir(); + void slotSelectVideoFile(); + void slotSelectImages(); + + void slotUpdateVideoInfo(); + void slotUpdateImagesInfo(); + + void slotUpdateButtonStates(); + void slotUpdateFrameSourceType(); +}; + +#endif // NEWPROJECTDIALOG_H
View file
slowmoVideo-0.6.tar.xz/src/slowmoUI/dialogues/newProjectDialog.ui
Changed
(renamed from src/slowmoVideo/slowmoUI/dialogues/newProjectDialog.ui)
View file
slowmoVideo-0.6.tar.xz/src/slowmoUI/dialogues/preferencesDialog.cpp
Added
@@ -0,0 +1,190 @@ +#include "preferencesDialog.h" +#include "ui_preferencesDialog.h" + +#include "project/flowSourceV3D_sV.h" +#include "lib/defs_sV.hpp" +#include "lib/avconvInfo_sV.h" +#include <QtCore/QProcess> +#include <QFileDialog> +#include <sstream> + +PreferencesDialog::PreferencesDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::PreferencesDialog) +{ + ui->setupUi(this); + ui->buildFlow->setText(m_settings.value("binaries/v3dFlowBuilder", "").toString()); + ui->ffmpeg->setText(m_settings.value("binaries/ffmpeg", "ffmpeg").toString()); + ui->buildFlow->setPlaceholderText(QApplication::translate("PreferencesDialog", "flowBuilder binary location", 0)); + +// TODO: qcombox box instead ? + m_flowMethodGroup.addButton(ui->methodOCV,-1); + m_flowMethodGroup.addButton(ui->methodV3D,-1); + m_flowMethodGroup.addButton(ui->methodOCL,-1); + m_flowMethodGroup.setExclusive(true); + + QString method = m_settings.value("preferences/flowMethod", "OpenCV-CPU").toString(); + qDebug() << "method is: " << method; + int opencv_olc_supported = isOCLsupported(); + if (opencv_olc_supported) { + ui->methodOCL->setEnabled(true); + // add OpenCL devices + QList<QString> ocldevices = oclFillDevices(); + ui->ocl_device->addItems(ocldevices); + } + else { + ui->methodOCL->setEnabled(false); + } + ui->preferredOpenCVAlgo->clear(); + ui->preferredOpenCVAlgo->addItem(tr("Farneback"), QVariant(2)); + ui->preferredOpenCVAlgo->addItem(tr("Dual TVL1"), QVariant(3)); + int algo = m_settings.value("preferences/preferredOpenCVAlgo", 0).toInt(); + ui->preferredOpenCVAlgo->setCurrentIndex(algo); + if ("V3D" == method) { + ui->methodV3D->setChecked(true); + } else if ("OpenCV-OCL" == method) { + ui->methodOCL->setChecked(true); + // restore selected device for OpenCL + int dev = m_settings.value("preferences/oclDriver", 0).toInt(); + ui->ocl_device->setCurrentIndex(dev); + } else { + ui->methodOCV->setChecked(true); + } + +#if 0 + // TODO: remove + // state of threading + bool precalc = m_settings.value("preferences/precalcFlow", true).toBool(); + if (precalc) + ui->precalcFlow->setChecked(true); + else + ui->precalcFlow->setChecked(false); +#endif + + connect(ui->bOk, SIGNAL(clicked()), this, SLOT(accept())); + connect(ui->bCancel, SIGNAL(clicked()), this, SLOT(reject())); + connect(ui->bBuildFlow, SIGNAL(clicked()), this, SLOT(slotBrowseFlow())); + connect(ui->buildFlow, SIGNAL(textChanged(QString)), this, SLOT(slotValidateFlowBinary())); + connect(&m_flowMethodGroup, SIGNAL(buttonClicked(int)), this, SLOT(slotUpdateFlowMethod())); + connect(ui->bFFmpeg, SIGNAL(clicked()), this, SLOT(slotBrowseFfmpeg())); + + if (!FlowSourceV3D_sV::validateFlowBinary(ui->buildFlow->text())) { + FlowSourceV3D_sV::correctFlowBinaryLocation(); + ui->buildFlow->setText(m_settings.value("binaries/v3dFlowBuilder", "").toString()); + } + slotValidateFlowBinary(); +} + +PreferencesDialog::~PreferencesDialog() +{ + delete ui; +} + +void PreferencesDialog::accept() +{ + // V3D binary location + if (FlowSourceV3D_sV::validateFlowBinary(ui->buildFlow->text())) { + m_settings.setValue("binaries/v3dFlowBuilder", ui->buildFlow->text()); + } + + // Flow method + QString method("OpenCV-CPU"); + if (ui->methodV3D->isChecked()) { + method = "V3D"; + } + else if (ui->methodOCL->isChecked()) { + method = "OpenCV-OCL"; + int dev = ui->ocl_device->currentIndex(); + qDebug() << "OpenCV-OCL driver choosen is: " << dev; + m_settings.setValue("preferences/oclDriver", dev); + } + int algo = ui->preferredOpenCVAlgo->currentIndex(); + m_settings.setValue("preferences/preferredOpenCVAlgo", algo); + + qDebug() << "saving method: " << method; + m_settings.setValue("preferences/flowMethod", method); + + // ffmpeg location + if (AvconvInfo::testAvconvExecutable(ui->ffmpeg->text())) { + m_settings.setValue("binaries/ffmpeg", ui->ffmpeg->text()); + } else { + qDebug() << "Not a valid ffmpeg/avconv executable: " << ui->ffmpeg->text(); + } + + // Store the values right now + m_settings.sync(); + QDialog::accept(); +} + +void PreferencesDialog::slotUpdateFlowMethod() +{ +} + +void PreferencesDialog::slotUpdateFfmpeg() +{ + m_settings.setValue("binaries/ffmpeg", ui->ffmpeg->text()); +} + +void PreferencesDialog::slotValidateFlowBinary() +{ + if (FlowSourceV3D_sV::validateFlowBinary(ui->buildFlow->text())) { + ui->buildFlow->setStyleSheet(QString("QLineEdit { background-color: %1; }").arg(Colours_sV::colOk.name())); + ui->methodV3D->setEnabled(true); + } else { + ui->buildFlow->setStyleSheet(QString("QLineEdit { background-color: %1; }").arg(Colours_sV::colBad.name())); + ui->methodV3D->setEnabled(false); + //ui->methodOCV->setChecked(true); + } +} + +void PreferencesDialog::slotBrowseFlow() +{ + QFileDialog dialog; + dialog.setAcceptMode(QFileDialog::AcceptOpen); + dialog.setFileMode(QFileDialog::ExistingFile); + dialog.setDirectory(QFileInfo(ui->buildFlow->text()).absolutePath()); + if (dialog.exec() == QDialog::Accepted) { + ui->buildFlow->setText(dialog.selectedFiles().at(0)); + slotValidateFlowBinary(); + } +} + +void PreferencesDialog::slotBrowseFfmpeg() +{ + QFileDialog dialog; + dialog.setAcceptMode(QFileDialog::AcceptOpen); + dialog.setFileMode(QFileDialog::ExistingFile); + dialog.setDirectory(QFileInfo(ui->ffmpeg->text()).absolutePath()); + if (dialog.exec() == QDialog::Accepted) { + ui->ffmpeg->setText(dialog.selectedFiles().at(0)); + //slotValidateFffmpegBinary(); + } +} + +int PreferencesDialog::isOCLsupported() +{ +#ifdef HAVE_OPENCV_OCL + return true; +#else + return false; +#endif +} + +QList<QString> PreferencesDialog::oclFillDevices(void) +{ + QList<QString> device_list; +#ifdef HAVE_OPENCV_OCL + using namespace cv::ocl; + PlatformsInfo platform_infos; + getOpenCLPlatforms(platform_infos); + for (unsigned int i = 0; i < platform_infos.size(); i++) { + const PlatformInfo *pi = platform_infosi; + for (unsigned int j = 0; j < pi->devices.size(); j++) { + const DeviceInfo *di = pi->devicesj; + QString device = QString::fromStdString(di->deviceName); + device_list << device; + } + } +#endif + return device_list; +}
View file
slowmoVideo-0.6.tar.xz/src/slowmoUI/dialogues/preferencesDialog.h
Added
@@ -0,0 +1,43 @@ +#ifndef PREFERENCESDIALOG_H +#define PREFERENCESDIALOG_H + +#include <QDialog> +#include <QtCore/QSettings> +#include <QButtonGroup> +#include "opencv2/opencv_modules.hpp" +#ifdef HAVE_OPENCV_OCL +#include "opencv2/ocl/ocl.hpp" +#endif + +namespace Ui { + class PreferencesDialog; +} + +class PreferencesDialog : public QDialog +{ + Q_OBJECT + +public: + explicit PreferencesDialog(QWidget *parent = 0); + ~PreferencesDialog(); + +protected slots: + void accept(); + +private: + Ui::PreferencesDialog *ui; + QButtonGroup m_flowMethodGroup; + QSettings m_settings; + int isOCLsupported(); + QList<QString> oclFillDevices(void); + +private slots: + void slotValidateFlowBinary(); + void slotUpdateFlowMethod(); + void slotUpdateFfmpeg(); + void slotBrowseFlow(); + void slotBrowseFfmpeg(); + +}; + +#endif // PREFERENCESDIALOG_H
View file
slowmoVideo-0.6.tar.xz/src/slowmoUI/dialogues/preferencesDialog.ui
Added
@@ -0,0 +1,243 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>PreferencesDialog</class> + <widget class="QDialog" name="PreferencesDialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>489</width> + <height>410</height> + </rect> + </property> + <property name="windowTitle"> + <string>slowmoUI preferences</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <item> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QGroupBox" name="groupBox"> + <property name="title"> + <string>Binary locations</string> + </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="1"> + <widget class="QLineEdit" name="buildFlow"/> + </item> + <item row="0" column="2"> + <widget class="QPushButton" name="bBuildFlow"> + <property name="text"> + <string>Browse</string> + </property> + </widget> + </item> + <item row="0" column="0"> + <widget class="QLabel" name="label"> + <property name="text"> + <string notr="true">flowBuilder</string> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string notr="true">ffmpeg</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QLineEdit" name="ffmpeg"/> + </item> + <item row="1" column="2"> + <widget class="QPushButton" name="bFFmpeg"> + <property name="text"> + <string>Browse</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + </layout> + </item> + <item> + <widget class="QGroupBox" name="flowMethodGroupBox"> + <property name="title"> + <string>Flow method</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_3"> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_5"> + <item> + <widget class="QRadioButton" name="methodV3D"> + <property name="text"> + <string>&flowBuilder (external binary, GPU based, requires GLSL)</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_4"> + <item> + <widget class="QRadioButton" name="methodOCV"> + <property name="text"> + <string>CP&U, OpenCV</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_3"> + <item> + <widget class="QRadioButton" name="methodOCL"> + <property name="text"> + <string>OpenC&V with OpenCL</string> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="ocl_device"/> + </item> + </layout> + </item> + <item> + <widget class="QGroupBox" name="preferredOpenCVAlgoBox"> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="title"> + <string/> + </property> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <property name="spacing"> + <number>0</number> + </property> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + <item> + <widget class="QLabel" name="labelPreferredOpenCVAlgo"> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="text"> + <string>Preferred OpenCV Algorithm:</string> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="preferredOpenCVAlgo"> + <property name="enabled"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <spacer name="verticalSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>38</height> + </size> + </property> + </spacer> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="bCancel"> + <property name="text"> + <string>Cancel</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="bOk"> + <property name="text"> + <string>Ok</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + <tabstops> + <tabstop>buildFlow</tabstop> + <tabstop>bBuildFlow</tabstop> + <tabstop>bCancel</tabstop> + <tabstop>bOk</tabstop> + </tabstops> + <resources/> + <connections> + <connection> + <sender>methodOCV</sender> + <signal>toggled(bool)</signal> + <receiver>preferredOpenCVAlgoBox</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel"> + <x>34</x> + <y>197</y> + </hint> + <hint type="destinationlabel"> + <x>170</x> + <y>270</y> + </hint> + </hints> + </connection> + <connection> + <sender>methodOCL</sender> + <signal>toggled(bool)</signal> + <receiver>preferredOpenCVAlgoBox</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel"> + <x>73</x> + <y>236</y> + </hint> + <hint type="destinationlabel"> + <x>86</x> + <y>271</y> + </hint> + </hints> + </connection> + </connections> +</ui>
View file
slowmoVideo-0.6.tar.xz/src/slowmoUI/dialogues/progressDialog.cpp
Added
@@ -0,0 +1,87 @@ +#include "progressDialog.h" +#include "ui_progressDialog.h" + +#include <QMessageBox> +#include <QtCore/QDebug> + +#include "notificator.h" + +ProgressDialog::ProgressDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::ProgressDialog) +{ + ui->setupUi(this); + // alas this make window transparent ! + //setWindowFlags(Qt::CustomizeWindowHint |Qt::WindowStaysOnTopHint); + + connect(ui->bAbort, SIGNAL(clicked()), this, SLOT(slotAbortPressed())); + connect(ui->bOk, SIGNAL(clicked()), this, SLOT(accept())); + + ui->bOk->setVisible(false); + ui->bOk->setEnabled(false); +} + +ProgressDialog::~ProgressDialog() +{ + delete ui; +} + +void ProgressDialog::setWorking(bool working) +{ + ui->bOk->setVisible(!working); + ui->bOk->setEnabled(!working); + ui->bAbort->setVisible(working); + ui->bAbort->setEnabled(working); +} + +void ProgressDialog::slotNextTask(const QString taskDescription, int taskSize) +{ + ui->lblTaskDesc->setText(taskDescription); + ui->progress->setMaximum(taskSize); + ui->progress->setValue(0); + if (windowTitle().startsWith(tr("(Finished) "))) { + setWindowTitle(windowTitle().remove(0, tr("(Finished) ").length())); + } + setWorking(true); +} +void ProgressDialog::slotTaskProgress(int progress) +{ + ui->progress->setValue(progress); +} +void ProgressDialog::slotTaskItemDescription(const QString desc) +{ + ui->lblTaskItemDesc->setText(desc); + repaint(); +} +void ProgressDialog::slotAbortPressed() +{ + emit signalAbortTask(); +} +void ProgressDialog::slotAborted(const QString &message) +{ + if (message.length() > 0) { + // Show message + QMessageBox box(QMessageBox::Warning, tr("Aborted"), message, QMessageBox::Ok); + box.show(); + } + reject(); +} + +void ProgressDialog::slotAllTasksFinished(const QString& timePassed) +{ + ui->progress->setValue(ui->progress->maximum()); + setWorking(false); + QString notifmsg = tr("Task finished in %1.").arg(timePassed); + if (timePassed.length() > 0) { + slotTaskItemDescription(notifmsg); + } else { + slotTaskItemDescription(tr("Task finished.")); + } + setWindowTitle(tr("(Finished) %1").arg(windowTitle())); +// display OS notification + Notificator* notif; + notif = new Notificator("simple"); + + + notif->notify(Notificator::Information, windowTitle(), notifmsg); +}
View file
slowmoVideo-0.6.tar.xz/src/slowmoUI/dialogues/progressDialog.h
Changed
(renamed from src/slowmoVideo/slowmoUI/dialogues/progressDialog.h)
View file
slowmoVideo-0.6.tar.xz/src/slowmoUI/dialogues/progressDialog.ui
Changed
(renamed from src/slowmoVideo/slowmoUI/dialogues/progressDialog.ui)
View file
slowmoVideo-0.6.tar.xz/src/slowmoUI/dialogues/projectPreferencesDialog.cpp
Added
@@ -0,0 +1,41 @@ +#include "projectPreferencesDialog.h" +#include "ui_projectPreferencesDialog.h" + +#include "lib/defs_sV.hpp" + +ProjectPreferencesDialog::ProjectPreferencesDialog(ProjectPreferences_sV *prefs, QWidget *parent) : + QDialog(parent), + ui(new Ui::ProjectPreferencesDialog), + m_projectPrefs(prefs) +{ + ui->setupUi(this); + ui->canvas_xAxisFPS->setText(m_projectPrefs->canvas_xAxisFPS().toString()); + + connect(ui->canvas_xAxisFPS, SIGNAL(textChanged(QString)), this, SLOT(slotCheckFPS())); +} +ProjectPreferencesDialog::~ProjectPreferencesDialog() +{ + delete ui; +} + +void ProjectPreferencesDialog::accept() +{ + try { + Fps_sV fps(ui->canvas_xAxisFPS->text()); + m_projectPrefs->canvas_xAxisFPS().num = fps.num; + m_projectPrefs->canvas_xAxisFPS().den = fps.den; + } catch (Error_sV &err) {} + QDialog::accept(); +} + +void ProjectPreferencesDialog::slotCheckFPS() +{ + try { + Fps_sV fps(ui->canvas_xAxisFPS->text()); + ui->canvas_xAxisFPS->setStyleSheet(QString("QLineEdit { background-color: %1; }").arg(Colours_sV::colOk.name())); + fps.den = fps.num; // Just to hopefully avoid the fps being optimized out + } catch (Error_sV &err) { + ui->canvas_xAxisFPS->setStyleSheet(QString("QLineEdit { background-color: %1; }").arg(Colours_sV::colBad.name())); + } +} +
View file
slowmoVideo-0.6.tar.xz/src/slowmoUI/dialogues/projectPreferencesDialog.h
Changed
(renamed from src/slowmoVideo/slowmoUI/dialogues/projectPreferencesDialog.h)
View file
slowmoVideo-0.6.tar.xz/src/slowmoUI/dialogues/projectPreferencesDialog.ui
Changed
(renamed from src/slowmoVideo/slowmoUI/dialogues/projectPreferencesDialog.ui)
View file
slowmoVideo-0.6.tar.xz/src/slowmoUI/dialogues/renderingDialog.cpp
Added
@@ -0,0 +1,576 @@ +/* +This file is part of slowmoVideo. +Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +*/ +#include "config.h" + +#include "renderingDialog.h" +#include "ui_renderingDialog.h" + +#include "lib/defs_sV.hpp" +#include "project/motionBlur_sV.h" +#include "project/project_sV.h" +#include "project/projectPreferences_sV.h" +#include "project/renderTask_sV.h" +#include "project/imagesRenderTarget_sV.h" +#include "project/abstractFlowSource_sV.h" +#include "project/flowSourceOpenCV_sV.h" + +#ifdef USE_FFMPEG +#if 0 +#include "project/new_videoRenderTarget.h" +#else +#include "project/exportVideoRenderTarget.h" +#endif +#else +#include "project/videoRenderTarget_sV.h" +#endif +#include "project/emptyFrameSource_sV.h" + +#include <QButtonGroup> +#include <QFileDialog> +#include <QSettings> // TODO: better +#include <QMessageBox> + +RenderingDialog::RenderingDialog(Project_sV *project, QWidget *parent) : + QDialog(parent), + ui(new Ui::RenderingDialog), + m_project(project) +{ + ui->setupUi(this); + + // Render section + m_sectionGroup = new QButtonGroup(this); + m_sectionGroup->addButton(ui->radioFullProject); + m_sectionGroup->addButton(ui->radioSection); + m_sectionGroup->addButton(ui->radioTagSection); + QString mode(m_project->preferences()->renderSectionMode()); + if (mode == "full") { + ui->radioFullProject->setChecked(true); + } else if (mode == "expr") { + ui->radioSection->setChecked(true); + } else if (mode == "tags") { + ui->radioTagSection->setChecked(true); + } else { + qDebug() << "Unknown render section mode: " << mode; + Q_ASSERT(false); + } + + // Optical flow + ui->lambda->setValue(m_project->preferences()->flowV3DLambda()); + + QSettings settings; //TODO: better define in project ? + ui->opticalFlowAlgo->clear(); + QString flow_method = settings.value("preferences/flowMethod", "OpenCV-CPU").toString(); + if (flow_method == "V3D") { + ui->opticalFlowAlgo->addItem(tr("flowBuilder"), QVariant(1)); + } else { + ui->opticalFlowAlgo->addItem(tr("OpenCV - Farneback"), QVariant(2)); + ui->opticalFlowAlgo->addItem(tr("OpenCV - Dual TVL1"), QVariant(3)); + } + + connect(ui->opticalFlowAlgo, SIGNAL(activated(int)), + ui->flowStackedWidget, SLOT(setCurrentIndex(int))); + + QWidget *flowbuilder_pane = ui->flowStackedWidget->widget(0); + QWidget *farneback_pane = ui->flowStackedWidget->widget(1); + QWidget *tvl1_pane = ui->flowStackedWidget->widget(2); + if (flow_method == "V3D") { + ui->opticalFlowAlgo->setCurrentIndex(0); + ui->flowStackedWidget->setCurrentIndex(0); + ui->flowStackedWidget->removeWidget(farneback_pane); + ui->flowStackedWidget->removeWidget(tvl1_pane); + } else { + int algo = settings.value("preferences/preferredOpenCVAlgo", 0).toInt(); + ui->opticalFlowAlgo->setCurrentIndex(algo); + ui->flowStackedWidget->setCurrentIndex(algo+1); + ui->flowStackedWidget->removeWidget(flowbuilder_pane); + } + connect(ui->clearflow, SIGNAL(clicked()), this, SLOT(slotClearFlowCache())); + // Motion blur + ui->maxSamples->setValue(m_project->motionBlur()->maxSamples()); + ui->slowmoSamples->setValue(m_project->motionBlur()->slowmoSamples()); + m_blurGroup = new QButtonGroup(this); + m_blurGroup->addButton(ui->radioBlurConvolution); + m_blurGroup->addButton(ui->radioBlurStacking); + m_blurGroup->addButton(ui->radioBlurNearest); + if (m_project->preferences()->renderMotionblurType() == MotionblurType_Convolving) { + ui->radioBlurConvolution->setChecked(true); + } else if (m_project->preferences()->renderMotionblurType() == MotionblurType_Stacking) { + ui->radioBlurStacking->setChecked(true); + } else { + ui->radioBlurNearest->setChecked(true); + } + + fillTagLists(); + + // Output target type + m_targetGroup = new QButtonGroup(this); + m_targetGroup->addButton(ui->radioImages); + m_targetGroup->addButton(ui->radioVideo); + if (m_project->preferences()->renderTarget() == "images") { + ui->radioImages->setChecked(true); + } else { + ui->radioVideo->setChecked(true); + } + + // Output target files + ui->imagesOutputDir->setText(m_project->preferences()->imagesOutputDir()); + ui->imagesFilenamePattern->setText(m_project->preferences()->imagesFilenamePattern()); + ui->videoOutputFile->setText(m_project->preferences()->videoFilename()); + ui->vcodec->setText(m_project->preferences()->videoCodec()); + + // FPS + QString fps = QVariant(m_project->preferences()->renderFPS().fps()).toString(); + if (ui->cbFps->findText(fps) < 0 && fps.toFloat() > 0) { + ui->cbFps->addItem(fps); + } + ui->cbFps->setCurrentIndex(ui->cbFps->findText(fps)); + + // Output size + ui->cbSize->addItem(tr("Original size"), QVariant(FrameSize_Orig)); + ui->cbSize->addItem(tr("Small"), QVariant(FrameSize_Small)); + ui->cbSize->setCurrentIndex(ui->cbSize->findData(QVariant(m_project->preferences()->renderFrameSize()))); + + // Interpolation type + ui->cbInterpolation->addItem(toString(InterpolationType_Forward), QVariant(InterpolationType_Forward)); + ui->cbInterpolation->addItem(toString(InterpolationType_ForwardNew), QVariant(InterpolationType_ForwardNew)); + ui->cbInterpolation->addItem(toString(InterpolationType_Twoway), QVariant(InterpolationType_Twoway)); + ui->cbInterpolation->addItem(toString(InterpolationType_TwowayNew), QVariant(InterpolationType_TwowayNew)); + ui->cbInterpolation->addItem(toString(InterpolationType_Bezier), QVariant(InterpolationType_Bezier)); + ui->cbInterpolation->addItem(toString(InterpolationType_None), QVariant(InterpolationType_None)); + ui->cbInterpolation->addItem(toString(InterpolationType_Nearest), QVariant(InterpolationType_Nearest)); + if (ui->cbInterpolation->findData(QVariant(m_project->preferences()->renderInterpolationType())) >= 0) { + ui->cbInterpolation->setCurrentIndex(ui->cbInterpolation->findData(QVariant(m_project->preferences()->renderInterpolationType()))); + } + + connect(m_targetGroup, SIGNAL(buttonClicked(int)), this, SLOT(slotUpdateRenderTarget())); + connect(m_sectionGroup, SIGNAL(buttonClicked(int)), this, SLOT(slotSectionModeChanged())); + connect(ui->timeStart, SIGNAL(textChanged(QString)), this, SLOT(slotValidate())); + connect(ui->timeEnd, SIGNAL(textChanged(QString)), this, SLOT(slotValidate())); + + connect(ui->cbStartTag, SIGNAL(currentIndexChanged(int)), this, SLOT(slotTagIndexChanged())); + connect(ui->cbEndTag, SIGNAL(currentIndexChanged(int)), this, SLOT(slotTagIndexChanged())); + + connect(ui->bAbort, SIGNAL(clicked()), this, SLOT(reject())); + connect(ui->bOk, SIGNAL(clicked()), this, SLOT(accept())); + connect(ui->bSave, SIGNAL(clicked()), this, SLOT(slotSaveSettings())); + + connect(ui->cbFps, SIGNAL(editTextChanged(QString)), this, SLOT(slotValidate())); + + connect(ui->imagesOutputDir, SIGNAL(textChanged(QString)), this, SLOT(slotValidate())); + connect(ui->imagesFilenamePattern, SIGNAL(textChanged(QString)), this, SLOT(slotValidate())); + connect(ui->videoOutputFile, SIGNAL(textChanged(QString)), this, SLOT(slotValidate())); + connect(ui->bImagesBrowseDir, SIGNAL(clicked()), this, SLOT(slotBrowseImagesDir())); + connect(ui->bBrowseVideoOutputFile, SIGNAL(clicked()), this, SLOT(slotBrowseVideoFile())); + + // Restore rendering start/end + int index = ui->cbStartTag->findText(m_project->preferences()->renderStartTag()); + if (index >= 0) { + ui->cbStartTag->setCurrentIndex(index); + } + index = ui->cbEndTag->findText(m_project->preferences()->renderEndTag()); + if (index >= 0) { + ui->cbEndTag->setCurrentIndex(index); + } + if (m_project->preferences()->renderStartTime().length() > 0) { + ui->timeStart->setText(m_project->preferences()->renderStartTime()); + } + if (m_project->preferences()->renderEndTime().length() > 0) { + ui->timeEnd->setText(m_project->preferences()->renderEndTime()); + } + + ui->timeStart->setPlaceholderText(QVariant(m_project->nodes()->startTime()).toString()); + ui->timeEnd->setPlaceholderText(QVariant(m_project->nodes()->endTime()).toString()); + +#ifndef USE_QTKIT + ui->use_qt->setChecked(false); + ui->use_qt->setEnabled(false); +#endif + + slotUpdateRenderTarget(); + slotSectionModeChanged(); +} + +RenderingDialog::~RenderingDialog() +{ + delete m_targetGroup; + delete ui; +} + +RenderTask_sV* RenderingDialog::buildTask() +{ + if (!slotValidate()) { + return NULL; + } + slotSaveSettings(); + + ProjectPreferences_sV *prefs = m_project->preferences(); + + const QString imagesOutputDir = ui->imagesOutputDir->text(); + const QString imagesFilenamePattern = ui->imagesFilenamePattern->text(); + + RenderTask_sV *task = new RenderTask_sV(m_project); + task->renderPreferences().setFps(prefs->renderFPS()); + task->renderPreferences().size = prefs->renderFrameSize(); + task->renderPreferences().interpolation = prefs->renderInterpolationType(); + task->renderPreferences().motionblur = prefs->renderMotionblurType(); + + + if (ui->radioImages->isChecked()) { + ImagesRenderTarget_sV *renderTarget = new ImagesRenderTarget_sV(task); + renderTarget->setFilenamePattern(imagesFilenamePattern); + renderTarget->setTargetDir(imagesOutputDir); + task->setRenderTarget(renderTarget); + } else if (ui->radioVideo->isChecked()) { +#ifdef USE_FFMPEG +#if 0 + newVideoRenderTarget *renderTarget = new newVideoRenderTarget(task); +#else + exportVideoRenderTarget *renderTarget = new exportVideoRenderTarget(task); +#endif + const bool use_qt = ui->use_qt->isChecked(); + if (!use_qt) { + qDebug() << "using classical FFMPEG"; + renderTarget->setQT(0); + } +#else +#warning "should not use this" + VideoRenderTarget_sV *renderTarget = new VideoRenderTarget_sV(task); +#endif + // check if file exist + QFile filetest(ui->videoOutputFile->text()); + if (filetest.exists()) { + int r = QMessageBox::warning(this, tr("slowmoUI"), + tr("The file already exist.\n" + "Do you want to overwrite it ?"), + QMessageBox::Yes | QMessageBox::No); + if (r == QMessageBox::Yes) { + filetest.remove(); + } else { + //TODO: maybe should delete task ? + return 0; + } + } + renderTarget->setTargetFile(ui->videoOutputFile->text()); + renderTarget->setVcodec(ui->vcodec->text()); + task->setRenderTarget(renderTarget); + } else { + qDebug() << "Render target is neither images nor video. Not implemented?"; + Q_ASSERT(false); + } + + if (ui->radioTagSection->isChecked()) { + bool b; + qreal start = ui->cbStartTag->itemData(ui->cbStartTag->currentIndex()).toFloat(&b); + Q_ASSERT(b); + qreal end = ui->cbEndTag->itemData(ui->cbEndTag->currentIndex()).toFloat(&b); + Q_ASSERT(b); + qDebug() << QString("Rendering tag section from %1 (%2) to %3 (%4)") + .arg(ui->cbStartTag->currentText()) + .arg(start).arg(ui->cbEndTag->currentText()).arg(end); + Q_ASSERT(start <= end); + task->setTimeRange(start, end); + } else if (ui->radioSection->isChecked()) { + qDebug() << QString("Rendering time section from %1 to %3") + .arg(ui->cbStartTag->currentText()) + .arg(ui->cbEndTag->currentText()); + task->setTimeRange(ui->timeStart->text(), ui->timeEnd->text()); + } + + QString mode; + if (ui->radioFullProject->isChecked()) { + mode = "full"; + } else if (ui->radioSection->isChecked()) { + mode = "time"; + m_project->preferences()->renderStartTime() = ui->timeStart->text(); + m_project->preferences()->renderEndTime() = ui->timeEnd->text(); + } else if (ui->radioTagSection->isChecked()) { + mode = "tags"; + m_project->preferences()->renderStartTag() = ui->cbStartTag->currentText(); + m_project->preferences()->renderEndTag() = ui->cbEndTag->currentText(); + } else { + qDebug() << "No section mode selected?"; + Q_ASSERT(false); + } + + // set optical flow parameters + QSettings settings; + QString flow_method = settings.value("preferences/flowMethod", "OpenCV-CPU").toString(); + if (flow_method == "V3D") { + AbstractFlowSource_sV *flow_algo = m_project->flowSource(); + flow_algo->setLambda(prefs->flowV3DLambda()); + } + else if (flow_method == "OpenCV-CPU" || flow_method == "OpenCV-OCL") { + int algo_index = ui->opticalFlowAlgo->currentIndex(); + qDebug() << "algo index is " << algo_index; + FlowSourceOpenCV_sV *flow_algo = (FlowSourceOpenCV_sV *)m_project->flowSource(); + + switch (algo_index) { + case 0: + flow_algo->setupOpticalFlow( + ui->FarnLevels->value(), + ui->FarnWin->value(), + ui->FarnPoly->value(), + ui->FarnPyr->value(), + ui->FarnPolyN->value() + ); + break; + + case 1: + flow_algo->setupTVL1( + ui->TVLtau->value(), + ui->TVLlambda->value(), + ui->TVLnscales->value(), + ui->TVLwarps->value(), + ui->TVLiterations->value(), + ui->TVLepsilon->value() + ); + break; + + default: + qDebug() << "no algo defined"; + } + } + else { + throw Error_sV("Unsupported Flow method"); + } + return task; +} + +void RenderingDialog::fillTagLists() +{ + QList<Tag_sV> list; + for (int i = 0; i < m_project->tags()->size(); i++) { + if (m_project->tags()->at(i).axis() == TagAxis_Output + && m_project->tags()->at(i).time() > m_project->nodes()->startTime() + && m_project->tags()->at(i).time() < m_project->nodes()->endTime()) { + list << m_project->tags()->at(i); + } + } + qSort(list); + ui->cbStartTag->addItem(tr("<Start>"), QVariant(m_project->nodes()->startTime())); + for (int i = 0; i < list.size(); i++) { + ui->cbStartTag->addItem(list.at(i).description(), QVariant(list.at(i).time())); + ui->cbEndTag->addItem(list.at(i).description(), QVariant(list.at(i).time())); + } + ui->cbEndTag->addItem(tr("<End>"), QVariant(m_project->nodes()->endTime())); +} + +void RenderingDialog::slotSaveSettings() +{ + qDebug() << "RenderingDialog::slotSaveSettings()"; + + const InterpolationType interpolation = (InterpolationType)ui->cbInterpolation->itemData(ui->cbInterpolation->currentIndex()).toInt(); + const FrameSize size = (FrameSize)ui->cbSize->itemData(ui->cbSize->currentIndex()).toInt(); + const QString imagesOutputDir = ui->imagesOutputDir->text(); + const QString imagesFilenamePattern = ui->imagesFilenamePattern->text(); + const float fps = ui->cbFps->currentText().toFloat(); + + const bool use_qt = ui->use_qt->isChecked(); + + m_project->motionBlur()->setMaxSamples(ui->maxSamples->value()); + m_project->motionBlur()->setSlowmoSamples(ui->slowmoSamples->value()); + m_project->preferences()->flowV3DLambda() = ui->lambda->value(); + + if (ui->radioBlurConvolution->isChecked()) { + m_project->preferences()->renderMotionblurType() = MotionblurType_Convolving; + } else if (ui->radioBlurStacking->isChecked()) { + m_project->preferences()->renderMotionblurType() = MotionblurType_Stacking; + } else { + m_project->preferences()->renderMotionblurType() = MotionblurType_Nearest; + } + + QString mode; + if (ui->radioFullProject->isChecked()) { + mode = "full"; + } else if (ui->radioSection->isChecked()) { + mode = "expr"; + m_project->preferences()->renderStartTime() = ui->timeStart->text(); + m_project->preferences()->renderEndTime() = ui->timeEnd->text(); + } else if (ui->radioTagSection->isChecked()) { + mode = "tags"; + m_project->preferences()->renderStartTag() = ui->cbStartTag->currentText(); + m_project->preferences()->renderEndTag() = ui->cbEndTag->currentText(); + } else { + qDebug() << "No section mode selected?"; + Q_ASSERT(false); + } + m_project->preferences()->renderSectionMode() = mode; + m_project->preferences()->imagesOutputDir() = imagesOutputDir; + m_project->preferences()->imagesFilenamePattern() = imagesFilenamePattern; + m_project->preferences()->videoFilename() = ui->videoOutputFile->text(); + m_project->preferences()->videoCodec() = ui->vcodec->text(); + m_project->preferences()->renderInterpolationType() = interpolation; + m_project->preferences()->renderFrameSize() = size; + m_project->preferences()->renderFPS() = fps; + m_project->preferences()->renderTarget() = ui->radioImages->isChecked() ? "images" : "video"; + m_project->preferences()->renderFormat() = use_qt; + + accept(); +} + +bool RenderingDialog::slotValidate() +{ + qDebug() << "RenderingDialog::slotValidate()"; + + bool ok = true; + + float fps = ui->cbFps->currentText().toFloat(&ok); + ok &= fps > 0; + if (ok) { + ui->cbFps->setStyleSheet(QString("QComboBox { background-color: %1; }").arg(Colours_sV::colOk.name())); + } else { + ui->cbFps->setStyleSheet(QString("QComboBox { background-color: %1; }").arg(Colours_sV::colBad.name())); + } + + if (ui->radioImages->isChecked()) { + if (ui->imagesFilenamePattern->text().contains("%1")) { + ui->imagesFilenamePattern->setStyleSheet(QString("QLineEdit { background-color: %1; }").arg(Colours_sV::colOk.name())); + } else { + ok = false; + ui->imagesFilenamePattern->setStyleSheet(QString("QLineEdit { background-color: %1; }").arg(Colours_sV::colBad.name())); + } + + if (ui->imagesOutputDir->text().length() > 0) { + ui->imagesOutputDir->setStyleSheet(QString("QLineEdit { background-color: %1; }").arg(Colours_sV::colOk.name())); + } else { + ok = false; + ui->imagesOutputDir->setStyleSheet(QString("QLineEdit { background-color: %1; }").arg(Colours_sV::colBad.name())); + } + } else if (ui->radioVideo->isChecked()) { + if (ui->videoOutputFile->text().length() > 0) { + ui->videoOutputFile->setStyleSheet(QString("QLineEdit { background-color: %1; }").arg(Colours_sV::colOk.name())); + } else { + ok = false; + ui->videoOutputFile->setStyleSheet(QString("QLineEdit { background-color: %1; }").arg(Colours_sV::colBad.name())); + } + } else { + Q_ASSERT(false); + } + + if (ui->radioSection->isChecked()) { + bool startOk = false; + bool endOk = false; + qreal timeStart = 0; + qreal timeEnd = 0; + QStringList messages; + + Fps_sV currentFps(ui->cbFps->currentText().toFloat()); + try { + timeStart = m_project->toOutTime(ui->timeStart->text(), currentFps); + startOk = true; + } catch (Error_sV &err) { + messages << err.message(); + } + try { + timeEnd = m_project->toOutTime(ui->timeEnd->text(), currentFps); + endOk = true; + } catch (Error_sV &err) { + messages << err.message(); + } + if (timeEnd <= timeStart) { + endOk = false; + messages << tr("Start time must be < end time!"); + } + + messages << tr("Rendering from %1 s to %2 s.").arg(timeStart).arg(timeEnd); + ui->sectionMessage->setText(messages.join("\n")); + + ok &= startOk && endOk; + + if (!startOk) { + ui->timeStart->setStyleSheet(QString("QLineEdit { background-color: %1; }").arg(Colours_sV::colBad.name())); + } else { + ui->timeStart->setStyleSheet(QString("QLineEdit { background-color: %1; }").arg(Colours_sV::colOk.name())); + } + if (!endOk) { + ui->timeEnd->setStyleSheet(QString("QLineEdit { background-color: %1; }").arg(Colours_sV::colBad.name())); + } else { + ui->timeEnd->setStyleSheet(QString("QLineEdit { background-color: %1; }").arg(Colours_sV::colOk.name())); + } + } + + ok &= dynamic_cast<EmptyFrameSource_sV*>(m_project->frameSource()) == NULL; + + ok &= m_project->nodes()->size() >= 2; + + ui->bOk->setEnabled(ok); + + return ok; +} + +void RenderingDialog::slotUpdateRenderTarget() +{ + ui->groupImages->setVisible(ui->radioImages->isChecked()); + ui->groupVideo->setVisible(ui->radioVideo->isChecked()); + slotValidate(); +} + +void RenderingDialog::slotBrowseImagesDir() +{ + QFileDialog dialog(this, tr("Output directory for rendered images")); + dialog.setAcceptMode(QFileDialog::AcceptOpen); + dialog.setFileMode(QFileDialog::Directory); + dialog.setOption(QFileDialog::ShowDirsOnly, true); + dialog.setDirectory(ui->imagesOutputDir->text()); + if (dialog.exec() == QDialog::Accepted) { + ui->imagesOutputDir->setText(dialog.selectedFiles().at(0)); + } +} + +void RenderingDialog::slotBrowseVideoFile() +{ + QFileDialog dialog(this, tr("Output video file")); + dialog.setAcceptMode(QFileDialog::AcceptSave); + dialog.setFileMode(QFileDialog::AnyFile); + dialog.setDirectory(QFileInfo(ui->videoOutputFile->text()).absolutePath()); + if (dialog.exec() == QDialog::Accepted) { + ui->videoOutputFile->setText(dialog.selectedFiles().at(0)); + } +} + +void RenderingDialog::slotSectionModeChanged() +{ + ui->timeStart->setVisible(ui->radioSection->isChecked()); + ui->timeEnd->setVisible(ui->radioSection->isChecked()); + ui->sectionMessage->setVisible(ui->radioSection->isChecked()); + ui->cbStartTag->setVisible(ui->radioTagSection->isChecked()); + ui->cbEndTag->setVisible(ui->radioTagSection->isChecked()); + ui->lblcTo->setVisible(ui->radioSection->isChecked() || ui->radioTagSection->isChecked()); + slotValidate(); +} + +void RenderingDialog::slotTagIndexChanged() +{ + if (QObject::sender() == ui->cbStartTag) { + qDebug() << "Start tag"; + if (ui->cbEndTag->currentIndex() < ui->cbStartTag->currentIndex()) { + ui->cbEndTag->setCurrentIndex(ui->cbStartTag->currentIndex()); + } + } else { + qDebug() << "End tag"; + if (ui->cbStartTag->currentIndex() > ui->cbEndTag->currentIndex()) { + ui->cbStartTag->setCurrentIndex(ui->cbEndTag->currentIndex()); + } + } +} + +#if 0 +void MainWindow::comboBox_Activated() +{ + std::cout << "Activated " << this->ui.comboBox->currentIndex() << std::endl; +} +#endif + +void RenderingDialog::slotClearFlowCache() { + m_project->flowSource()->clearFlowCache(); +} + + +
View file
slowmoVideo-0.6.tar.xz/src/slowmoUI/dialogues/renderingDialog.h
Added
@@ -0,0 +1,64 @@ +/* +This file is part of slowmoVideo. +Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +*/ + +#ifndef RENDERINGDIALOG_H +#define RENDERINGDIALOG_H + +#include <QDialog> + +namespace Ui { + class RenderingDialog; +} + +class QButtonGroup; +class RenderTask_sV; +class Project_sV; + +/** + \brief Dialog for rendering option + */ +class RenderingDialog : public QDialog +{ + Q_OBJECT + +public: + explicit RenderingDialog(Project_sV *project, QWidget *parent = 0); + ~RenderingDialog(); + + /** \return \c NULL on invalid input, a render task for the given project otherwise */ + RenderTask_sV* buildTask(); + +public slots: + bool slotValidate(); + +private: + Ui::RenderingDialog *ui; + + Project_sV *m_project; + QButtonGroup *m_targetGroup; + QButtonGroup *m_sectionGroup; + QButtonGroup *m_blurGroup; + + void fillTagLists(); + +private slots: + void slotBrowseImagesDir(); + void slotBrowseVideoFile(); + void slotUpdateRenderTarget(); + + void slotSectionModeChanged(); + void slotTagIndexChanged(); + + void slotSaveSettings(); + void slotClearFlowCache(); + +}; + +#endif // RENDERINGDIALOG_H
View file
slowmoVideo-0.6.tar.xz/src/slowmoUI/dialogues/renderingDialog.ui
Added
@@ -0,0 +1,1255 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>RenderingDialog</class> + <widget class="QDialog" name="RenderingDialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>762</width> + <height>593</height> + </rect> + </property> + <property name="windowTitle"> + <string>Rendering settings</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <item> + <spacer name="verticalSpacer_2"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>10</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QTabWidget" name="tabWidget"> + <property name="currentIndex"> + <number>1</number> + </property> + <widget class="QWidget" name="tabWidgetPage1"> + <property name="accessibleName"> + <string>a</string> + </property> + <property name="accessibleDescription"> + <string>a</string> + </property> + <attribute name="title"> + <string>Rendering settings</string> + </attribute> + <layout class="QVBoxLayout" name="verticalLayout_8"> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QRadioButton" name="radioFullProject"> + <property name="text"> + <string>Fu&ll Project</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <widget class="QRadioButton" name="radioTagSection"> + <property name="text"> + <string>&Tag section</string> + </property> + </widget> + </item> + <item> + <widget class="QRadioButton" name="radioSection"> + <property name="text"> + <string>Custom sect&ion</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_5"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>13</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QComboBox" name="cbStartTag"/> + </item> + <item> + <widget class="QLineEdit" name="timeStart"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="baseSize"> + <size> + <width>100</width> + <height>0</height> + </size> + </property> + <property name="maxLength"> + <number>16</number> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="lblcTo"> + <property name="text"> + <string>to</string> + </property> + </widget> + </item> + <item> + <widget class="QLineEdit" name="timeEnd"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="baseSize"> + <size> + <width>100</width> + <height>0</height> + </size> + </property> + <property name="maxLength"> + <number>16</number> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="cbEndTag"/> + </item> + <item> + <spacer name="horizontalSpacer_2"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_8"> + <item> + <spacer name="horizontalSpacer_11"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>30</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QLabel" name="sectionMessage"> + <property name="text"> + <string/> + </property> + <property name="wordWrap"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_5"> + <item> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>Frames per second:</string> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="cbFps"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>100</width> + <height>0</height> + </size> + </property> + <property name="baseSize"> + <size> + <width>100</width> + <height>0</height> + </size> + </property> + <property name="editable"> + <bool>true</bool> + </property> + <property name="currentIndex"> + <number>0</number> + </property> + <item> + <property name="text"> + <string notr="true">23.976</string> + </property> + </item> + <item> + <property name="text"> + <string notr="true">24</string> + </property> + </item> + <item> + <property name="text"> + <string notr="true">25</string> + </property> + </item> + <item> + <property name="text"> + <string notr="true">29.976</string> + </property> + </item> + <item> + <property name="text"> + <string notr="true">30</string> + </property> + </item> + <item> + <property name="text"> + <string notr="true">50</string> + </property> + </item> + <item> + <property name="text"> + <string notr="true">60</string> + </property> + </item> + <item> + <property name="text"> + <string notr="true">72</string> + </property> + </item> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_4"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_6"> + <item> + <widget class="QLabel" name="label_3"> + <property name="text"> + <string>Size:</string> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="cbSize"/> + </item> + <item> + <spacer name="horizontalSpacer_7"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Minimum</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>10</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QLabel" name="label_4"> + <property name="text"> + <string>Interpolation:</string> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="cbInterpolation"/> + </item> + <item> + <spacer name="horizontalSpacer_6"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_9"> + <property name="topMargin"> + <number>8</number> + </property> + <item> + <widget class="QLabel" name="label_13"> + <property name="text"> + <string>For two frames A and B, the two-way interpolations calculate both the flows A→B and B→A, which leads to smoother transitions between them. Forward interpolations only calculate A→B; Twice as fast, but usually less smooth.</string> + </property> + <property name="wordWrap"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </item> + <item> + <spacer name="verticalSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + <widget class="QWidget" name="tabWidgetPage2"> + <attribute name="title"> + <string>Optical Flow</string> + </attribute> + <layout class="QVBoxLayout" name="verticalLayout_9"> + <item> + <widget class="QGroupBox" name="groupBox_3"> + <property name="title"> + <string>Optical flow</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_6"> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_13"> + <item> + <widget class="QLabel" name="label_17"> + <property name="text"> + <string>Optical Flow Algorithm : </string> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="opticalFlowAlgo"/> + </item> + <item> + <spacer name="horizontalSpacer_14"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item> + <widget class="QStackedWidget" name="flowStackedWidget"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="currentIndex"> + <number>2</number> + </property> + <widget class="QWidget" name="page3D"> + <widget class="QWidget" name="FarnlayoutWidget"> + <property name="geometry"> + <rect> + <x>0</x> + <y>20</y> + <width>472</width> + <height>36</height> + </rect> + </property> + <layout class="QHBoxLayout" name="horizontalLayout_7"> + <item> + <widget class="QLabel" name="label_12"> + <property name="text"> + <string>buildFlow lambda</string> + </property> + </widget> + </item> + <item> + <widget class="QDoubleSpinBox" name="lambda"> + <property name="locale"> + <locale language="English" country="UnitedStates"/> + </property> + <property name="minimum"> + <double>5.000000000000000</double> + </property> + <property name="maximum"> + <double>50.000000000000000</double> + </property> + <property name="singleStep"> + <double>1.000000000000000</double> + </property> + <property name="value"> + <double>20.000000000000000</double> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_10"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>10</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QLabel" name="label_11"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Use a higher value for high-quality footage and larger images.</string> + </property> + <property name="wordWrap"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </widget> + <widget class="QWidget" name="flowlayoutWidget"> + <property name="geometry"> + <rect> + <x>0</x> + <y>70</y> + <width>662</width> + <height>101</height> + </rect> + </property> + <layout class="QHBoxLayout" name="horizontalLayout_10"> + <property name="topMargin"> + <number>8</number> + </property> + <item> + <widget class="QLabel" name="label_14"> + <property name="text"> + <string>The lambda is only used with the GPU based Optical Flow algorithm. There is no general rule which value is best, so it is usually a good idea to render a short part with a low (5) and a high (50) lambda to see the differences, and then try to find the best value between.</string> + </property> + <property name="wordWrap"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </widget> + </widget> + <widget class="QWidget" name="pageFarn"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>223</height> + </size> + </property> + <widget class="QWidget" name="layoutWidget_1"> + <property name="geometry"> + <rect> + <x>10</x> + <y>10</y> + <width>231</width> + <height>212</height> + </rect> + </property> + <layout class="QFormLayout" name="formLayout_2"> + <property name="sizeConstraint"> + <enum>QLayout::SetMinAndMaxSize</enum> + </property> + <property name="horizontalSpacing"> + <number>2</number> + </property> + <property name="verticalSpacing"> + <number>5</number> + </property> + <item row="0" column="0"> + <widget class="QLabel" name="labelLevel"> + <property name="toolTip"> + <string><html><head/><body><p>number of pyramid layers including the initial image; `levels=1` means that no extra layers are created and only the original images are used</p></body></html></string> + </property> + <property name="text"> + <string>Levels:</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QDoubleSpinBox" name="FarnLevels"> + <property name="toolTip"> + <string><html><head/><body><p>number of pyramid layers including the initial image; `levels=1` means that no extra layers are created and only the original images are used</p></body></html></string> + </property> + <property name="decimals"> + <number>0</number> + </property> + <property name="value"> + <double>3.000000000000000</double> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="labelWinsize"> + <property name="toolTip"> + <string><html><head/><body><p>Averaging window size; larger values increase the algorithm robustness to image noise and give more chances for fast motion detection, but yield more blurred motion field.</p></body></html></string> + </property> + <property name="text"> + <string>WinSize:</string> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QDoubleSpinBox" name="FarnWin"> + <property name="toolTip"> + <string><html><head/><body><p>Averaging window size; larger values increase the algorithm robustness to image noise and give more chances for fast motion detection, but yield more blurred motion field.</p></body></html></string> + </property> + <property name="decimals"> + <number>0</number> + </property> + <property name="value"> + <double>15.000000000000000</double> + </property> + </widget> + </item> + <item row="4" column="0"> + <widget class="QLabel" name="labelSigma"> + <property name="toolTip"> + <string><html><head/><body><p>Standard deviation of the Gaussian that is used to smooth derivatives used as a basis for the polynomial expansion; for `poly_n=5`, you can set `poly_sigma=1.1`, for `poly_n=7`, a good value would be `poly_sigma=1.5`.</p></body></html></string> + </property> + <property name="text"> + <string>PolySigma:</string> + </property> + </widget> + </item> + <item row="4" column="1"> + <widget class="QDoubleSpinBox" name="FarnPoly"> + <property name="toolTip"> + <string><html><head/><body><p>Standard deviation of the Gaussian that is used to smooth derivatives used as a basis for the polynomial expansion; for `poly_n=5`, you can set `poly_sigma=1.1`, for `poly_n=7`, a good value would be `poly_sigma=1.5`.</p></body></html></string> + </property> + <property name="singleStep"> + <double>0.010000000000000</double> + </property> + <property name="value"> + <double>1.200000000000000</double> + </property> + </widget> + </item> + <item row="6" column="0"> + <widget class="QLabel" name="labelPyr"> + <property name="toolTip"> + <string><html><head/><body><p>Parameter, specifying the image scale (&lt;1) to build pyramids for each image; `pyr_scale=0.5` means a classical pyramid, where each next layer is twice smaller than the previous one.</p></body></html></string> + </property> + <property name="text"> + <string>Pyr_Scale:</string> + </property> + </widget> + </item> + <item row="8" column="0"> + <widget class="QLabel" name="labelPoly"> + <property name="toolTip"> + <string><html><head/><body><p>Size of the pixel neighborhood used to find polynomial expansion in each pixel; larger values mean that the image will be approximated with smoother surfaces, yielding more robust algorithm and more blurred motion field, typically `poly_n` = 5 or 7.</p></body></html></string> + </property> + <property name="text"> + <string>PolyN:</string> + </property> + </widget> + </item> + <item row="8" column="1"> + <widget class="QDoubleSpinBox" name="FarnPolyN"> + <property name="toolTip"> + <string><html><head/><body><p>Size of the pixel neighborhood used to find polynomial expansion in each pixel; larger values mean that the image will be approximated with smoother surfaces, yielding more robust algorithm and more blurred motion field, typically `poly_n` = 5 or 7.</p></body></html></string> + </property> + <property name="decimals"> + <number>0</number> + </property> + <property name="value"> + <double>5.000000000000000</double> + </property> + </widget> + </item> + <item row="6" column="1"> + <widget class="QDoubleSpinBox" name="FarnPyr"> + <property name="toolTip"> + <string><html><head/><body><p>Parameter, specifying the image scale (&lt;1) to build pyramids for each image; `pyr_scale=0.5` means a classical pyramid, where each next layer is twice smaller than the previous one.</p></body></html></string> + </property> + <property name="singleStep"> + <double>0.010000000000000</double> + </property> + <property name="value"> + <double>0.500000000000000</double> + </property> + </widget> + </item> + </layout> + </widget> + </widget> + <widget class="QWidget" name="pageTVL1"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>229</height> + </size> + </property> + <widget class="QWidget" name="layoutWidget_2"> + <property name="geometry"> + <rect> + <x>10</x> + <y>10</y> + <width>261</width> + <height>218</height> + </rect> + </property> + <layout class="QFormLayout" name="formLayout"> + <property name="fieldGrowthPolicy"> + <enum>QFormLayout::AllNonFixedFieldsGrow</enum> + </property> + <property name="horizontalSpacing"> + <number>2</number> + </property> + <property name="verticalSpacing"> + <number>4</number> + </property> + <item row="0" column="0"> + <widget class="QLabel" name="labelTau"> + <property name="toolTip"> + <string><html><head/><body><p><span style=" font-family:'sans-serif'; font-size:16px; color:#000000; background-color:#ffffff;">Time step of the numerical scheme</span></p></body></html></string> + </property> + <property name="text"> + <string>Tau:</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QDoubleSpinBox" name="TVLtau"> + <property name="toolTip"> + <string><html><head/><body><p><span style=" font-family:'sans-serif'; font-size:16px; color:#000000; background-color:#ffffff;">Time step of the numerical scheme</span></p></body></html></string> + </property> + <property name="singleStep"> + <double>0.010000000000000</double> + </property> + <property name="value"> + <double>0.250000000000000</double> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="labelLambda"> + <property name="toolTip"> + <string><html><head/><body><p><span style=" font-family:'sans-serif'; font-size:16px; color:#000000; background-color:#ffffff;">Weight parameter for the data term, attachment parameter. This is the most relevant parameter, which determines the smoothness of the output. The smaller this parameter is, the smoother the solutions we obtain. It depends on the range of motions of the images, so its value should be adapted to each image sequence</span></string> + </property> + <property name="text"> + <string>Lambda:</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QDoubleSpinBox" name="TVLlambda"> + <property name="toolTip"> + <string><html><head/><body><p><span style=" font-family:'sans-serif'; font-size:16px; color:#000000; background-color:#ffffff;">Weight parameter for the data term, attachment parameter. This is the most relevant parameter, which determines the smoothness of the output. The smaller this parameter is, the smoother the solutions we obtain. It depends on the range of motions of the images, so its value should be adapted to each image sequence</span></string> + </property> + <property name="singleStep"> + <double>0.010000000000000</double> + </property> + <property name="value"> + <double>0.150000000000000</double> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="labelWarp"> + <property name="toolTip"> + <string><html><head/><body><p><span style=" font-family:'sans-serif'; font-size:16px; color:#000000; background-color:#ffffff;">Number of warpings per scale. Represents the number of times that I1(x+u0) and grad( I1(x+u0) ) are computed per scale. This is a parameter that assures the stability of the method. It also affects the running time, so it is a compromise between speed and accuracy</span></string> + </property> + <property name="text"> + <string>Warps:</string> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QDoubleSpinBox" name="TVLwarps"> + <property name="toolTip"> + <string><html><head/><body><p><span style=" font-family:'sans-serif'; font-size:16px; color:#000000; background-color:#ffffff;">Number of warpings per scale. Represents the number of times that I1(x+u0) and grad( I1(x+u0) ) are computed per scale. This is a parameter that assures the stability of the method. It also affects the running time, so it is a compromise between speed and accuracy</span></string> + </property> + <property name="decimals"> + <number>0</number> + </property> + <property name="value"> + <double>10.000000000000000</double> + </property> + </widget> + </item> + <item row="3" column="0"> + <widget class="QLabel" name="labelNscales"> + <property name="toolTip"> + <string><html><head/><body><p><span style=" font-family:'sans-serif'; font-size:16px; color:#000000; background-color:#ffffff;">Number of scales used to create the pyramid of images</span></string> + </property> + <property name="text"> + <string>Nscales:</string> + </property> + </widget> + </item> + <item row="3" column="1"> + <widget class="QDoubleSpinBox" name="TVLnscales"> + <property name="toolTip"> + <string><html><head/><body><p><span style=" font-family:'sans-serif'; font-size:16px; color:#000000; background-color:#ffffff;">Number of scales used to create the pyramid of images</span></string> + </property> + <property name="decimals"> + <number>0</number> + </property> + <property name="value"> + <double>5.000000000000000</double> + </property> + </widget> + </item> + <item row="5" column="1"> + <widget class="QDoubleSpinBox" name="TVLiterations"> + <property name="toolTip"> + <string><html><head/><body><p><span style=" font-family:'sans-serif'; font-size:16px; color:#000000; background-color:#ffffff;">Stopping criterion iterations number used in the numerical scheme</span></string> + </property> + <property name="decimals"> + <number>0</number> + </property> + <property name="maximum"> + <double>400.000000000000000</double> + </property> + <property name="value"> + <double>300.000000000000000</double> + </property> + </widget> + </item> + <item row="5" column="0"> + <widget class="QLabel" name="labelIter"> + <property name="toolTip"> + <string><html><head/><body><p><span style=" font-family:'sans-serif'; font-size:16px; color:#000000; background-color:#ffffff;">Stopping criterion iterations number used in the numerical scheme</span></string> + </property> + <property name="text"> + <string>Iterations:</string> + </property> + </widget> + </item> + <item row="6" column="0"> + <widget class="QLabel" name="LabelEspilon"> + <property name="toolTip"> + <string><html><head/><body><p><span style=" font-family:'sans-serif'; font-size:16px; color:#000000; background-color:#ffffff;">Stopping criterion threshold used in the numerical scheme, which is a trade-off between precision and running time. A small value will yield more accurate solutions at the expense of a slower convergence</span></string> + </property> + <property name="text"> + <string>Epsilon:</string> + </property> + </widget> + </item> + <item row="6" column="1"> + <widget class="QDoubleSpinBox" name="TVLepsilon"> + <property name="toolTip"> + <string><html><head/><body><p><span style=" font-family:'sans-serif'; font-size:16px; color:#000000; background-color:#ffffff;">Stopping criterion threshold used in the numerical scheme, which is a trade-off between precision and running time. A small value will yield more accurate solutions at the expense of a slower convergence</span></string> + </property> + <property name="singleStep"> + <double>0.010000000000000</double> + </property> + <property name="value"> + <double>0.010000000000000</double> + </property> + </widget> + </item> + </layout> + </widget> + </widget> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_11"> + <item> + <widget class="QPushButton" name="clearflow"> + <property name="text"> + <string>Clear Flow Cache</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_12"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item> + <spacer name="verticalSpacer_3"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + </item> + </layout> + </widget> + <widget class="QWidget" name="tabWidgetPage3"> + <attribute name="title"> + <string>Motion Blur</string> + </attribute> + <layout class="QVBoxLayout" name="verticalLayout_10"> + <item> + <widget class="QGroupBox" name="groupBox_2"> + <property name="title"> + <string>Motion blur</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_5"> + <item> + <widget class="QLabel" name="label_9"> + <property name="text"> + <string>Motion blur will only be applied for segments on which it is enabled.</string> + </property> + <property name="wordWrap"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <widget class="QRadioButton" name="radioBlurStacking"> + <property name="text"> + <string>Stacking &blur (Uses more disk space, but is faster for repeated rendering.)</string> + </property> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <item> + <widget class="QLabel" name="label_6"> + <property name="text"> + <string>Maximum samples</string> + </property> + </widget> + </item> + <item> + <widget class="QSpinBox" name="maxSamples"> + <property name="minimum"> + <number>1</number> + </property> + <property name="value"> + <number>64</number> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_9"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>10</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QLabel" name="label_8"> + <property name="text"> + <string>Samples for slow motion</string> + </property> + </widget> + </item> + <item> + <widget class="QSpinBox" name="slowmoSamples"> + <property name="minimum"> + <number>1</number> + </property> + <property name="value"> + <number>16</number> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_8"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item> + <widget class="QRadioButton" name="radioBlurConvolution"> + <property name="text"> + <string>Convolution blur (Smoother &than stacking, usually the better choice.)</string> + </property> + </widget> + </item> + <item> + <widget class="QRadioButton" name="radioBlurNearest"> + <property name="text"> + <string>Nearest (no b&lurring)</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <spacer name="verticalSpacer_4"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + <widget class="QWidget" name="tabWidgetPage4"> + <attribute name="title"> + <string>Output</string> + </attribute> + <layout class="QVBoxLayout" name="verticalLayout_11"> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_3"> + <item> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Target:</string> + </property> + </widget> + </item> + <item> + <widget class="QRadioButton" name="radioVideo"> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="text"> + <string>&Video</string> + </property> + </widget> + </item> + <item> + <widget class="QRadioButton" name="radioImages"> + <property name="text"> + <string>&Images</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_3"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item> + <widget class="QGroupBox" name="groupImages"> + <property name="title"> + <string>Images</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QLabel" name="label_10"> + <property name="text"> + <string>The %1 in the filename pattern is mandatory and will be replaced by the frame number.</string> + </property> + </widget> + </item> + <item> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="0"> + <widget class="QLabel" name="lblcOutputDir"> + <property name="text"> + <string>Output directory</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QLineEdit" name="imagesOutputDir"/> + </item> + <item row="0" column="2"> + <widget class="QPushButton" name="bImagesBrowseDir"> + <property name="text"> + <string>Browse</string> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="lblcFilenamePattern"> + <property name="text"> + <string>Filename pattern</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QLineEdit" name="imagesFilenamePattern"> + <property name="toolTip"> + <string extracomment="%1 for the frame number (required!)"/> + </property> + <property name="text"> + <string>rendered-%1.jpg</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QGroupBox" name="groupVideo"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Minimum"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="title"> + <string>Video</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_3"> + <item> + <widget class="QLabel" name="label_7"> + <property name="text"> + <string>Videos will be encoded with ffmpeg. If additional arguments are left empty, defaults will be used. The video format is determined by ffmpeg according to the file suffix.</string> + </property> + <property name="wordWrap"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <layout class="QGridLayout" name="gridLayout_2"> + <item row="0" column="0"> + <widget class="QLabel" name="lblcOutputFile"> + <property name="text"> + <string>Output file</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QLineEdit" name="videoOutputFile"/> + </item> + <item row="0" column="2"> + <widget class="QPushButton" name="bBrowseVideoOutputFile"> + <property name="text"> + <string>Browse</string> + </property> + </widget> + </item> + <item row="1" column="0" colspan="3"> + <widget class="QGroupBox" name="groupBox"> + <property name="title"> + <string>Optional arguments</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_4"> + <item> + <widget class="QCheckBox" name="use_qt"> + <property name="text"> + <string>Use Quicktime</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <layout class="QGridLayout" name="gridLayout_3"> + <item row="0" column="0"> + <widget class="QLabel" name="label_5"> + <property name="text"> + <string notr="true">vcodec</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QLineEdit" name="vcodec"/> + </item> + </layout> + </item> + </layout> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + </item> + <item> + <spacer name="verticalSpacer_5"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_4"> + <item> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="bSave"> + <property name="toolTip"> + <string>Will *not* save the project!</string> + </property> + <property name="text"> + <string>&Save settings</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="bAbort"> + <property name="text"> + <string>&Abort</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="bOk"> + <property name="text"> + <string>&Ok</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + <tabstops> + <tabstop>radioFullProject</tabstop> + <tabstop>cbFps</tabstop> + <tabstop>cbSize</tabstop> + <tabstop>cbInterpolation</tabstop> + <tabstop>radioVideo</tabstop> + <tabstop>radioImages</tabstop> + <tabstop>imagesOutputDir</tabstop> + <tabstop>bImagesBrowseDir</tabstop> + <tabstop>imagesFilenamePattern</tabstop> + <tabstop>videoOutputFile</tabstop> + <tabstop>bBrowseVideoOutputFile</tabstop> + <tabstop>vcodec</tabstop> + <tabstop>bAbort</tabstop> + <tabstop>bOk</tabstop> + </tabstops> + <resources/> + <connections/> +</ui>
View file
slowmoVideo-0.6.tar.xz/src/slowmoUI/dialogues/shutterFunctionDialog.cpp
Added
@@ -0,0 +1,220 @@ +/* +This file is part of slowmoVideo. +Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +*/ + +#include "shutterFunctionDialog.h" +#include "ui_shutterFunctionDialog.h" +#include "project/shutterFunction_sV.h" +#include "project/shutterFunctionList_sV.h" +#include "project/project_sV.h" +#include <QtGui/QPainter> + +QString ShutterFunctionDialog::emptyFunction("<None>"); + +/// \todo Icons +ShutterFunctionDialog::ShutterFunctionDialog(Project_sV *project, QWidget *parent) : + QDialog(parent), + ui(new Ui::ShutterFunctionDialog), + m_currentFunction(NULL) +{ + ui->setupUi(this); + + ui->lblcHeader->setText(ShutterFunction_sV::templateHeader); + ui->lblcFooter->setText(ShutterFunction_sV::templateFooter); + + connect(ui->bClose, SIGNAL(clicked()), this, SLOT(accept())); + connect(ui->cbFunction, SIGNAL(currentIndexChanged(int)), this, SLOT(slotUpdateNode())); + connect(ui->cbFunction, SIGNAL(currentIndexChanged(int)), this, SLOT(slotLoadSelectedFunction())); + connect(ui->function, SIGNAL(textChanged()), this, SLOT(slotFunctionTextChanged())); + connect(ui->bAdd, SIGNAL(clicked()), this, SLOT(slotAddFunction())); + connect(ui->bRemove, SIGNAL(clicked()), this, SLOT(slotRemoveFunction())); + + connect(ui->bPrevSegment, SIGNAL(clicked()), this, SLOT(slotPrevSegment())); + connect(ui->bNextSegment, SIGNAL(clicked()), this, SLOT(slotNextSegment())); + + loadProject(project); + slotLoadSelectedFunction(); +} + +ShutterFunctionDialog::~ShutterFunctionDialog() +{ + delete ui; +} + +void ShutterFunctionDialog::loadProject(Project_sV *project) +{ + qDebug() << "loadProject();"; + m_project = project; + ui->cbFunction->blockSignals(true); + ui->cbFunction->clear(); + ui->cbFunction->addItem(emptyFunction); + for (int i = 0; i < project->shutterFunctions()->size(); i++) { + ui->cbFunction->addItem(m_project->shutterFunctions()->at(i)->id()); + } + ui->cbFunction->blockSignals(false); + setSegment(0); +} + +void ShutterFunctionDialog::paintEvent(QPaintEvent *e) +{ + QDialog::paintEvent(e); + QPainter p(this); + QImage img(":images/shutterFunc.png"); + p.drawImage(ui->verticalLayout_code->contentsRect().topRight() - QPoint(img.width()+10, -10), img); +} + +void ShutterFunctionDialog::closeEvent(QCloseEvent *e) +{ + m_project->nodes()->segments()->unselectAll(); + parentWidget()->repaint(); + QDialog::closeEvent(e); +} + +void ShutterFunctionDialog::slotNodesUpdated() +{ + qDebug() << "slotNodesUpdated();"; + if (m_segment+1 >= m_project->nodes()->size() && m_project->nodes()->size() >= 2) { + setSegment(m_project->nodes()->size()-2); + } else { + setSegment(m_segment); + } +} + +void ShutterFunctionDialog::setSegment(int segment) +{ + qDebug() << "setSegment(" << segment << ");"; + m_segment = segment; + ui->lblSegmentNumber->setText(tr("Segment %1 (total number: %2)") + .arg(m_segment).arg(m_project->nodes()->size()-1)); + + // Enable/disable buttons + ui->bPrevSegment->setEnabled(m_segment > 0); + ui->bNextSegment->setEnabled(m_segment+1 < m_project->nodes()->size()-1); + + + // Update the curve parameters for this segment + if (m_project->nodes()->size() >= 2) { + const Node_sV *leftNode = &m_project->nodes()->at(m_segment); + const Node_sV *rightNode = &m_project->nodes()->at(m_segment+1); + ui->shutterCurve->updateValues( + leftNode->y(), + 1.0/24 * (rightNode->y()-leftNode->y()) / (rightNode->x()-leftNode->x()) // dy = dx * /\y / /\x + ); + + Q_ASSERT(m_segment+1 < m_project->nodes()->size()); + } else { + qDebug() << "Less than 2 nodes!"; + } + + // Select function in the dropdown + if (m_project->nodes()->size() >= 2) { + const Node_sV *node = &m_project->nodes()->at(m_segment); + QString id = node->shutterFunctionID(); + qDebug() << "Shutter function ID of node " << node << " is " << id; + if (id.length() == 0) { + ui->cbFunction->setCurrentIndex(ui->cbFunction->findText(emptyFunction)); + } else { + int pos = ui->cbFunction->findText(id); + Q_ASSERT(pos >= 0); + ui->cbFunction->setCurrentIndex(pos); + } + } + + m_project->nodes()->segments()->unselectAll(); + (*m_project->nodes()->segments())m_segment.select(); + parentWidget()->repaint(); + + Q_ASSERT(m_segment >= 0); +} + +void ShutterFunctionDialog::slotUpdateNode() +{ + qDebug() << "slotUpdateNode();"; + if (m_project->nodes()->size() >= 2) { + Q_ASSERT(m_segment+1 < m_project->nodes()->size()); + QString id = ui->cbFunction->currentText(); + if (id == emptyFunction) { + id = ""; + } + Node_sV *node = &(*m_project->nodes())m_segment; + node->setShutterFunctionID(id); + qDebug() << "Shutter function ID of node " << node << "set to " << id; + } +} + +void ShutterFunctionDialog::slotFunctionTextChanged() +{ + qDebug() << "slotUpdateFunctionCode();"; + if (m_currentFunction != NULL) { + ui->function->setEnabled(true); + m_currentFunction->updateFunction(ui->function->toPlainText()); + ui->shutterCurve->slotDisplayFunction(ui->function->toPlainText()); + } + else { + ui->function->setEnabled(false); + ui->shutterCurve->slotDisplayFunction("return 0;"); + } +} + +void ShutterFunctionDialog::slotLoadSelectedFunction() +{ + QString id = ui->cbFunction->currentText(); + if (id == emptyFunction) { + id = ""; + m_currentFunction = NULL; + ui->function->setPlainText("return 0;"); + } else { + m_currentFunction = m_project->shutterFunctions()->function(id); + ui->function->setPlainText(m_currentFunction->function()); + } + int count = 0; + for (int i = 0; i < m_project->nodes()->size(); i++) { + if (m_project->nodes()->at(i).shutterFunctionID() == id) { + count++; + } + } + ui->lblUsage->setText(tr("Used: %1 times").arg(count)); + +} + +void ShutterFunctionDialog::slotAddFunction() +{ + ShutterFunction_sV *fun = m_project->shutterFunctions()->addFunction(ShutterFunction_sV(), true); + if (fun != NULL) { + ui->cbFunction->addItem(fun->id()); + ui->cbFunction->setCurrentIndex(ui->cbFunction->findText(fun->id())); + } else { + qDebug() << "Could not add new function."; + Q_ASSERT(false); + } +} + +void ShutterFunctionDialog::slotRemoveFunction() +{ + if (ui->cbFunction->currentText() != emptyFunction) { + bool ok = m_project->shutterFunctions()->removeFunction(ui->cbFunction->currentText()); + int index = ui->cbFunction->currentIndex(); + ui->cbFunction->setCurrentIndex(ui->cbFunction->findText(emptyFunction)); + ui->cbFunction->removeItem(index); + Q_ASSERT(ok); + } +} + +void ShutterFunctionDialog::slotPrevSegment() +{ + qDebug() << "slotPrevSegment();"; + setSegment(m_segment-1); +} + +void ShutterFunctionDialog::slotNextSegment() +{ + qDebug() << "slotNextSegment();"; + setSegment(m_segment+1); +} +
View file
slowmoVideo-0.6.tar.xz/src/slowmoUI/dialogues/shutterFunctionDialog.h
Changed
(renamed from src/slowmoVideo/slowmoUI/dialogues/shutterFunctionDialog.h)
View file
slowmoVideo-0.6.tar.xz/src/slowmoUI/dialogues/shutterFunctionDialog.ui
Changed
(renamed from src/slowmoVideo/slowmoUI/dialogues/shutterFunctionDialog.ui)
View file
slowmoVideo-0.6.tar.xz/src/slowmoUI/dialogues/shutterFunctionFrame.cpp
Changed
(renamed from src/slowmoVideo/slowmoUI/dialogues/shutterFunctionFrame.cpp)
View file
slowmoVideo-0.6.tar.xz/src/slowmoUI/dialogues/shutterFunctionFrame.h
Changed
(renamed from src/slowmoVideo/slowmoUI/dialogues/shutterFunctionFrame.h)
View file
slowmoVideo-0.6.tar.xz/src/slowmoUI/dialogues/tagAddDialog.cpp
Added
@@ -0,0 +1,82 @@ +/* +This file is part of slowmoVideo. +Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +*/ + +#include "tagAddDialog.h" +#include "ui_tagAddDialog.h" +#include <QtGui/QKeyEvent> + +TagAddDialog::TagAddDialog(TagAxis defaultAxis, QWidget *parent) : + QDialog(parent), + ui(new Ui::TagAddDialog), + m_axis(defaultAxis) +{ + ui->setupUi(this); + ui->bOk->setEnabled(false); + + connect(ui->bAbort, SIGNAL(clicked()), this, SLOT(reject())); + connect(ui->bOk, SIGNAL(clicked()), this, SLOT(accept())); + connect(ui->tag, SIGNAL(textChanged(QString)), this, SLOT(slotTextChanged(QString))); + connect(ui->tag, SIGNAL(returnPressed()), ui->bOk, SLOT(click())); + + slotUpdateAxis(); +} + +TagAddDialog::~TagAddDialog() +{ + delete ui; +} + +Tag_sV TagAddDialog::buildTag(QPointF time) +{ + if (m_axis == TagAxis_Source) { + return Tag_sV(time.y(), ui->tag->text(), m_axis); + } else { + return Tag_sV(time.x(), ui->tag->text(), m_axis); + } +} + +void TagAddDialog::keyPressEvent(QKeyEvent *e) +{ + if (e->key() == Qt::Key_Up) { + m_axis = TagAxis_Source; + slotUpdateAxis(); + } else if (e->key() == Qt::Key_Down) { + m_axis = TagAxis_Output; + slotUpdateAxis(); + } else { + QDialog::keyPressEvent(e); + } +} + +void TagAddDialog::slotTextChanged(const QString &text) +{ + if (text.length() == 0) { + ui->bOk->setEnabled(false); + } else { + ui->bOk->setEnabled(true); + m_text = text; + } +} + +void TagAddDialog::slotUpdateAxis() +{ + QSizePolicy::Policy upperPolicy = QSizePolicy::Fixed; + QSizePolicy::Policy lowerPolicy = QSizePolicy::Expanding; + if (m_axis == TagAxis_Output) { + upperPolicy = QSizePolicy::Expanding; + lowerPolicy = QSizePolicy::Fixed; + } + ui->verticalUpperSpacer->changeSize(0, 0, QSizePolicy::Minimum, upperPolicy); + ui->verticalLowerSpacer->changeSize(0, 0, QSizePolicy::Minimum, lowerPolicy); + ui->verticalLayout_2->invalidate(); + + repaint(); + updateGeometry(); +}
View file
slowmoVideo-0.6.tar.xz/src/slowmoUI/dialogues/tagAddDialog.h
Changed
(renamed from src/slowmoVideo/slowmoUI/dialogues/tagAddDialog.h)
View file
slowmoVideo-0.6.tar.xz/src/slowmoUI/dialogues/tagAddDialog.ui
Changed
(renamed from src/slowmoVideo/slowmoUI/dialogues/tagAddDialog.ui)
View file
slowmoVideo-0.6.tar.xz/src/slowmoUI/flowEditCanvas.cpp
Added
@@ -0,0 +1,118 @@ +/* +slowmoFlowEdit is a user interface for editing slowmoVideo's Optical Flow files. +Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +*/ + +#include "flowEditCanvas.h" +#include "ui_flowEditCanvas.h" + +#include "flowRW_sV.h" +#include "lib/flowTools_sV.h" +#include "lib/flowVisualization_sV.h" + +#include <QtCore/QDebug> + +FlowEditCanvas::FlowEditCanvas(QWidget *parent) : + QWidget(parent), + ui(new Ui::FlowEditCanvas), + m_flowField(NULL), + m_boost(1.0) +{ + ui->setupUi(this); + + ui->flow->trackMouse(true); + + connect(ui->flow, SIGNAL(signalRectDrawn(QRectF)), this, SLOT(slotRectDrawn(QRectF))); + connect(ui->flow, SIGNAL(signalMouseMoved(float,float)), this, SLOT(slotExamineValues(float,float))); + connect(ui->amplification, SIGNAL(valueChanged(int)),this, SLOT(newAmplification(int))); + +} + +FlowEditCanvas::~FlowEditCanvas() +{ + delete ui; +} + +float FlowEditCanvas::amplification() const +{ + return m_boost; +} + +void FlowEditCanvas::setAmplification(float val) +{ + //qDebug() << "setAmplification: " << val; + Q_ASSERT(val > 0); + m_boost = val; + repaintFlow(); +} + +void FlowEditCanvas::newAmplification(int val) +{ + //qDebug() << "newAmplification: " << val; + Q_ASSERT(val > 0); + m_boost = (float)val; + repaintFlow(); +} + +/// \todo Make flow visualization configurable +void FlowEditCanvas::repaintFlow() +{ + if (m_flowField != NULL) { + ui->flow->loadImage(FlowVisualization_sV::colourizeFlow(m_flowField, FlowVisualization_sV::HSV, m_boost)); + repaint(); + } +} + +void FlowEditCanvas::slotRectDrawn(QRectF imageRect) +{ + qDebug() << "Rect drawn: " << imageRect; + if (m_flowField != NULL) { + Kernel_sV k(8, 8); + k.gauss(); + FlowTools_sV::deleteRect(*m_flowField, imageRect.top(), imageRect.left(), imageRect.bottom(), imageRect.right()); + FlowTools_sV::refill(*m_flowField, k, imageRect.top(), imageRect.left(), imageRect.bottom(), imageRect.right()); + repaintFlow(); + } +} + +void FlowEditCanvas::slotLoadFlow(QString filename) +{ + if (m_flowField != NULL) { + delete m_flowField; + m_flowField = NULL; + } + m_flowField = FlowRW_sV::load(filename.toStdString()); + m_flowFilename = filename; + + repaintFlow(); +} + +void FlowEditCanvas::slotSaveFlow(QString filename) +{ + if (m_flowField != NULL) { + if (filename.length() == 0) { + filename = m_flowFilename; + } + FlowRW_sV::save(filename.toStdString(), m_flowField); + } else { + qDebug() << "No flow file loaded, cannot save."; + } +} + +void FlowEditCanvas::slotExamineValues(float x, float y) +{ + if (m_flowField != NULL) { + if (x >= 0 && y >= 0 + && x <= m_flowField->width()-1 && y <= m_flowField->height()-1) { + float dx = m_flowField->x(x,y); + float dy = m_flowField->y(x,y); + ui->lblValues->setText(QString("dx/dy: (%1|%2)").arg(dx, 0, 'f', 2).arg(dy, 0, 'f', 2)); + ui->lblPos->setText(QString("(%1|%2)").arg(x).arg(y)); + } + } +}
View file
slowmoVideo-0.6.tar.xz/src/slowmoUI/flowEditCanvas.h
Added
@@ -0,0 +1,54 @@ +/* +slowmoFlowEdit is a user interface for editing slowmoVideo's Optical Flow files. +Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +*/ + +#ifndef FLOWEDITCANVAS_H +#define FLOWEDITCANVAS_H + +#include <QWidget> +#include <QtCore/QRectF> + +class FlowField_sV; +namespace Ui { + class FlowEditCanvas; +} + +/// \todo Auto-fix feature (confirm to accept) +class FlowEditCanvas : public QWidget +{ + Q_OBJECT + +public: + explicit FlowEditCanvas(QWidget *parent = 0); + ~FlowEditCanvas(); + + void setAmplification(float val); + float amplification() const; + + +public slots: + void slotLoadFlow(QString filename); + void slotSaveFlow(QString filename = QString()); + void newAmplification(int val); + +private: + Ui::FlowEditCanvas *ui; + + FlowField_sV *m_flowField; + QString m_flowFilename; + float m_boost; + + void repaintFlow(); + +private slots: + void slotRectDrawn(QRectF imageRect); + void slotExamineValues(float x, float y); +}; + +#endif // FLOWEDITCANVAS_H
View file
slowmoVideo-0.6.tar.xz/src/slowmoUI/flowEditCanvas.ui
Added
@@ -0,0 +1,141 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>FlowEditCanvas</class> + <widget class="QWidget" name="FlowEditCanvas"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>1058</width> + <height>608</height> + </rect> + </property> + <property name="windowTitle"> + <string notr="true">Form</string> + </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="2" column="0"> + <layout class="QHBoxLayout" name="horizontalLayout"> + <property name="sizeConstraint"> + <enum>QLayout::SetMinimumSize</enum> + </property> + <item> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QLabel" name="lblPos"> + <property name="text"> + <string notr="true">TextLabel</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_2"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>10</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QLabel" name="lblValues"> + <property name="text"> + <string>Values at mouse position</string> + </property> + </widget> + </item> + </layout> + </item> + <item row="0" column="0"> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <item> + <widget class="ImageDisplay" name="flow"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="frameShape"> + <enum>QFrame::StyledPanel</enum> + </property> + <property name="frameShadow"> + <enum>QFrame::Raised</enum> + </property> + </widget> + </item> + <item> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QSlider" name="amplification"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Expanding"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="maximum"> + <number>20</number> + </property> + <property name="sliderPosition"> + <number>3</number> + </property> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="tickPosition"> + <enum>QSlider::TicksBelow</enum> + </property> + <property name="tickInterval"> + <number>1</number> + </property> + </widget> + </item> + <item> + <spacer name="verticalSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + </layout> + </item> + </layout> + </widget> + <customwidgets> + <customwidget> + <class>ImageDisplay</class> + <extends>QFrame</extends> + <header>libgui/imageDisplay.h</header> + <container>1</container> + </customwidget> + </customwidgets> + <resources/> + <connections/> +</ui>
View file
slowmoVideo-0.6.tar.xz/src/slowmoUI/frameMonitor.cpp
Added
@@ -0,0 +1,108 @@ +/* +slowmoUI is a user interface for slowmoVideo. +Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +*/ + +#include "frameMonitor.h" +#include "ui_frameMonitor.h" + +#include <QImage> +#include <QPainter> +#include <QDebug> +#include <QSettings> + +FrameMonitor::FrameMonitor(QWidget *parent) : + QWidget(parent), + ui(new Ui::FrameMonitor), + m_semaphore(1) +{ + ui->setupUi(this); + + m_queue0 = NULL; + m_queue1 = NULL; + + imgCache.clear(); + setCacheLimit(10240); // cache size of 10Mb +} + +FrameMonitor::~FrameMonitor() +{ + delete ui; + if (m_queue0 != NULL) { delete m_queue0; } + if (m_queue1 != NULL) { delete m_queue1; } +} + +/** + * Sets the cache limit to n kilobytes. +*/ +void FrameMonitor::setCacheLimit(int n) +{ + cache_limit = n; + imgCache.setMaxCost(1024 * cache_limit); +} + +void FrameMonitor::slotLoadImage(const QString &filename) +{ + m_semaphore.acquire(); + if (m_queue0 == NULL) { + m_queue0 = new QString(filename); + } else { + if (m_queue1 != NULL) { + delete m_queue1; + m_queue1 = NULL; + } + m_queue1 = new QString(filename); + } + m_semaphore.release(); + repaint(); +} + +void FrameMonitor::closeEvent(QCloseEvent *event) +{ + QWidget::closeEvent(event); +} + +void FrameMonitor::paintEvent(QPaintEvent *) +{ + QString image; + m_semaphore.acquire(); + if (m_queue0 != NULL) { + image = *m_queue0; + delete m_queue0; + m_queue0 = NULL; + } + if (m_queue1 != NULL) { + m_queue0 = m_queue1; + m_queue1 = NULL; + } + m_semaphore.release(); + + if (!image.isNull()) { + // add some better cache mgmt + QImage *_image; + //qDebug() << "cost : " << imgCache.totalCost(); + if(imgCache.contains(image)) { + //return *(frameCache.object(path)); + //qDebug() << "cache : " << image; + _image = imgCache.object(image); + } else { + _image = new QImage(image); + //qDebug() << "cache store : " << image << "cost : " << _image->byteCount(); + //TODO: provide a method for that + bool success = imgCache.insert(image, _image, _image->byteCount()); + if ( !success) { + qDebug() << "WARN: memory error"; + _image = new QImage(image); + } + + } + + if (_image != 0) + ui->imageDisplay->loadImage(*_image); + } +}
View file
slowmoVideo-0.6.tar.xz/src/slowmoUI/frameMonitor.h
Added
@@ -0,0 +1,55 @@ +/* +slowmoUI is a user interface for slowmoVideo. +Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +*/ + +#ifndef INPUTMONITOR_H +#define INPUTMONITOR_H + +#include <QWidget> +#include <QSemaphore> +#include <QCache> +#include <QImage> + +namespace Ui { + class FrameMonitor; +} + +/** + \brief Used for displaying input frames at the mouse position. + */ +class FrameMonitor : public QWidget +{ + Q_OBJECT + +public: + explicit FrameMonitor(QWidget *parent = 0); + ~FrameMonitor(); + + void setCacheLimit(int n); + int cacheLimit() { return cache_limit; }; + +protected: + virtual void paintEvent(QPaintEvent *event); + virtual void closeEvent(QCloseEvent *event) ; + +public slots: + void slotLoadImage(const QString &filename); + +private: + Ui::FrameMonitor *ui; + + QSemaphore m_semaphore; + QString *m_queue2; + + // for cache mgmt + int cache_limit; + QCache<QString, QImage> imgCache; +}; + +#endif // INPUTMONITOR_H
View file
slowmoVideo-0.6.tar.xz/src/slowmoUI/frameMonitor.ui
Changed
(renamed from src/slowmoVideo/slowmoUI/frameMonitor.ui)
View file
slowmoVideo-0.6.tar.xz/src/slowmoUI/logbrowserdialog.cpp
Added
@@ -0,0 +1,106 @@ +/* + * snippet from : https://wiki.qt.io/index.php?title=Browser_for_QDebug_output&oldid=15731 + * add a logwindow to a project + * + */ +#include "logbrowserdialog.h" + +#include <QVBoxLayout> +#include <QTextBrowser> +#include <QPushButton> +#include <QFileDialog> +#include <QDir> +#include <QFile> +#include <QMessageBox> +#include <QTextStream> +#include <QCloseEvent> + +LogBrowserDialog::LogBrowserDialog(QWidget *parent) + : QDialog(parent) { + auto *layout = new QVBoxLayout; + setLayout(layout); + + browser = new QTextEdit(this); + layout->addWidget(browser); + + auto *buttonLayout = new QHBoxLayout; + buttonLayout->setContentsMargins(0, 0, 0, 0); + layout->addLayout(buttonLayout); + + buttonLayout->addStretch(10); + + clearButton = new QPushButton(this); + clearButton->setText("clear"); + buttonLayout->addWidget(clearButton); + connect(clearButton, SIGNAL (clicked()), browser, SLOT (clear())); + + saveButton = new QPushButton(this); + saveButton->setText("save output"); + buttonLayout->addWidget(saveButton); + connect(saveButton, SIGNAL (clicked()), this, SLOT (save())); + + resize(600, 400); +} + + +void LogBrowserDialog::outputMessage(QtMsgType type, const QString &msg) { + // out << QTime::currentTime().toString("hh:mm:ss.zzz "); + // fprintf(stderr, "Debug: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function); + QString temp; + + switch (type) { + case QtDebugMsg: + temp = (tr("DEBUG: %1").arg(msg)); + break; + case QtWarningMsg: + temp = (tr("WARNING: %1").arg(msg)); + break; + case QtCriticalMsg: + temp = (tr("CRITICAL: %1").arg(msg)); + break; + case QtFatalMsg: + temp = (tr("FATAL: %1").arg(msg)); + break; + default: + temp = (tr("UNK: %1").arg(msg)); + break; + } + // indirect invoke for threading safety + QMetaObject::invokeMethod(browser, "append", + Qt::QueuedConnection, Q_ARG(QString, temp)); +} + + +void LogBrowserDialog::save() { + QString saveFileName = QFileDialog::getSaveFileName( + this, + tr("Save Log Output"), + tr("%1/logfile.txt").arg(QDir::homePath()), + tr("Text Files ('''.txt);;All Files (*)") + ); + + if (saveFileName.isEmpty()) + return; + + QFile file(saveFileName); + if (!file.open(QIODevice::WriteOnly)) { + QMessageBox::warning( + this, + tr("Error"), + QString(tr("<nobr>File '%1'<br/>cannot be opened for writing.<br/><br/>" + "The log output could <b>not</b> be saved!</nobr>")) + .arg(saveFileName)); + return; + } + + QTextStream stream(&file); + stream << browser->toPlainText(); + file.close(); +} + +void LogBrowserDialog::keyPressEvent(QKeyEvent *e) { + // ignore all keyboard events + // protects against accidentally closing of the dialog + // without asking the user + e->ignore(); +}
View file
slowmoVideo-0.6.tar.xz/src/slowmoUI/logbrowserdialog.h
Added
@@ -0,0 +1,31 @@ +#ifndef LOGDIALOG_H +#define LOGDIALOG_H + +#include <QDialog> +#include <QTextEdit> + +class QPushButton; + +class LogBrowserDialog : public QDialog { +Q_OBJECT + +public: + explicit LogBrowserDialog(QWidget *parent = nullptr); + +public slots: + + void outputMessage(QtMsgType type, const QString &msg); + +protected slots: + + void save(); + +protected: + void keyPressEvent(QKeyEvent *e) override; + + QTextEdit *browser; + QPushButton *clearButton; + QPushButton *saveButton; +}; + +#endif // LOGDIALOG_H
View file
slowmoVideo-0.6.tar.xz/src/slowmoUI/macnotificationhandler.h
Added
@@ -0,0 +1,25 @@ +#ifndef MACNOTIFICATIONHANDLER_H +#define MACNOTIFICATIONHANDLER_H +#include <QObject> + +/** Macintosh-specific notification handler (supports UserNotificationCenter and Growl). + */ +class MacNotificationHandler : public QObject +{ + Q_OBJECT + +public: + /** shows a 10.8+ UserNotification in the UserNotificationCenter + */ + void showNotification(const QString &title, const QString &text); + + /** executes AppleScript */ + void sendAppleScript(const QString &script); + + /** check if OS can handle UserNotifications */ + bool hasUserNotificationCenterSupport(void); + static MacNotificationHandler *instance(); +}; + + +#endif // MACNOTIFICATIONHANDLER_H
View file
slowmoVideo-0.6.tar.xz/src/slowmoUI/macnotificationhandler.mm
Added
@@ -0,0 +1,68 @@ +#include "macnotificationhandler.h" + +#undef slots +#include <Cocoa/Cocoa.h> + +void MacNotificationHandler::showNotification(const QString &title, const QString &text) +{ + // check if users OS has support for NSUserNotification + if(this->hasUserNotificationCenterSupport()) { + // okay, seems like 10.8+ + QByteArray utf8 = title.toUtf8(); + char* cString = (char *)utf8.constData(); + NSString *titleMac = NSString alloc initWithUTF8String:cString; + + utf8 = text.toUtf8(); + cString = (char *)utf8.constData(); + NSString *textMac = NSString alloc initWithUTF8String:cString; + + // do everything weak linked (because we will keep <10.8 compatibility) + Class userNotification = NSClassFromString(@"NSUserNotification") alloc init; + if (userNotification) { + userNotification performSelector:@selector(setTitle:) withObject:titleMac; + userNotification performSelector:@selector(setInformativeText:) withObject:textMac; + } + + Class notificationCenterInstance = NSClassFromString(@"NSUserNotificationCenter") performSelector:@selector(defaultUserNotificationCenter); + if (notificationCenterInstance) + notificationCenterInstance performSelector:@selector(deliverNotification:) withObject:userNotification; + + titleMac release; + textMac release; + userNotification release; + } +} + +// sendAppleScript just take a QString and executes it as apple script +void MacNotificationHandler::sendAppleScript(const QString &script) +{ + QByteArray utf8 = script.toUtf8(); + char* cString = (char *)utf8.constData(); + NSString *scriptApple = NSString alloc initWithUTF8String:cString; + + NSAppleScript *as = NSAppleScript alloc initWithSource:scriptApple; + NSDictionary *err = nil; + as executeAndReturnError:&err; + as release; + scriptApple release; +} + +bool MacNotificationHandler::hasUserNotificationCenterSupport(void) +{ + Class possibleClass = NSClassFromString(@"NSUserNotificationCenter"); + + // check if users OS has support for NSUserNotification + if(possibleClass!=nil) { + return true; + } + return false; +} + + +MacNotificationHandler *MacNotificationHandler::instance() +{ + static MacNotificationHandler *s_instance = NULL; + if (!s_instance) + s_instance = new MacNotificationHandler(); + return s_instance; +}
View file
slowmoVideo-0.6.tar.xz/src/slowmoUI/main.cpp
Added
@@ -0,0 +1,116 @@ +/* +slowmoUI is a user interface for slowmoVideo. +Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +*/ + +#include <QApplication> +#include <QPointer> +#include <QtCore/QTranslator> +#include <QtCore/QDebug> + +#include "opencv2/core/version.hpp" + +#include "mainwindow.h" +#include "logbrowserdialog.h" + +QPointer<LogBrowserDialog> logBrowser; + +/** + * Message handler; see https://doc.qt.io/qt-5/qtglobal.html#qInstallMessageHandler + */ +void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg) { + if (logBrowser) { + logBrowser->outputMessage(type, msg); + } +} + +int main(int argc, char *argv) { + QApplication app(argc, argv); + + // Set up preferences for the QSettings file + QCoreApplication::setOrganizationName("Granjow"); + QCoreApplication::setOrganizationDomain("granjow.net"); + QCoreApplication::setApplicationName("slowmoUI"); + + QString projectPath; + bool logToStdout = true; + + const int N = app.arguments().size(); + for (int n = 1; n < N; n++) { + QString arg = app.arguments().at(n); + if (arg.startsWith("--")) { + + bool langUpdated = false; + + // Changes the file loaded from the resource container + // to force a different language + if (arg == "--fr") { + QLocale::setDefault(QLocale::French); + langUpdated = true; + } else if (arg == "--de") { + QLocale::setDefault(QLocale::German); + langUpdated = true; + } else if (arg == "--en") { + QLocale::setDefault(QLocale::English); + langUpdated = true; + } else if (arg == "--it") { + QLocale::setDefault(QLocale::Italian); + langUpdated = true; + } else if (arg == "--no-stdout") { + logToStdout = false; + } else { + langUpdated = false; + } + + if (langUpdated) { + qDebug() << "Changed locale to " << QLocale::languageToString(QLocale().language()); + } else { + qDebug() << "Not handled: " << arg; + } + + } else { + QFileInfo info(arg); + if (info.exists() && info.isReadable() && info.isFile()) { + projectPath = info.absoluteFilePath(); + qDebug() << "Loading project: " << projectPath; + } else { + qDebug() << projectPath << " does not exist."; + } + } + } + + // Setup debug output system. + logBrowser = new LogBrowserDialog; + if (logToStdout) { + myMessageOutput(QtInfoMsg, QMessageLogContext(), "Log is going to stdout."); + } else { + qInstallMessageHandler(myMessageOutput); + } + + qDebug() << QApplication::arguments(); + qDebug() << "threading info : " << QThread::idealThreadCount(); + // TODO: place this in About ... + qDebug() << "OpenCV version: " << CV_MAJOR_VERSION << "." + << CV_MINOR_VERSION << "." << CV_SUBMINOR_VERSION; + + // Load the translation file from the resource container and use it + QTranslator translator; + translator.load(":translations"); + QApplication::installTranslator(&translator); + + MainWindow w(projectPath); + + w.show(); + + //use menu here : logBrowser->show(); + + int result = QApplication::exec(); + qDebug() << "application exec return result =" << result; + delete logBrowser; + return result; +}
View file
slowmoVideo-0.6.tar.xz/src/slowmoUI/mainwindow.cpp
Added
@@ -0,0 +1,701 @@ +/* +slowmoUI is a user interface for slowmoVideo. +Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +*/ + +#include <QtCore> +#include <QPointer> +#include <QObject> +#include <QDockWidget> +#include <QDebug> +#include <QMessageBox> +#include <QStatusBar> + +#include <QDir> +#include <QFileDialog> + +#include <QShortcut> +#include <QSignalMapper> +#include <QTime> +#include <QFuture> + +#include <QPainter> + +#include <functional> + +#include "mainwindow.h" +#include "ui_mainwindow.h" + +#include "newProjectDialog.h" +#include "progressDialog.h" +#include "renderingDialog.h" +#include "projectPreferencesDialog.h" +#include "preferencesDialog.h" +#include "aboutDialog.h" + +#include "lib/defs_sV.hpp" +#include "project/renderTask_sV.h" +#include "project/xmlProjectRW_sV.h" +#include "project/abstractFrameSource_sV.h" +#include "project/projectPreferences_sV.h" + +// for editing optical flow +#include "flowEditCanvas.h" + +#include "logbrowserdialog.h" + + +extern QPointer<LogBrowserDialog> logBrowser; + +MainWindow::MainWindow(const QString& projectPath, QWidget *parent) : + QMainWindow(parent), + ui(new Ui::MainWindow), + m_progressDialog(nullptr), + m_renderProgressDialog(nullptr), + m_flowExaminer(nullptr), + m_cs(this) +{ + ui->setupUi(this); + + m_project = new Project_sV(); + + m_wCanvas = new Canvas(m_project, this); + setCentralWidget(m_wCanvas); + + createActions(); + createDockWindows(); + + updateWindowTitle(); + setWindowIcon(QIcon(":icons/slowmoIcon.png")); + + QSettings settings; + bool show = settings.value("ui/displayHelp", true).toBool(); + m_wCanvas->showHelp(show); + settings.sync(); + + restoreGeometry(settings.value("mainwindow/geometry").toByteArray()); + restoreState(settings.value("mainwindow/windowState").toByteArray()); + + if (!projectPath.isEmpty()) { + loadProject(projectPath); + } + + if (!settings.contains("binaries/ffmpeg")) { + qDebug() << "need to find ffmpeg"; + QMessageBox::information( this, + "valid FFMPEG not found", "Please choose a working ffmpeg\n" , + QMessageBox::Ok, 0 ); + PreferencesDialog dialog; + dialog.exec(); + } +} + +MainWindow::~MainWindow() +{ + delete ui; + delete m_wInputMonitor; + delete m_wCurveMonitor; + delete m_wInputMonitorDock; + delete m_wCurveMonitorDock; + delete m_wRenderPreview; + delete m_wRenderPreviewDock; + + delete m_project; + + // shoudl check task ? + m_rendererThread.quit(); + m_rendererThread.wait(); + + delete m_progressDialog; + delete m_renderProgressDialog; + delete m_flowExaminer; + + for (int i = 0; i < m_widgetActions.size(); i++) { + delete m_widgetActionsi; + } + +} + +void MainWindow::createActions() +{ + ui->actionNew->setShortcut(QKeySequence(QKeySequence::New)); + ui->actionOpen->setShortcut(QKeySequence(QKeySequence::Open)); + ui->actionSave->setShortcut(QKeySequence(QKeySequence::Save)); + ui->actionSave_as->setShortcut(QKeySequence("Shift+Ctrl+S")); + ui->actionShortcuts->setShortcut(QKeySequence("Ctrl+H")); + ui->actionRender->setShortcut(QKeySequence("Ctrl+R")); + ui->actionRenderPreview->setShortcut(QKeySequence("Shift+Ctrl+R")); + ui->actionExamineFlow->setShortcut(QKeySequence("Shift+Ctrl+X")); + ui->actionPreferences->setShortcut(QKeySequence("Ctrl+,")); + ui->actionAbout->setShortcut(QKeySequence("F1")); + ui->actionQuit->setShortcut(QKeySequence(QKeySequence::Quit)); + ui->actionZoomIn->setShortcut(QKeySequence(QKeySequence::ZoomIn)); + ui->actionZoomOut->setShortcut(QKeySequence(QKeySequence::ZoomOut)); + + m_cs.addShortcut("h", Help, tr("Show help overlay")); + m_cs.addShortcut("q-q", Quit, tr("Quit")); + m_cs.addShortcut("n", New, tr("New project")); + m_cs.addShortcut("o", Open, tr("Open project")); + m_cs.addShortcut("s-s", Save_Same, tr("Save")); + m_cs.addShortcut("s-a", Save_As, tr("Save as ...")); + m_cs.addShortcut("a", Abort, tr("Abort move")); + m_cs.addShortcut("a-s", Abort_Selection, tr("Unselect all")); + m_cs.addShortcut("d-n", Delete_Node, tr("Delete selected nodes")); + m_cs.addShortcut("t-s", Tool_Select, tr("Selecting tool")); + m_cs.addShortcut("t-m", Tool_Move, tr("Move tool")); + m_cs.addShortcut("t-t", Tag, tr("Insert label (tag)")); + + connect(&m_cs, SIGNAL(signalShortcutUsed(int)), this, SLOT(slotShortcutUsed(int))); + + connect(this, SIGNAL(deleteNodes()), m_wCanvas, SLOT(slotDeleteNodes())); + connect(this, SIGNAL(setMode(Canvas::ToolMode)), m_wCanvas, SLOT(slotSetToolMode(Canvas::ToolMode))); + connect(this, SIGNAL(abort(Canvas::Abort)), m_wCanvas, SLOT(slotAbort(Canvas::Abort))); + connect(this, SIGNAL(addTag()), m_wCanvas, SLOT(slotAddTag())); + + connect(ui->actionZoomIn, SIGNAL(triggered()), m_wCanvas, SLOT(slotZoomIn())); + connect(ui->actionZoomOut, SIGNAL(triggered()), m_wCanvas, SLOT(slotZoomOut())); + + connect(m_wCanvas, SIGNAL(signalMouseInputTimeChanged(qreal)), + this, SLOT(slotForwardInputPosition(qreal))); + connect(m_wCanvas, SIGNAL(signalMouseCurveSrcTimeChanged(qreal)), + this, SLOT(slotForwardCurveSrcPosition(qreal))); + + + connect(ui->actionNew, SIGNAL(triggered()), this, SLOT(slotNewProject())); + connect(ui->actionOpen, SIGNAL(triggered()), this, SLOT(slotLoadProjectDialog())); + connect(ui->actionSave, SIGNAL(triggered()), this, SLOT(slotSaveProject())); + connect(ui->actionSave_as, SIGNAL(triggered()), this, SLOT(slotSaveProjectDialog())); + connect(ui->actionRender, SIGNAL(triggered()), this, SLOT(slotShowRenderDialog())); + connect(ui->actionRenderPreview, SIGNAL(triggered()), this, SLOT(slotUpdateRenderPreview())); + connect(ui->actionExamineFlow, SIGNAL(triggered()), this, SLOT(slotShowFlowExaminerDialog())); + connect(ui->actionPreferences, SIGNAL(triggered()), this, SLOT(slotShowPreferencesDialog())); + connect(ui->actionShortcuts, SIGNAL(triggered()), this, SLOT(slotToggleHelp())); + connect(ui->actionAbout, SIGNAL(triggered()), this, SLOT(slotShowAboutDialog())); + connect(ui->actionQuit, SIGNAL(triggered()), this, SLOT(close())); + connect(ui->actionProjectPreferences, SIGNAL(triggered()), this, SLOT(slotShowProjectPreferencesDialog())); + connect(ui->actionEdit_Flow, SIGNAL(triggered()), this, SLOT(slotShowFlowEditWindow())); + connect(ui->actionDebug_Window, SIGNAL(toggled(bool)), this, SLOT(slotShowDebugWindow(bool))); +} + +void MainWindow::createDockWindows() +{ + m_wInputMonitor = new FrameMonitor(this); + m_wInputMonitorDock = new QDockWidget(tr("Input monitor"), this); + m_wInputMonitorDock->setWidget(m_wInputMonitor); + m_wInputMonitorDock->setObjectName("inputMonitor"); + addDockWidget(Qt::TopDockWidgetArea, m_wInputMonitorDock); + + m_wCurveMonitor = new FrameMonitor(this); + m_wCurveMonitorDock = new QDockWidget(tr("Curve monitor"), this); + m_wCurveMonitorDock->setWidget(m_wCurveMonitor); + m_wCurveMonitorDock->setObjectName("curveMonitor"); + addDockWidget(Qt::TopDockWidgetArea, m_wCurveMonitorDock); + + m_wRenderPreview = new RenderPreview(m_project, this); + m_wRenderPreviewDock = new QDockWidget(tr("Render preview"), this); + m_wRenderPreviewDock->setWidget(m_wRenderPreview); + m_wRenderPreviewDock->setObjectName("renderPreview"); + addDockWidget(Qt::TopDockWidgetArea, m_wRenderPreviewDock); + //TODO: replace by : + // ui->menuView->addAction(dock->toggleViewAction()); + // http://ariya.ofilabs.com/2007/04/custom-toggle-action-for-qdockwidget.html + + // Fill the view menu that allows (de)activating widgets + QObjectList windowChildren = children(); + QDockWidget *w; + for (auto i : windowChildren) { + if ((w = dynamic_cast<QDockWidget*>(i)) != nullptr) { + qDebug() << "Adding " << w->windowTitle() << " to the menu's widget list"; + + auto *a = new QAction("&" + w->objectName(), this); + a->setCheckable(true); + connect(a, SIGNAL(toggled(bool)), w, SLOT(setVisible(bool))); + // This does not work since it is also emitted e.g. when the window is minimized + // (with «Show Desktop» on KDE4), therefore an event filter is required. (below.) + // Thanks ArGGu^^ for the tip! + connect(w, SIGNAL(visibilityChanged(bool)), a, SLOT(setChecked(bool))); + //a->setChecked(true); + + + ui->menuView->addAction(a); + m_widgetActions << a; + + } + } +} + +bool MainWindow::okToContinue() +{ + if (isWindowModified()) { + int r = QMessageBox::warning(this, tr("slowmoUI"), + tr("The document has been modified.\n" + "Do you want to save your changes?"), + QMessageBox::Yes | QMessageBox::No + | QMessageBox::Cancel); + if (r == QMessageBox::Yes) { + slotSaveProjectDialog(); + return true; + } else if (r == QMessageBox::Cancel) { + return false; + } + } + return true; +} + +void MainWindow::closeEvent(QCloseEvent *e) +{ + if (okToContinue()) { + qDebug() << "closing"; + m_settings.setValue("mainwindow/geometry", saveGeometry()); + m_settings.setValue("mainwindow/windowState", saveState()); + logBrowser->close(); + QMainWindow::closeEvent(e); + } +} + + + + + +////////// Shortcuts + +void MainWindow::slotShortcutUsed(int id) +{ + if (id == Quit) { + qApp->quit(); + } else if (id == Abort_Selection) { + emit abort(Canvas::Abort_Selection); + } else if (id == Delete_Node) { + emit deleteNodes(); + } else if (id == Tool_Select) { + emit setMode(Canvas::ToolMode_Select); + } else if (id == Tool_Move) { + emit setMode(Canvas::ToolMode_Move); + } else if (id == Tag) { + emit addTag(); + } else if (id == Save_Same) { + slotSaveProject(); + } else if (id == Save_As) { + slotSaveProjectDialog(); + } else if (id == Abort) { + emit abort(Canvas::Abort_General); + } else if (id == Help) { + slotToggleHelp(); + } else if (id == New) { + slotNewProject(); + } else if (id == Open) { + slotLoadProjectDialog(); + } +} + + +////////// Project R/W + +void MainWindow::slotNewProject() +{ + NewProjectDialog npd(this); + if (npd.exec() == QDialog::Accepted) { + try { + Project_sV *project = npd.buildProject(); + + // Save project + XmlProjectRW_sV writer; + + //qDebug() << "Saving project as " << npd.filename; + // check if directory exist ... + QFileInfo projfile(npd.projectFilename()); + QDir dir(projfile.absoluteDir()); + if (!dir.exists()) { + dir.mkpath("."); + } + + try { + writer.saveProject(project, npd.projectFilename()); + statusBar()->showMessage(QString(tr("Saved project as: %1")).arg(npd.projectFilename())); + setWindowModified(false); + } catch (Error_sV &err) { + QMessageBox(QMessageBox::Warning, tr("Error writing project file"), err.message()).exec(); + } + + m_projectPath = npd.projectFilename(); + + project->preferences()->viewport_secRes() = QPointF(400, 400)/project->frameSource()->framesCount()*project->frameSource()->fps()->fps(); + + /* add a first (default) node */ + Node_sV snode; + + snode.setX(0.0); + snode.setY(0.0); + project->nodes()->add(snode); + + loadProject(project); + + m_wCanvas->showHelp(true); + setWindowModified(true); + + } catch (FrameSourceError &err) { + QMessageBox(QMessageBox::Warning, "Frame source error", err.message()).exec(); + } + } +} + +void MainWindow::loadProject(Project_sV *project) +{ + Q_ASSERT(project != nullptr); + resetDialogs(); + + Project_sV *projTemp = nullptr; + if (m_project != nullptr) { + projTemp = m_project; + } + m_project = project; + m_wCanvas->load(m_project); + m_wRenderPreview->load(m_project); + updateWindowTitle(); + + // Do not delete the old project object earlier to avoid segfaults + // (may still be used in the ShutterFunction dialog e.g.) + delete projTemp; + + connect(m_project->frameSource(), SIGNAL(signalNextTask(QString,int)), this, SLOT(slotNewFrameSourceTask(QString,int))); + connect(m_project->frameSource(), SIGNAL(signalAllTasksFinished()), this, SLOT(slotFrameSourceTasksFinished())); + + m_project->frameSource()->initialize(); + +} +void MainWindow::slotLoadProjectDialog() +{ + if (okToContinue()) { + QString dir = m_settings.value("directories/lastOpenedProject", QDir::current().absolutePath()).toString(); + QString file = QFileDialog::getOpenFileName(this, tr("Load Project"), dir, tr("slowmoVideo projects (*.sVproj)")); + + if (!file.isEmpty()) { + qDebug() << file; + loadProject(QFileInfo(file).absoluteFilePath()); + } + } +} + +void MainWindow::loadProject(QString path) +{ + m_settings.setValue("directories/lastOpenedProject", path); + XmlProjectRW_sV reader; + try { + QString warning; + Project_sV *project = reader.loadProject(path, &warning); + if (warning.length() > 0) { + QMessageBox(QMessageBox::Warning, tr("Warning"), warning).exec(); + } + m_projectPath = path; + loadProject(project); + } catch (FrameSourceError &err) { + QMessageBox(QMessageBox::Warning, tr("Frame source error"), err.message()).exec(); + } catch (Error_sV &err) { + QMessageBox(QMessageBox::Warning, tr("Error"), err.message()).exec(); + } +} + + +void MainWindow::slotSaveProject(QString filename) +{ + if (filename.length() == 0) { + filename = m_project->projectFilename(); + } + if (filename.length() == 0) { + qDebug() << "No filename given, won't save. (Perhaps an empty project?)"; + statusBar()->showMessage(tr("No filename given, won't save. (Perhaps an empty project?)"), 5000); + } else { + qDebug() << "Saving project as " << filename; + try { + XmlProjectRW_sV writer; + writer.saveProject(m_project, filename); + statusBar()->showMessage(QString(tr("Saved project as: %1")).arg(filename)); + setWindowModified(false); + } catch (Error_sV &err) { + QMessageBox(QMessageBox::Warning, tr("Error writing project file"), err.message()).exec(); + } + } +} +void MainWindow::slotSaveProjectDialog() +{ + QFileDialog dialog(this, tr("Save project")); + dialog.setAcceptMode(QFileDialog::AcceptSave); + dialog.setDefaultSuffix("sVproj"); + dialog.setNameFilter(tr("slowmoVideo projects (*.sVproj)")); + dialog.setFileMode(QFileDialog::AnyFile); + dialog.setDirectory(QFileInfo(m_project->projectFilename()).absolutePath()); + if (dialog.exec() == QDialog::Accepted) { + slotSaveProject(dialog.selectedFiles().at(0)); + } +} + + + +////////// UI interaction + +void MainWindow::slotToggleHelp() +{ + m_wCanvas->toggleHelp(); +} +void MainWindow::displayHelp(QPainter &davinci) const +{ + QString helpText = m_cs.shortcutList() + + tr("\nNavigation: Shift Scroll, Drag") + + tr("\nMove nodes: Ctrl Drag"); + + QRect content; + const QPoint topLeft(10, 10); + const QPoint padding(10, 10); + + // Check how big the text's bounding box will be + davinci.drawText(QRect(0,0,0,0), Qt::AlignLeft | Qt::TextExpandTabs, helpText, &content); + + // Draw the background + content.adjust(topLeft.x(), topLeft.y(), topLeft.x()+2*padding.x(), topLeft.y()+2*padding.y()); + davinci.fillRect(content, QColor(0,0,40, 200)); + + // Really draw the text now + content.translate(padding); + davinci.drawText(content, Qt::AlignLeft, helpText, &content); +} +void MainWindow::slotForwardInputPosition(qreal frame) +{ + if (0 <= frame && frame < m_project->frameSource()->framesCount()) { + m_wInputMonitor->slotLoadImage(m_project->frameSource()->framePath(qFloor(frame), FrameSize_Small)); + } +} +void MainWindow::slotForwardCurveSrcPosition(qreal frame) +{ + if (0 <= frame && frame < m_project->frameSource()->framesCount()) { + m_wCurveMonitor->slotLoadImage(m_project->frameSource()->framePath(qFloor(frame), FrameSize_Small)); + } +} +void MainWindow::slotUpdateRenderPreview() +{ + m_wRenderPreview->slotRenderAt(m_project->snapToOutFrame( + m_wCanvas->prevMouseTime().x(), false, + m_project->preferences()->renderFPS(), nullptr) + ); +} + + +void MainWindow::updateWindowTitle() +{ + QString project(tr("empty project")); + if (m_projectPath.length() > 0) { + project = m_projectPath; + } + setWindowTitle(QString("slowmo UI (%1) *").arg(project)); +} + + + +////////// Dialogues + +void MainWindow::resetDialogs() +{ + if (m_progressDialog != nullptr) { + m_progressDialog->close(); + delete m_progressDialog; + m_progressDialog = nullptr; + } + if (m_renderProgressDialog != nullptr) { + m_renderProgressDialog->close(); + delete m_renderProgressDialog; + m_renderProgressDialog = nullptr; + } + if (m_flowExaminer != nullptr) { + m_flowExaminer->close(); + delete m_flowExaminer; + m_flowExaminer = nullptr; + } +} + +void MainWindow::slotShowAboutDialog() +{ + AboutDialog dialog(this); + dialog.exec(); +} + +void MainWindow::slotShowPreferencesDialog() +{ + PreferencesDialog dialog; + dialog.exec(); + // Use the new flow method (if it has changed) + m_project->reloadFlowSource(); +} + +void MainWindow::slotShowProjectPreferencesDialog() +{ + ProjectPreferencesDialog ppd(m_project->preferences(), this); + ppd.exec(); +} + +void MainWindow::slotShowFlowExaminerDialog() +{ + if (m_flowExaminer == nullptr) { + m_flowExaminer = new FlowExaminer(m_project, this); + } + + int frame = floor(m_wCanvas->prevMouseInFrame()); + if (frame+1 >= m_project->frameSource()->framesCount()) { + frame = m_project->frameSource()->framesCount()-2; + } + if (frame < 0) { frame = 0; } + + m_flowExaminer->show(); + m_flowExaminer->examine(frame); +} + +void MainWindow::slotShowRenderDialog() +{ + if (m_project->renderTask() != nullptr) { + disconnect(SIGNAL(signalRendererContinue()), m_project->renderTask()); + } + + RenderingDialog renderingDialog(m_project, this); + if (renderingDialog.exec() == QDialog::Accepted) { + + RenderTask_sV *task = renderingDialog.buildTask(); + if (task != nullptr) { + task->moveToThread(&m_rendererThread); + + if (m_project->renderTask() != nullptr) { + disconnect(SIGNAL(signalRendererContinue()), m_project->renderTask()); + } + //m_project->replaceRenderTask(task); + + if (m_renderProgressDialog == nullptr) { + m_renderProgressDialog = new ProgressDialog(this); + m_renderProgressDialog->setWindowTitle(tr("Rendering progress")); + } else { + m_renderProgressDialog->disconnect(); + } + + connect(task, SIGNAL(signalNewTask(QString,int)), m_renderProgressDialog, SLOT(slotNextTask(QString,int))); + connect(task, SIGNAL(signalItemDesc(QString)), m_renderProgressDialog, SLOT(slotTaskItemDescription(QString))); + connect(task, SIGNAL(signalTaskProgress(int)), m_renderProgressDialog, SLOT(slotTaskProgress(int))); + connect(task, SIGNAL(signalRenderingFinished(QString)), m_renderProgressDialog, SLOT(slotAllTasksFinished(QString))); + connect(task, SIGNAL(signalRenderingAborted(QString)), this, SLOT(slotRenderingAborted(QString))); + connect(task, SIGNAL(signalRenderingAborted(QString)), m_renderProgressDialog, SLOT(close())); + connect(task, SIGNAL(signalRenderingStopped(QString)), m_renderProgressDialog, SLOT(slotAborted(QString))); + connect(m_renderProgressDialog, SIGNAL(signalAbortTask()), task, SLOT(slotStopRendering())); + //connect(this, SIGNAL(signalRendererContinue()), task, SLOT(slotContinueRendering()), Qt::UniqueConnection); + + connect(task, SIGNAL(workFlowRequested()), &m_rendererThread, SLOT(start())); + connect(&m_rendererThread, SIGNAL(started()), task, SLOT(slotContinueRendering())); + + connect(task, SIGNAL(signalRenderingFinished(QString)), &m_rendererThread, SLOT(quit())); + // done another way ?! + connect(task, SIGNAL(signalRenderingFinished(QString)), task, SLOT(deleteLater())); + + //connect(&m_rendererThread, &QThread::finished, task, &QObject::deleteLater); + // let's start + m_rendererThread.wait(); // If the thread is not running, this will immediately return. + + m_renderProgressDialog->show(); + + //emit signalRendererContinue(); + //m_rendererThread.exec (); + m_rendererThread.start(); + task->requestWork(); + } + } else { + QMessageBox(QMessageBox::Warning, tr("Aborted"), tr("Aborted by user"), QMessageBox::Ok).exec(); + } +} + +void MainWindow::slotRenderingAborted(QString message) +{ + QMessageBox(QMessageBox::Warning, tr("Error"), message, QMessageBox::Ok).exec(); +} + +void MainWindow::slotNewFrameSourceTask(const QString taskDescription, int taskSize) +{ + if (m_progressDialog == nullptr) { + m_progressDialog = new ProgressDialog(this); + m_progressDialog->setWindowTitle(tr("Frame extraction progress")); + connect(m_project->frameSource(), SIGNAL(signalNextTask(QString,int)), m_progressDialog, SLOT(slotNextTask(QString,int))); + connect(m_project->frameSource(), SIGNAL(signalTaskProgress(int)), m_progressDialog, SLOT(slotTaskProgress(int))); + connect(m_project->frameSource(), SIGNAL(signalTaskItemDescription(QString)), m_progressDialog, SLOT(slotTaskItemDescription(QString))); + connect(m_project->frameSource(), SIGNAL(signalAllTasksFinished()), m_progressDialog, SLOT(slotAllTasksFinished())); + connect(m_progressDialog, SIGNAL(signalAbortTask()), m_project->frameSource(), SLOT(slotAbortInitialization())); + } + m_progressDialog->show(); + m_progressDialog->slotNextTask(taskDescription, taskSize); +} +void MainWindow::slotFrameSourceTasksFinished() +{ + QTimer::singleShot(200, this, SLOT(slotCloseFrameSourceProgress())); +} +void MainWindow::slotCloseFrameSourceProgress() +{ + if (m_progressDialog != nullptr) { + m_progressDialog->close(); + } + //is right place ? should we check ? + m_project->buildCacheFlowSource(); +} + +#if 0 +/** + * load a flow file in edit window + * + * @param filename <#filename description#> + */ +void MainWindow::loadFlow(QString filename) +{ + if (QFileInfo(filename).exists()) { + m_canvas->slotLoadFlow(filename); + m_lastFlowFile = filename; + updateTitle(); + } +} +#endif + +/** + * display the optical flow editor + */ +void MainWindow::slotShowFlowEditWindow() +{ +//TODO: show window + qDebug() << "slotShowFlowEditWindow: No Yet Implemented"; + #if 1 + FlowEditCanvas* m_canvas; + m_canvas = new FlowEditCanvas(0); + m_canvas->show(); + #endif +#if 0 + // dock it + QDockWidget *m_wflowMonitorDock = new QDockWidget(tr("Flow monitor"), this); + m_wflowMonitorDock->setWidget(m_canvas); + m_wflowMonitorDock->setObjectName("flowMonitor"); + addDockWidget(Qt::TopDockWidgetArea, m_wflowMonitorDock); +#endif +} + +/** + * display/hide the debug window + */ +void MainWindow::slotShowDebugWindow(bool set) +{ + qDebug() << "slotShowDebugWindow " << set; + + if (set) + logBrowser->show(); + else + logBrowser->hide(); +#if 0 + // dock it + QDockWidget *m_wflowMonitorDock = new QDockWidget(tr("Flow monitor"), this); + m_wflowMonitorDock->setWidget(m_canvas); + m_wflowMonitorDock->setObjectName("flowMonitor"); + addDockWidget(Qt::TopDockWidgetArea, m_wflowMonitorDock); +#endif + +}
View file
slowmoVideo-0.6.tar.xz/src/slowmoUI/mainwindow.h
Added
@@ -0,0 +1,140 @@ +/* +slowmoUI is a user interface for slowmoVideo. +Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +*/ + +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include "canvas.h" +#include "frameMonitor.h" +#include "renderPreview.h" +#include "dialogues/flowExaminer.h" +#include "../project/project_sV.h" +#include "../libgui/combinedShortcuts.h" + +namespace Ui { + class MainWindow; +} + +#include <QMainWindow> +#include <QtCore/QMap> +#include <QtCore/QList> +#include <QtCore/QTime> +#include <QtCore/QThread> +#include <QSettings> + +class Canvas; +class ProgressDialog; +class QShortcut; +class QSignalMapper; + +namespace Ui { + class MainWindow; +} + +/// \todo Call flow editor from here +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + explicit MainWindow(const QString& projectPath = QString(), QWidget *parent = 0); + ~MainWindow(); + + void displayHelp(QPainter &davinci) const; + +protected slots: + virtual void closeEvent(QCloseEvent *e); + +private: + enum ShortcutCommands { + Quit, + Abort, + Abort_Selection, + Delete_Node, + Tool_Select, + Tool_Move, + Tag, + Help, + New, + Open, + Save_Same, + Save_As + }; + + Ui::MainWindow *ui; + QSettings m_settings; + + Project_sV *m_project; + QString m_projectPath; + + Canvas *m_wCanvas; + FrameMonitor *m_wInputMonitor; + FrameMonitor *m_wCurveMonitor; + QDockWidget *m_wInputMonitorDock; + QDockWidget *m_wCurveMonitorDock; + RenderPreview* m_wRenderPreview; + QDockWidget *m_wRenderPreviewDock; + QList<QAction*> m_widgetActions; + + ProgressDialog *m_progressDialog; + ProgressDialog *m_renderProgressDialog; + FlowExaminer *m_flowExaminer; + + + CombinedShortcuts m_cs; + + QThread m_rendererThread; + + void createDockWindows(); + void createActions(); + + void loadProject(QString path); + void loadProject(Project_sV *project); + void resetDialogs(); + void updateWindowTitle(); + bool okToContinue(); + + private slots: + void slotShortcutUsed(int id); + void slotShowRenderDialog(); + void slotShowPreferencesDialog(); + void slotShowProjectPreferencesDialog(); + void slotShowFlowExaminerDialog(); + void slotShowDebugWindow(bool set); + void slotForwardInputPosition(qreal frame); + void slotForwardCurveSrcPosition(qreal frame); + + void slotNewFrameSourceTask(const QString taskDescription, int taskSize); + void slotFrameSourceTasksFinished(); + void slotCloseFrameSourceProgress(); + + void slotRenderingAborted(QString message); + + void slotNewProject(); + void slotSaveProject(QString filename = ""); + void slotSaveProjectDialog(); + void slotLoadProjectDialog(); + + void slotToggleHelp(); + void slotShowAboutDialog(); + void slotUpdateRenderPreview(); + + void slotShowFlowEditWindow(); + +signals: + void deleteNodes(); + void setMode(const Canvas::ToolMode mode); + void abort(const Canvas::Abort abort); + void addTag(); + void signalRendererContinue(); + +}; + +#endif // MAINWINDOW_H
View file
slowmoVideo-0.6.tar.xz/src/slowmoUI/mainwindow.ui
Added
@@ -0,0 +1,189 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>MainWindow</class> + <widget class="QMainWindow" name="MainWindow"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>1000</width> + <height>700</height> + </rect> + </property> + <property name="windowTitle"> + <string>slowmoVideo UI</string> + </property> + <widget class="QWidget" name="centralWidget"/> + <widget class="QMenuBar" name="menuBar"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>1000</width> + <height>25</height> + </rect> + </property> + <widget class="QMenu" name="menuSlowmoVideo_UI"> + <property name="title"> + <string>&File</string> + </property> + <addaction name="actionNew"/> + <addaction name="actionOpen"/> + <addaction name="actionSave"/> + <addaction name="actionSave_as"/> + <addaction name="separator"/> + <addaction name="actionRender"/> + <addaction name="actionRenderPreview"/> + <addaction name="actionExamineFlow"/> + <addaction name="separator"/> + <addaction name="actionPreferences"/> + <addaction name="separator"/> + <addaction name="actionQuit"/> + <addaction name="separator"/> + </widget> + <widget class="QMenu" name="menuHelp"> + <property name="title"> + <string>&Help</string> + </property> + <addaction name="actionAbout"/> + <addaction name="actionShortcuts"/> + </widget> + <widget class="QMenu" name="menuView"> + <property name="title"> + <string>&View</string> + </property> + <addaction name="actionZoomIn"/> + <addaction name="actionZoomOut"/> + <addaction name="separator"/> + <addaction name="actionEdit_Flow"/> + <addaction name="actionDebug_Window"/> + </widget> + <widget class="QMenu" name="menuProject"> + <property name="title"> + <string>&Project</string> + </property> + <addaction name="actionProjectPreferences"/> + </widget> + <addaction name="menuSlowmoVideo_UI"/> + <addaction name="menuProject"/> + <addaction name="menuView"/> + <addaction name="menuHelp"/> + </widget> + <widget class="QToolBar" name="mainToolBar"> + <attribute name="toolBarArea"> + <enum>TopToolBarArea</enum> + </attribute> + <attribute name="toolBarBreak"> + <bool>false</bool> + </attribute> + </widget> + <widget class="QStatusBar" name="statusBar"/> + <action name="actionRender"> + <property name="text"> + <string>&Render</string> + </property> + </action> + <action name="actionPreferences"> + <property name="text"> + <string>Preferences</string> + </property> + <property name="menuRole"> + <enum>QAction::PreferencesRole</enum> + </property> + </action> + <action name="actionSave"> + <property name="text"> + <string>&Save</string> + </property> + </action> + <action name="actionSave_as"> + <property name="text"> + <string>Save &as …</string> + </property> + </action> + <action name="actionOpen"> + <property name="text"> + <string>&Open</string> + </property> + </action> + <action name="actionShortcuts"> + <property name="text"> + <string>&Shortcuts</string> + </property> + </action> + <action name="actionAbout"> + <property name="text"> + <string>&About</string> + </property> + <property name="menuRole"> + <enum>QAction::AboutRole</enum> + </property> + </action> + <action name="actionQuit"> + <property name="text"> + <string>&Quit</string> + </property> + <property name="menuRole"> + <enum>QAction::QuitRole</enum> + </property> + </action> + <action name="actionRenderPreview"> + <property name="text"> + <string>Render &preview</string> + </property> + </action> + <action name="actionExamineFlow"> + <property name="text"> + <string>E&xamine flow</string> + </property> + <property name="toolTip"> + <string>Examine flow at input frame</string> + </property> + </action> + <action name="actionNew"> + <property name="text"> + <string>&New …</string> + </property> + </action> + <action name="actionProjectPreferences"> + <property name="text"> + <string>&Preferences</string> + </property> + <property name="menuRole"> + <enum>QAction::TextHeuristicRole</enum> + </property> + </action> + <action name="actionZoomIn"> + <property name="text"> + <string>Zoom &in</string> + </property> + </action> + <action name="actionZoomOut"> + <property name="text"> + <string>Zoom &out</string> + </property> + </action> + <action name="actionEdit_Flow"> + <property name="checkable"> + <bool>true</bool> + </property> + <property name="text"> + <string>Edit Optical Flow</string> + </property> + <property name="toolTip"> + <string>Edit Optical Flow</string> + </property> + </action> + <action name="actionDebug_Window"> + <property name="checkable"> + <bool>true</bool> + </property> + <property name="text"> + <string>Debug Window</string> + </property> + </action> + </widget> + <layoutdefault spacing="6" margin="11"/> + <resources/> + <connections/> +</ui>
View file
slowmoVideo-0.6.tar.xz/src/slowmoUI/notificator.cpp
Added
@@ -0,0 +1,317 @@ +#include "notificator.h" + +#include <QMetaType> +#include <QVariant> +#include <QIcon> +#include <QApplication> +#include <QStyle> +#include <QByteArray> +#include <QSystemTrayIcon> +#include <QMessageBox> +#include <QTemporaryFile> +#include <QImageWriter> + +#ifdef USE_DBUS +#include <QtDBus> +#include <stdint.h> +#endif + +#ifdef Q_OS_MAC +#include <ApplicationServices/ApplicationServices.h> +#include "macnotificationhandler.h" +#endif + +// https://wiki.ubuntu.com/NotificationDevelopmentGuidelines recommends at least 128 +const int FREEDESKTOP_NOTIFICATION_ICON_SIZE = 128; + +Notificator::Notificator(const QString &programName, QSystemTrayIcon *trayicon, QWidget *parent): + QObject(parent), + parent(parent), + programName(programName), + mode(None), + trayIcon(trayicon) +#ifdef USE_DBUS + ,interface(0) +#endif +{ + if(trayicon && trayicon->supportsMessages()) + { + mode = QSystemTray; + } +#ifdef USE_DBUS + interface = new QDBusInterface("org.freedesktop.Notifications", + "/org/freedesktop/Notifications", "org.freedesktop.Notifications"); + if(interface->isValid()) + { + mode = Freedesktop; + } +#endif +#ifdef Q_OS_MAC + // check if users OS has support for NSUserNotification + if( MacNotificationHandler::instance()->hasUserNotificationCenterSupport()) { + mode = UserNotificationCenter; + } + else { + // Check if Growl is installed (based on Qt's tray icon implementation) + CFURLRef cfurl; + OSStatus status = LSGetApplicationForInfo(kLSUnknownType, kLSUnknownCreator, CFSTR("growlTicket"), kLSRolesAll, 0, &cfurl); + if (status != kLSApplicationNotFoundErr) { + CFBundleRef bundle = CFBundleCreate(0, cfurl); + if (CFStringCompare(CFBundleGetIdentifier(bundle), CFSTR("com.Growl.GrowlHelperApp"), kCFCompareCaseInsensitive | kCFCompareBackwards) == kCFCompareEqualTo) { + if (CFStringHasSuffix(CFURLGetString(cfurl), CFSTR("/Growl.app/"))) + mode = Growl13; + else + mode = Growl12; + } + CFRelease(cfurl); + CFRelease(bundle); + } + } +#endif +} + +Notificator::~Notificator() +{ +#ifdef USE_DBUS + delete interface; +#endif +} + +#ifdef USE_DBUS + +// Loosely based on http://www.qtcentre.org/archive/index.php/t-25879.html +class FreedesktopImage +{ +public: + FreedesktopImage() {} + FreedesktopImage(const QImage &img); + + static int metaType(); + + // Image to variant that can be marshalled over DBus + static QVariant toVariant(const QImage &img); + +private: + int width, height, stride; + bool hasAlpha; + int channels; + int bitsPerSample; + QByteArray image; + + friend QDBusArgument &operator<<(QDBusArgument &a, const FreedesktopImage &i); + friend const QDBusArgument &operator>>(const QDBusArgument &a, FreedesktopImage &i); +}; + +Q_DECLARE_METATYPE(FreedesktopImage); + +// Image configuration settings +const int CHANNELS = 4; +const int BYTES_PER_PIXEL = 4; +const int BITS_PER_SAMPLE = 8; + +FreedesktopImage::FreedesktopImage(const QImage &img): + width(img.width()), + height(img.height()), + stride(img.width() * BYTES_PER_PIXEL), + hasAlpha(true), + channels(CHANNELS), + bitsPerSample(BITS_PER_SAMPLE) +{ + // Convert 00xAARRGGBB to RGBA bytewise (endian-independent) format + QImage tmp = img.convertToFormat(QImage::Format_ARGB32); + const uint32_t *data = reinterpret_cast<const uint32_t*>(tmp.bits()); + + unsigned int num_pixels = width * height; + image.resize(num_pixels * BYTES_PER_PIXEL); + + for(unsigned int ptr = 0; ptr < num_pixels; ++ptr) + { + imageptr*BYTES_PER_PIXEL+0 = dataptr >> 16; // R + imageptr*BYTES_PER_PIXEL+1 = dataptr >> 8; // G + imageptr*BYTES_PER_PIXEL+2 = dataptr; // B + imageptr*BYTES_PER_PIXEL+3 = dataptr >> 24; // A + } +} + +QDBusArgument &operator<<(QDBusArgument &a, const FreedesktopImage &i) +{ + a.beginStructure(); + a << i.width << i.height << i.stride << i.hasAlpha << i.bitsPerSample << i.channels << i.image; + a.endStructure(); + return a; +} + +const QDBusArgument &operator>>(const QDBusArgument &a, FreedesktopImage &i) +{ + a.beginStructure(); + a >> i.width >> i.height >> i.stride >> i.hasAlpha >> i.bitsPerSample >> i.channels >> i.image; + a.endStructure(); + return a; +} + +int FreedesktopImage::metaType() +{ + return qDBusRegisterMetaType<FreedesktopImage>(); +} + +QVariant FreedesktopImage::toVariant(const QImage &img) +{ + FreedesktopImage fimg(img); + return QVariant(FreedesktopImage::metaType(), &fimg); +} + +void Notificator::notifyDBus(Class cls, const QString &title, const QString &text, const QIcon &icon, int millisTimeout) +{ + Q_UNUSED(cls); + // Arguments for DBus call: + QList<QVariant> args; + + // Program Name: + args.append(programName); + + // Unique ID of this notification type: + args.append(0U); + + // Application Icon, empty string + args.append(QString()); + + // Summary + args.append(title); + + // Body + args.append(text); + + // Actions (none, actions are deprecated) + QStringList actions; + args.append(actions); + + // Hints + QVariantMap hints; + + // If no icon specified, set icon based on class + QIcon tmpicon; + if(icon.isNull()) + { + QStyle::StandardPixmap sicon = QStyle::SP_MessageBoxQuestion; + switch(cls) + { + case Information: sicon = QStyle::SP_MessageBoxInformation; break; + case Warning: sicon = QStyle::SP_MessageBoxWarning; break; + case Critical: sicon = QStyle::SP_MessageBoxCritical; break; + default: break; + } + tmpicon = QApplication::style()->standardIcon(sicon); + } + else + { + tmpicon = icon; + } + hints"icon_data" = FreedesktopImage::toVariant(tmpicon.pixmap(FREEDESKTOP_NOTIFICATION_ICON_SIZE).toImage()); + args.append(hints); + + // Timeout (in msec) + args.append(millisTimeout); + + // "Fire and forget" + interface->callWithArgumentList(QDBus::NoBlock, "Notify", args); +} +#endif + +void Notificator::notifySystray(Class cls, const QString &title, const QString &text, const QIcon &icon, int millisTimeout) +{ + Q_UNUSED(icon); + QSystemTrayIcon::MessageIcon sicon = QSystemTrayIcon::NoIcon; + switch(cls) // Set icon based on class + { + case Information: sicon = QSystemTrayIcon::Information; break; + case Warning: sicon = QSystemTrayIcon::Warning; break; + case Critical: sicon = QSystemTrayIcon::Critical; break; + } + trayIcon->showMessage(title, text, sicon, millisTimeout); +} + +// Based on Qt's tray icon implementation +#ifdef Q_OS_MAC +void Notificator::notifyGrowl(Class cls, const QString &title, const QString &text, const QIcon &icon) +{ + const QString script( + "tell application \"%5\"\n" + " set the allNotificationsList to {\"Notification\"}\n" // -- Make a list of all the notification types (all) + " set the enabledNotificationsList to {\"Notification\"}\n" // -- Make a list of the notifications (enabled) + " register as application \"%1\" all notifications allNotificationsList default notifications enabledNotificationsList\n" // -- Register our script with Growl + " notify with name \"Notification\" title \"%2\" description \"%3\" application name \"%1\"%4\n" // -- Send a Notification + "end tell" + ); + + QString notificationApp(QApplication::applicationName()); + if (notificationApp.isEmpty()) + notificationApp = "Application"; + + QPixmap notificationIconPixmap; + if (icon.isNull()) { // If no icon specified, set icon based on class + QStyle::StandardPixmap sicon = QStyle::SP_MessageBoxQuestion; + switch (cls) + { + case Information: sicon = QStyle::SP_MessageBoxInformation; break; + case Warning: sicon = QStyle::SP_MessageBoxWarning; break; + case Critical: sicon = QStyle::SP_MessageBoxCritical; break; + } + notificationIconPixmap = QApplication::style()->standardPixmap(sicon); + } + else { + QSize size = icon.actualSize(QSize(48, 48)); + notificationIconPixmap = icon.pixmap(size); + } + + QString notificationIcon; + QTemporaryFile notificationIconFile; + if (!notificationIconPixmap.isNull() && notificationIconFile.open()) { + QImageWriter writer(¬ificationIconFile, "PNG"); + if (writer.write(notificationIconPixmap.toImage())) + notificationIcon = QString(" image from location \"file://%1\"").arg(notificationIconFile.fileName()); + } + + QString quotedTitle(title), quotedText(text); + quotedTitle.replace("\\", "\\\\").replace("\"", "\\"); + quotedText.replace("\\", "\\\\").replace("\"", "\\"); + QString growlApp(this->mode == Notificator::Growl13 ? "Growl" : "GrowlHelperApp"); + MacNotificationHandler::instance()->sendAppleScript(script.arg(notificationApp, quotedTitle, quotedText, notificationIcon, growlApp)); +} + +void Notificator::notifyMacUserNotificationCenter(Class cls, const QString &title, const QString &text, const QIcon &icon) { + // icon is not supported by the user notification center yet. OSX will use the app icon. + MacNotificationHandler::instance()->showNotification(title, text); +} + +#endif + +void Notificator::notify(Class cls, const QString &title, const QString &text, const QIcon &icon, int millisTimeout) +{ + switch(mode) + { +#ifdef USE_DBUS + case Freedesktop: + notifyDBus(cls, title, text, icon, millisTimeout); + break; +#endif + case QSystemTray: + notifySystray(cls, title, text, icon, millisTimeout); + break; +#ifdef Q_OS_MAC + case UserNotificationCenter: + notifyMacUserNotificationCenter(cls, title, text, icon); + break; + case Growl12: + case Growl13: + notifyGrowl(cls, title, text, icon); + break; +#endif + default: + if(cls == Critical) + { + // Fall back to old fashioned pop-up dialog if critical and no other notification available + QMessageBox::critical(parent, title, text, QMessageBox::Ok, QMessageBox::Ok); + } + break; + } +}
View file
slowmoVideo-0.6.tar.xz/src/slowmoUI/notificator.h
Added
@@ -0,0 +1,71 @@ +#ifndef NOTIFICATOR_H +#define NOTIFICATOR_H + +#include <QObject> +#include <QIcon> + +QT_BEGIN_NAMESPACE +class QSystemTrayIcon; +#ifdef USE_DBUS +class QDBusInterface; +#endif +QT_END_NAMESPACE + +/** Cross-platform desktop notification client. */ +class Notificator: public QObject +{ + Q_OBJECT + +public: + /** Create a new notificator. + @note Ownership of trayIcon is not transferred to this object. + */ + Notificator(const QString &programName=QString(), QSystemTrayIcon *trayIcon=0, QWidget *parent=0); + ~Notificator(); + + // Message class + enum Class + { + Information, /**< Informational message */ + Warning, /**< Notify user of potential problem */ + Critical /**< An error occurred */ + }; + +public slots: + /** Show notification message. + @paramin cls general message class + @paramin title title shown with message + @paramin text message content + @paramin icon optional icon to show with message + @paramin millisTimeout notification timeout in milliseconds (defaults to 10 seconds) + @note Platform implementations are free to ignore any of the provided fields except for \a text. + */ + void notify(Class cls, const QString &title, const QString &text, + const QIcon &icon = QIcon(), int millisTimeout = 10000); + +private: + QWidget *parent; + enum Mode { + None, /**< Ignore informational notifications, and show a modal pop-up dialog for Critical notifications. */ + Freedesktop, /**< Use DBus org.freedesktop.Notifications */ + QSystemTray, /**< Use QSystemTray::showMessage */ + Growl12, /**< Use the Growl 1.2 notification system (Mac only) */ + Growl13, /**< Use the Growl 1.3 notification system (Mac only) */ + UserNotificationCenter /**< Use the 10.8+ User Notification Center (Mac only) */ + }; + QString programName; + Mode mode; + QSystemTrayIcon *trayIcon; +#ifdef USE_DBUS + QDBusInterface *interface; + + void notifyDBus(Class cls, const QString &title, const QString &text, const QIcon &icon, int millisTimeout); +#endif + void notifySystray(Class cls, const QString &title, const QString &text, const QIcon &icon, int millisTimeout); +#ifdef Q_OS_MAC + void notifyGrowl(Class cls, const QString &title, const QString &text, const QIcon &icon); + void notifyMacUserNotificationCenter(Class cls, const QString &title, const QString &text, const QIcon &icon); +#endif +}; + +#endif // NOTIFICATOR_H
View file
slowmoVideo-0.6.tar.xz/src/slowmoUI/renderPreview.cpp
Added
@@ -0,0 +1,97 @@ +/* +slowmoUI is a user interface for slowmoVideo. +Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +*/ + +#include "renderPreview.h" +#include "ui_renderPreview.h" +#include "project/emptyFrameSource_sV.h" +#include "project/project_sV.h" +#include "project/projectPreferences_sV.h" + +#include <QtGui/QPainter> +#include <QMainWindow> +#include <QStatusBar> +#include <QtConcurrent> + +RenderPreview::RenderPreview(Project_sV *project, QWidget *parent) : + QWidget(parent), + ui(new Ui::RenderPreview), + m_project(project) +{ + ui->setupUi(this); + + m_parentMainWindow = dynamic_cast<QMainWindow*>(parentWidget()); + + ui->info->setVisible(m_parentMainWindow == NULL); + ui->info->clear(); + + connect(&m_futureWatcher, SIGNAL(finished()), this, SLOT(slotUpdateImage())); +} + +RenderPreview::~RenderPreview() +{ + delete ui; +} + +void RenderPreview::load(Project_sV *project) +{ + m_project = project; +} + +void RenderPreview::notify(const QString message) +{ + if (m_parentMainWindow != NULL) { + m_parentMainWindow->statusBar()->showMessage(message, 5000); + } else { + ui->info->setText(message); + } +} + +void RenderPreview::slotRenderAt(qreal time) +{ + if (dynamic_cast<EmptyFrameSource_sV*>(m_project->frameSource()) != NULL) { + notify(tr("Cannot render preview, no frames loaded.")); + return; + } + if (m_project->nodes()->size() < 2) { + notify(tr("Cannot render preview at the curve position since no curve is available.")); + return; + } + if (time >= m_project->nodes()->startTime() && time <= m_project->nodes()->endTime()) { + notify(tr("Rendering preview at output time %1 s (might take some time) ...").arg(time)); + + if (m_future.isRunning()) { + notify(tr("Preview is still being rendered.")); + } else { + + RenderPreferences_sV prefs; + prefs.fps() = m_project->preferences()->renderFPS(); + prefs.interpolation = m_project->preferences()->renderInterpolationType(); + prefs.size = FrameSize_Orig; + + m_future = QtConcurrent::run(m_project, &Project_sV::render, time, prefs); + m_futureWatcher.setFuture(m_future); + if (m_future.isFinished()) { + qDebug() << "qFuture has already finished! Manually calling update."; + slotUpdateImage(); + } + } + } else { + notify(tr("Cannot render at output time %1 s; Not within the curve.").arg(time)); + } +} + +void RenderPreview::slotUpdateImage() +{ + qDebug() << "Updating preview image now. Saving as /tmp/renderPreview.jpg."; ///< \todo do not save anymore + ui->imageDisplay->loadImage(m_future.result()); + ui->imageDisplay->image().save(QDir::tempPath () + "/renderPreview.jpg"); + repaint(); + notify(tr("Preview rendering finished.")); +}
View file
slowmoVideo-0.6.tar.xz/src/slowmoUI/renderPreview.h
Changed
(renamed from src/slowmoVideo/slowmoUI/renderPreview.h)
View file
slowmoVideo-0.6.tar.xz/src/slowmoUI/renderPreview.ui
Changed
(renamed from src/slowmoVideo/slowmoUI/renderPreview.ui)
View file
slowmoVideo-0.6.tar.xz/src/slowmoUI/res
Added
+(directory)
View file
slowmoVideo-0.6.tar.xz/src/slowmoUI/res/AppIcon.png
Changed
(renamed from src/slowmoVideo/slowmoUI/res/AppIcon.png)
View file
slowmoVideo-0.6.tar.xz/src/slowmoUI/res/Colours.svg
Changed
(renamed from src/slowmoVideo/slowmoUI/res/Colours.svg)
View file
slowmoVideo-0.6.tar.xz/src/slowmoUI/res/Icons.svg
Changed
(renamed from src/slowmoVideo/slowmoUI/res/Icons.svg)
View file
slowmoVideo-0.6.tar.xz/src/slowmoUI/res/Info.plist.in
Changed
(renamed from src/slowmoVideo/slowmoUI/res/Info.plist.cmake)
View file
slowmoVideo-0.6.tar.xz/src/slowmoUI/res/iconAdd.png
Changed
(renamed from src/slowmoVideo/slowmoUI/res/iconAdd.png)
View file
slowmoVideo-0.6.tar.xz/src/slowmoUI/res/iconMov.png
Changed
(renamed from src/slowmoVideo/slowmoUI/res/iconMov.png)
View file
slowmoVideo-0.6.tar.xz/src/slowmoUI/res/iconSel.png
Changed
(renamed from src/slowmoVideo/slowmoUI/res/iconSel.png)
View file
slowmoVideo-0.6.tar.xz/src/slowmoUI/res/shutterFunction.png
Changed
(renamed from src/slowmoVideo/slowmoUI/res/shutterFunction.png)
View file
slowmoVideo-0.6.tar.xz/src/slowmoUI/res/slowmoUI.icns
Changed
(renamed from src/slowmoVideo/slowmoUI/res/slowmoUI.icns)
View file
slowmoVideo-0.6.tar.xz/src/slowmoUI/resources.qrc
Changed
(renamed from src/slowmoVideo/slowmoUI/resources.qrc)
View file
slowmoVideo-0.6.tar.xz/src/test
Added
+(directory)
View file
slowmoVideo-0.6.tar.xz/src/test/CMakeLists.txt
Added
@@ -0,0 +1,19 @@ +set(SRCS + test.cpp +) + +include_directories(${FFMPEG_INCLUDE_PATHS}) +add_executable(Test ${SRCS}) +target_link_libraries(Test sVproj ${EXTERNAL_LIBS}) + +#add_executable(encodeTest encodeTest.c) +#target_link_libraries(encodeTest sVencode ${EXTERNAL_LIBS}) + +#add_executable(encodeFramesTest ffmpegTestEncodeFrames.cpp) +#message(STATUS "Additional libraries: ${ADDITIONAL_LIBS}") +#target_link_libraries(encodeFramesTest sVencode ${EXTERNAL_LIBS}) + +add_executable(AvconvInfo testAvconvInfo.cpp) +target_link_libraries(AvconvInfo sVinfo ${EXTERNAL_LIBS}) + +install(TARGETS Test DESTINATION bin)
View file
slowmoVideo-0.6.tar.xz/src/test/Makefile
Changed
(renamed from src/slowmoVideo/test/Makefile)
View file
slowmoVideo-0.6.tar.xz/src/test/encodeTest.c
Added
@@ -0,0 +1,14 @@ + +#include "../lib/ffmpegEncode_sV.h" + +int main() +{ + int i; + + VideoOut_sV video; + prepareDefault(&video); + for (i = 0; i < 50; i++) { + eatSample(&video); + } + finish(&video); +}
View file
slowmoVideo-0.6.tar.xz/src/test/ffmpegTest.c
Changed
(renamed from src/slowmoVideo/test/ffmpegTest.c)
View file
slowmoVideo-0.6.tar.xz/src/test/ffmpegTestEncodeFrames.cpp
Changed
(renamed from src/slowmoVideo/test/ffmpegTestEncodeFrames.cpp)
View file
slowmoVideo-0.6.tar.xz/src/test/test.cpp
Changed
(renamed from src/slowmoVideo/test/test.cpp)
View file
slowmoVideo-0.6.tar.xz/src/test/testAvconvInfo.cpp
Changed
(renamed from src/slowmoVideo/test/testAvconvInfo.cpp)
View file
slowmoVideo-0.6.tar.xz/src/tr
Added
+(directory)
View file
slowmoVideo-0.6.tar.xz/src/tr/slowmoVideo_de.qm
Changed
(renamed from src/slowmoVideo/tr/slowmoVideo_de.qm)
View file
slowmoVideo-0.6.tar.xz/src/tr/slowmoVideo_de.ts
Changed
(renamed from src/slowmoVideo/tr/slowmoVideo_de.ts)
View file
slowmoVideo-0.6.tar.xz/src/tr/slowmoVideo_fr.qm
Changed
(renamed from src/slowmoVideo/tr/slowmoVideo_fr.qm)
View file
slowmoVideo-0.6.tar.xz/src/tr/slowmoVideo_fr.ts
Added
@@ -0,0 +1,1441 @@ +<?xml version="1.0" encoding="utf-8"?> +<!DOCTYPE TS> +<TS version="2.0" language="fr_FR"> +<context> + <name>AboutDialog</name> + <message> + <location filename="../slowmoUI/dialogues/aboutDialog.ui" line="14"/> + <source>About</source> + <translation>A propos</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/aboutDialog.ui" line="28"/> + <source>About slowmoVideo</source> + <translation>A propos de slowmoVideo</translation> + </message> + <message utf8="true"> + <location filename="../slowmoUI/dialogues/aboutDialog.ui" line="41"/> + <source><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Bitstream Vera Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-style:italic;">slowmoVideo</span> is developed by Simon A. Eugster (aka. Granjow, co-author of Kdenlive) and licensed under GPLv3.</p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-style:italic;">slowmoVideo</span> allows to change the speed of a video clip based upon a curve. If the speed becomes higher than 1×, an exposure (shutter) effect simulates motion blur. For lower speed, frames are interpolated with optical flow.</p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Thanks for contributing:</p> +<ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Mirko Götze <span style=" font-style:italic;">&lt;mail@mgo80.de&gt;</span> for converting <span style=" font-weight:600;">Cg to GLSL</span> (Removing the nVidia dependency)</li> +<li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Morten Sylvest Olsen <span style=" font-style:italic;">&lt;mso@kapowsoftware.com&gt;</span> for the <span style=" font-weight:600;">V3D speedup</span> and removing the unnecessary window</li> +<li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Elias Vanderstuyft for displaying the <span style=" font-weight:600;">shutter function</span> on the canvas</li> +<li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Christian Frisson <span style=" font-style:italic;">&lt;christian.frisson@umons.ac.be&gt;</span> for<span style=" font-weight:600;"> OpenCV on MXE</span> (allowed me to compile slowmoVideo for Windows)</li> +<li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Per <span style=" font-style:italic;">&lt;per@stuffmatic.com&gt;</span> for the<span style=" font-weight:600;"> OpenCV</span> code (slowmoVideo can run on CPU only with it)</li></ul> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Visit <a href="http://slowmoVideo.granjow.net"><span style=" text-decoration: underline; color:#0057ae;">slowmoVideo.granjow.net</span></a> for more information.</p></body></html></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/aboutDialog.ui" line="133"/> + <source>(c) 2012 Simon A. Eugster</source> + <translation>(c) 2012 Simon A. Eugster</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/aboutDialog.cpp" line="23"/> + <source>Version %1, %2</source> + <translation>Version %1, %2</translation> + </message> +</context> +<context> + <name>Canvas</name> + <message> + <location filename="../slowmoUI/canvas.ui" line="78"/> + <source>slowmoUI canvas</source> + <translation>Canevas slowmoUI</translation> + </message> + <message> + <location filename="../slowmoUI/canvas.cpp" line="105"/> + <source>&Delete node</source> + <translation>Effacer le &noeud</translation> + </message> + <message> + <location filename="../slowmoUI/canvas.cpp" line="106"/> + <source>&Snap in node</source> + <translation>&Aimanter aux noeuds</translation> + </message> + <message> + <location filename="../slowmoUI/canvas.cpp" line="107"/> + <source>&Delete tag</source> + <translation>Effacer le &tag</translation> + </message> + <message> + <location filename="../slowmoUI/canvas.cpp" line="108"/> + <source>&Rename tag</source> + <translation>&Renomer le tag</translation> + </message> + <message> + <location filename="../slowmoUI/canvas.cpp" line="109"/> + <source>Set tag &time</source> + <translation>&Horodater le tag</translation> + </message> + <message> + <location filename="../slowmoUI/canvas.cpp" line="118"/> + <source>&Linear curve</source> + <translation>Courbe &Lineaire</translation> + </message> + <message utf8="true"> + <location filename="../slowmoUI/canvas.cpp" line="119"/> + <source>&Bézier curve</source> + <translation>Courbe de &Bézier</translation> + </message> + <message> + <location filename="../slowmoUI/canvas.cpp" line="123"/> + <source>Set &custom speed</source> + <translation>Fixer une &vitesse personnalisé</translation> + </message> + <message> + <location filename="../slowmoUI/canvas.cpp" line="124"/> + <source>Set/edit shutter &function</source> + <translation>Fixer/Éditer la fonction de l'&obturateur</translation> + </message> + <message utf8="true"> + <location filename="../slowmoUI/canvas.cpp" line="130"/> + <source>Set speed to %1×</source> + <translation>Fixer la vitesse à %1x</translation> + </message> + <message> + <location filename="../slowmoUI/canvas.cpp" line="135"/> + <source>Reset left handle</source> + <translation>Réinitialiser la poignée gauche</translation> + </message> + <message> + <location filename="../slowmoUI/canvas.cpp" line="136"/> + <source>Reset right handle</source> + <translation>Réinitialiser la poignée droite</translation> + </message> + <message utf8="true"> + <location filename="../slowmoUI/canvas.cpp" line="789"/> + <source>Segment replay &speed …</source> + <translation>&Vitesse de relecture du segment ...</translation> + </message> + <message> + <location filename="../slowmoUI/canvas.cpp" line="800"/> + <source>Node %1</source> + <translation>Noeud %1</translation> + </message> + <message> + <location filename="../slowmoUI/canvas.cpp" line="803"/> + <source>Handle actions</source> + <translation>Actions des poignées</translation> + </message> + <message> + <location filename="../slowmoUI/canvas.cpp" line="811"/> + <source>Segment between node %1 and %2</source> + <translation>Segment entre les noeuds %1 et %2</translation> + </message> + <message> + <location filename="../slowmoUI/canvas.cpp" line="830"/> + <source>Tag %1</source> + <translation>Tag %1</translation> + </message> + <message> + <location filename="../slowmoUI/canvas.cpp" line="1078"/> + <source>New tag name</source> + <translation>Nouveau nom du tag</translation> + </message> + <message> + <location filename="../slowmoUI/canvas.cpp" line="1078"/> + <source>Tag:</source> + <translation>Tag:</translation> + </message> + <message> + <location filename="../slowmoUI/canvas.cpp" line="1087"/> + <source>New tag time</source> + <translation>Nouveau temps du tag</translation> + </message> + <message> + <location filename="../slowmoUI/canvas.cpp" line="1087"/> + <source>Time:</source> + <translatorcomment>Temps</translatorcomment> + <translation></translation> + </message> + <message> + <location filename="../slowmoUI/canvas.cpp" line="1153"/> + <source>Replay speed for current segment</source> + <translation>Vitesse de relecture pour le segment courrant</translation> + </message> + <message> + <location filename="../slowmoUI/canvas.cpp" line="1153"/> + <source>Speed:</source> + <translation>Vitesse:</translation> + </message> +</context> +<context> + <name>FlowEditCanvas</name> + <message> + <location filename="../slowmoFlowEdit/flowEditCanvas.ui" line="77"/> + <source>Values at mouse position</source> + <translation>Valeurs à la position de la sourie</translation> + </message> +</context> +<context> + <name>FlowExaminer</name> + <message> + <location filename="../slowmoUI/dialogues/flowExaminer.ui" line="95"/> + <source>Close</source> + <translation>Fermer</translation> + </message> +</context> +<context> + <name>FrameMonitor</name> + <message> + <location filename="../slowmoUI/frameMonitor.ui" line="20"/> + <source>Input monitor</source> + <translation>Moniteur d'entrée</translation> + </message> +</context> +<context> + <name>ImageDisplay</name> + <message> + <location filename="../libgui/imageDisplay.cpp" line="28"/> + <source>Scale image to widget size</source> + <translation>Ajuster l'image à la taille du widget</translation> + </message> + <message> + <location filename="../libgui/imageDisplay.cpp" line="32"/> + <source>Export image</source> + <translation>Exporter l'image</translation> + </message> + <message> + <location filename="../libgui/imageDisplay.cpp" line="241"/> + <source>Export render preview to image</source> + <translation>Exporter une image de la prévisualisation</translation> + </message> +</context> +<context> + <name>ImagesFrameSource_sV</name> + <message> + <location filename="../project/imagesFrameSource_sV.cpp" line="53"/> + <source>No images selected.</source> + <translation>Pas d'image selectionnée.</translation> + </message> + <message> + <location filename="../project/imagesFrameSource_sV.cpp" line="58"/> + <source>Image %1 is not of the same size (%2) as the first image (%3).</source> + <translation>L'image %1 n'as pas la même taille (%2) que la première image (%3).</translation> + </message> + <message> + <location filename="../project/imagesFrameSource_sV.cpp" line="94"/> + <source>Creating preview images from the input images</source> + <translation>Création des images de previsualisation à partir des images d'entrée</translation> + </message> + <message> + <location filename="../project/imagesFrameSource_sV.cpp" line="99"/> + <source>Resized image already exists for %1</source> + <translation>Une image de cette taille existe déjà pour %1</translation> + </message> + <message> + <location filename="../project/imagesFrameSource_sV.cpp" line="101"/> + <source>Re-sizing image %1 to: +%2</source> + <translation>Changement de la taille de l'image %1 vers : %2</translation> + </message> +</context> +<context> + <name>MainWindow</name> + <message> + <location filename="../slowmoFlowEdit/mainwindow.ui" line="14"/> + <source>slowmo Flow Editor</source> + <translation>slowmo Éditeur de flux</translation> + </message> + <message> + <location filename="../slowmoFlowEdit/mainwindow.ui" line="28"/> + <source>File</source> + <translation>Fichier</translation> + </message> + <message> + <location filename="../slowmoFlowEdit/mainwindow.ui" line="40"/> + <source>Help</source> + <translation>Aide</translation> + </message> + <message> + <location filename="../slowmoFlowEdit/mainwindow.ui" line="50"/> + <source>Open</source> + <translation>Ouvrir</translation> + </message> + <message> + <location filename="../slowmoFlowEdit/mainwindow.ui" line="55"/> + <location filename="../slowmoUI/mainwindow.cpp" line="131"/> + <source>Save</source> + <translation>Enregistrer</translation> + </message> + <message> + <location filename="../slowmoFlowEdit/mainwindow.ui" line="60"/> + <location filename="../slowmoUI/mainwindow.cpp" line="128"/> + <source>Quit</source> + <translation>Quitter</translation> + </message> + <message> + <location filename="../slowmoFlowEdit/mainwindow.ui" line="65"/> + <source>Next file</source> + <translation>Fichier suivant</translation> + </message> + <message> + <location filename="../slowmoFlowEdit/mainwindow.ui" line="70"/> + <source>Previous file</source> + <translation>Fichier précedent</translation> + </message> + <message> + <location filename="../slowmoFlowEdit/mainwindow.ui" line="78"/> + <source>Amplify colours</source> + <translation>Amplifier les couleurs</translation> + </message> + <message> + <location filename="../slowmoFlowEdit/mainwindow.ui" line="83"/> + <source>Shortcuts</source> + <translation>Raccourcis</translation> + </message> + <message> + <location filename="../slowmoUI/mainwindow.ui" line="14"/> + <source>slowmoVideo UI</source> + <translation>slowmoVideo UI</translation> + </message> + <message> + <location filename="../slowmoUI/mainwindow.ui" line="28"/> + <source>&File</source> + <translation>&Fichier</translation> + </message> + <message> + <location filename="../slowmoUI/mainwindow.ui" line="46"/> + <source>&Help</source> + <translation>&Aide</translation> + </message> + <message> + <location filename="../slowmoUI/mainwindow.ui" line="53"/> + <source>&View</source> + <translation>&Affichage</translation> + </message> + <message> + <location filename="../slowmoUI/mainwindow.ui" line="60"/> + <source>&Project</source> + <translation>&Projet</translation> + </message> + <message> + <location filename="../slowmoUI/mainwindow.ui" line="80"/> + <source>&Render</source> + <translation>&Rendu</translation> + </message> + <message> + <location filename="../slowmoUI/mainwindow.ui" line="85"/> + <source>Preferences</source> + <translation>Préférences</translation> + </message> + <message> + <location filename="../slowmoUI/mainwindow.ui" line="90"/> + <source>&Save</source> + <translation>&Enregistrer</translation> + </message> + <message utf8="true"> + <location filename="../slowmoUI/mainwindow.ui" line="95"/> + <source>Save &as …</source> + <translation>Enregistrer &sous...</translation> + </message> + <message> + <location filename="../slowmoUI/mainwindow.ui" line="100"/> + <source>&Open</source> + <translation>&Ouvrir</translation> + </message> + <message> + <location filename="../slowmoUI/mainwindow.ui" line="105"/> + <source>&Shortcuts</source> + <translation>&Raccourcis</translation> + </message> + <message> + <location filename="../slowmoUI/mainwindow.ui" line="110"/> + <source>&About</source> + <translation>&À propos</translation> + </message> + <message> + <location filename="../slowmoUI/mainwindow.ui" line="115"/> + <source>&Quit</source> + <translation>&Quitter</translation> + </message> + <message> + <location filename="../slowmoUI/mainwindow.ui" line="120"/> + <source>Render &preview</source> + <translation>Générer une &prévisualisation</translation> + </message> + <message> + <location filename="../slowmoUI/mainwindow.ui" line="125"/> + <source>E&xamine flow</source> + <translation>E&xaminer le flux</translation> + </message> + <message> + <location filename="../slowmoUI/mainwindow.ui" line="128"/> + <source>Examine flow at input frame</source> + <translation>Examiner le flux à l'image d'entrée</translation> + </message> + <message utf8="true"> + <location filename="../slowmoUI/mainwindow.ui" line="133"/> + <source>&New …</source> + <translation>&Nouveau ...</translation> + </message> + <message> + <location filename="../slowmoUI/mainwindow.ui" line="138"/> + <source>&Preferences</source> + <translation>&Préférences</translation> + </message> + <message> + <location filename="../slowmoUI/mainwindow.ui" line="143"/> + <source>Zoom &in</source> + <translation>Zoom &avant</translation> + </message> + <message> + <location filename="../slowmoUI/mainwindow.ui" line="148"/> + <source>Zoom &out</source> + <translation>Zoom a&rrière</translation> + </message> + <message> + <location filename="../slowmoUI/mainwindow.cpp" line="66"/> + <source>Input monitor</source> + <translation>Moniteur d'entrée</translation> + </message> + <message> + <location filename="../slowmoUI/mainwindow.cpp" line="72"/> + <source>Curve monitor</source> + <translation>Moniteur de courbe</translation> + </message> + <message> + <location filename="../slowmoUI/mainwindow.cpp" line="78"/> + <source>Render preview</source> + <translation>Générer une prévisualisation</translation> + </message> + <message> + <location filename="../slowmoUI/mainwindow.cpp" line="127"/> + <source>Show help overlay</source> + <translation>Afficher l'aide</translation> + </message> + <message> + <location filename="../slowmoUI/mainwindow.cpp" line="129"/> + <source>New project</source> + <translation>Nouveau projet</translation> + </message> + <message> + <location filename="../slowmoUI/mainwindow.cpp" line="130"/> + <source>Open project</source> + <translation>Ouvrir un projet</translation> + </message> + <message> + <location filename="../slowmoUI/mainwindow.cpp" line="132"/> + <source>Save as ...</source> + <translation>Enregistrer sous...</translation> + </message> + <message> + <location filename="../slowmoUI/mainwindow.cpp" line="133"/> + <source>Abort move</source> + <translation>Annuler le mouvement</translation> + </message> + <message> + <location filename="../slowmoUI/mainwindow.cpp" line="134"/> + <source>Unselect all</source> + <translation>Tout désélectionner</translation> + </message> + <message> + <location filename="../slowmoUI/mainwindow.cpp" line="135"/> + <source>Delete selected nodes</source> + <translation>Supprimer les noeuds sélectionnés</translation> + </message> + <message> + <location filename="../slowmoUI/mainwindow.cpp" line="136"/> + <source>Selecting tool</source> + <translation>Outil sélection</translation> + </message> + <message> + <location filename="../slowmoUI/mainwindow.cpp" line="137"/> + <source>Move tool</source> + <translation>Outil déplacer</translation> + </message> + <message> + <location filename="../slowmoUI/mainwindow.cpp" line="138"/> + <source>Insert label (tag)</source> + <translation>Insérer une étiquette (tag)</translation> + </message> + <message> + <location filename="../slowmoUI/mainwindow.cpp" line="335"/> + <source>Load Project</source> + <translation>Charger un Projet</translation> + </message> + <message> + <location filename="../slowmoUI/mainwindow.cpp" line="335"/> + <location filename="../slowmoUI/mainwindow.cpp" line="386"/> + <source>slowmoVideo projects (*.sVproj)</source> + <translation>projects slowmoVideo (*.sVproj)</translation> + </message> + <message> + <location filename="../slowmoUI/mainwindow.cpp" line="351"/> + <source>Warning</source> + <translation>Avertissement</translation> + </message> + <message> + <location filename="../slowmoUI/mainwindow.cpp" line="356"/> + <source>Frame source error</source> + <translation>Érreur d'image source</translation> + </message> + <message> + <location filename="../slowmoUI/mainwindow.cpp" line="358"/> + <location filename="../slowmoUI/mainwindow.cpp" line="556"/> + <source>Error</source> + <translation>Erreur</translation> + </message> + <message> + <location filename="../slowmoUI/mainwindow.cpp" line="369"/> + <source>No filename given, won't save. (Perhaps an empty project?)</source> + <translation>Pas de nom de fichier donné, pas d'enregistrement. (Peut être un projet vide ?)</translation> + </message> + <message> + <location filename="../slowmoUI/mainwindow.cpp" line="375"/> + <source>Saved project as: %1</source> + <translation>Projet enregistré sous : %1</translation> + </message> + <message> + <location filename="../slowmoUI/mainwindow.cpp" line="377"/> + <source>Error writing project file</source> + <translation>Érreur lors de l'écriture du projet</translation> + </message> + <message> + <location filename="../slowmoUI/mainwindow.cpp" line="383"/> + <source>Save project</source> + <translation>Enregistrer le projet</translation> + </message> + <message> + <location filename="../slowmoUI/mainwindow.cpp" line="405"/> + <source> +Navigation: Shift Scroll, Drag</source> + <translation> +Navigation: Shift Défiler, Déplacer</translation> + </message> + <message> + <location filename="../slowmoUI/mainwindow.cpp" line="406"/> + <source> +Move nodes: Ctrl Drag</source> + <translation> +Déplacement des noeuds: Ctrl Déplacer</translation> + </message> + <message> + <location filename="../slowmoUI/mainwindow.cpp" line="444"/> + <source>empty project</source> + <translation>projet vide</translation> + </message> + <message> + <location filename="../slowmoUI/mainwindow.cpp" line="529"/> + <source>Rendering progress</source> + <translation>Rendu en cours</translation> + </message> + <message> + <location filename="../slowmoUI/mainwindow.cpp" line="563"/> + <source>Frame extraction progress</source> + <translation>Extraction d'image en cours</translation> + </message> +</context> +<context> + <name>NewProjectDialog</name> + <message> + <location filename="../slowmoUI/dialogues/newProjectDialog.ui" line="14"/> + <source>New slowmo Project</source> + <translation>Nouveau projet slowmo</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/newProjectDialog.ui" line="23"/> + <location filename="../slowmoUI/dialogues/newProjectDialog.ui" line="92"/> + <location filename="../slowmoUI/dialogues/newProjectDialog.ui" line="157"/> + <source>Browse</source> + <translation>Parcourir</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/newProjectDialog.ui" line="45"/> + <source>Abort</source> + <translation>Annuler</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/newProjectDialog.ui" line="58"/> + <source>Ok</source> + <translation>Ok</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/newProjectDialog.ui" line="70"/> + <source>Directory will be created</source> + <translation>Le répertoire seras créé</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/newProjectDialog.ui" line="83"/> + <source>Video source</source> + <translation>Vidéo source</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/newProjectDialog.ui" line="99"/> + <source>Video information:</source> + <translation>Informations sur la vidéo :</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/newProjectDialog.ui" line="128"/> + <source>Input video</source> + <translation>Video en entrée</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/newProjectDialog.ui" line="138"/> + <source>Image source</source> + <translation>Images source</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/newProjectDialog.ui" line="150"/> + <source>Input images</source> + <translation>Images d'entrée</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/newProjectDialog.ui" line="164"/> + <source>Images information:</source> + <translation>Informations sur les images :</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/newProjectDialog.ui" line="186"/> + <source>Video file</source> + <translation>Fichier vidéo</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/newProjectDialog.ui" line="193"/> + <source>Images</source> + <translation>Images</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/newProjectDialog.ui" line="234"/> + <source>Project Directory</source> + <translation>Répertoire du projet</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/newProjectDialog.ui" line="247"/> + <source>Project Filename</source> + <translation>Nom du projet</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/newProjectDialog.ui" line="257"/> + <source>.sVproj</source> + <translation></translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/newProjectDialog.ui" line="264"/> + <source>You should preferredly use an empty directory here. Each project needs its own project directory.</source> + <translation>Chaque projet ayant besoin de son répertoire de projet, vous devriez en choisir un vide.</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/newProjectDialog.ui" line="274"/> + <source>The project will be saved to this file right after confirming this dialog.</source> + <translation>Le projet sera enregistré dans ce fichier à la confirmation de cette boite de dialogue.</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/newProjectDialog.cpp" line="91"/> + <source>Select input video file</source> + <translation>Sélectionnez le fichier vidéo d'entrée</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/newProjectDialog.cpp" line="112"/> + <source>Character %1 is not an ASCII character. This file path will likely not work with ffmpeg.</source> + <translation>Le charactère %1 n'est pas ASCII. Ce chemin de fichier ne vas malheuresement pas fonctionner avec ffmpeg.</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/newProjectDialog.cpp" line="123"/> + <source>Select input images</source> + <translation>Sélectionnez les images d'entrée</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/newProjectDialog.cpp" line="146"/> + <source>Select a project directory</source> + <translation>Sélectionnez un répertoire pour le projet</translation> + </message> + <message utf8="true"> + <location filename="../slowmoUI/dialogues/newProjectDialog.cpp" line="165"/> + <source>Number of video streams: %1 +Frames: %2 +Size: %3×%4 +</source> + <translation>Nombre de flux vidéo : %1 +Images : %2 +Taille : %3x%4</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/newProjectDialog.cpp" line="168"/> + <source>Frame rate: %1/%2</source> + <translation>Fréquence d'image: %1/%2</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/newProjectDialog.cpp" line="172"/> + <source>No video stream detected.</source> + <translation>Aucun flux vidéo trouvé.</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/newProjectDialog.cpp" line="217"/> + <source>Image size: %1</source> + <translation>Taille de l'image : %1</translation> + </message> +</context> +<context> + <name>PreferencesDialog</name> + <message> + <location filename="../slowmoUI/dialogues/preferencesDialog.ui" line="14"/> + <source>slowmoUI preferences</source> + <translation>slommoUI préférences</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/preferencesDialog.ui" line="22"/> + <source>Binary locations</source> + <translation>Localisation des executables</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/preferencesDialog.ui" line="31"/> + <location filename="../slowmoUI/dialogues/preferencesDialog.ui" line="55"/> + <source>Browse</source> + <translation>Parcourir</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/preferencesDialog.ui" line="67"/> + <source>Flow method</source> + <translation>Méthode d'évaluation du flux optique</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/preferencesDialog.ui" line="73"/> + <source>GPU, V3D (requires flowBuilder and a video card)</source> + <translation>GPU, V3D (nécessite flowBuilder et une carte graphique)</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/preferencesDialog.ui" line="80"/> + <source>CPU, OpenCV</source> + <translation>CPU, OpenCV</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/preferencesDialog.ui" line="121"/> + <source>Cancel</source> + <translation>Annuler</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/preferencesDialog.ui" line="128"/> + <source>Ok</source> + <translation>Ok</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/preferencesDialog.cpp" line="20"/> + <source>flowBuilder binary location</source> + <translation>localisation de l'executable flowBuilder</translation> + </message> +</context> +<context> + <name>ProgressDialog</name> + <message> + <location filename="../slowmoUI/dialogues/progressDialog.ui" line="14"/> + <source>Progress</source> + <translation>Progression</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/progressDialog.ui" line="28"/> + <source>Current Task</source> + <translation>Tache courante</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/progressDialog.ui" line="42"/> + <source>Task Description</source> + <translation>Déscription de la tache</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/progressDialog.ui" line="82"/> + <source>Abort</source> + <translation>Annuler</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/progressDialog.ui" line="89"/> + <source>Ok</source> + <translation>Ok</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/progressDialog.cpp" line="40"/> + <location filename="../slowmoUI/dialogues/progressDialog.cpp" line="41"/> + <source>(Finished) </source> + <translation>(Terminé)</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/progressDialog.cpp" line="62"/> + <source>Aborted</source> + <translation>Annulé</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/progressDialog.cpp" line="73"/> + <source>Task finished in %1.</source> + <translation>Tache terminé en %1.</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/progressDialog.cpp" line="75"/> + <source>Task finished.</source> + <translation>Tache terminé.</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/progressDialog.cpp" line="77"/> + <source>(Finished) %1</source> + <translation>(Fini) %1</translation> + </message> +</context> +<context> + <name>ProjectPreferencesDialog</name> + <message> + <location filename="../slowmoUI/dialogues/projectPreferencesDialog.ui" line="14"/> + <source>Dialog</source> + <translation>Dialogue</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/projectPreferencesDialog.ui" line="22"/> + <source>FPS value to use for calculating the output frame (display only)</source> + <translation>Valeur FPS à utiliser pour le calcul de l'image de sortie (affichage seulement)</translation> + </message> +</context> +<context> + <name>Project_sV</name> + <message> + <location filename="../project/project_sV.cpp" line="249"/> + <source>Empty frame source; Cannot build flow.</source> + <translation>Image source vide: Impossible de construire le flux.</translation> + </message> +</context> +<context> + <name>QObject</name> + <message> + <location filename="../lib/defs_sV.cpp" line="38"/> + <source>Orig</source> + <translation>Original</translation> + </message> + <message> + <location filename="../lib/defs_sV.cpp" line="40"/> + <source>Small</source> + <translation>Miniature</translation> + </message> + <message> + <location filename="../lib/defs_sV.cpp" line="43"/> + <source>Unknown size</source> + <translation>Taille inconnue</translation> + </message> + <message> + <location filename="../lib/defs_sV.cpp" line="51"/> + <source>Forward</source> + <translation>Arrière</translation> + </message> + <message> + <location filename="../lib/defs_sV.cpp" line="53"/> + <source>Backward</source> + <translation>Avant</translation> + </message> + <message> + <location filename="../lib/defs_sV.cpp" line="56"/> + <source>Unknown direction</source> + <translation>Direction inconnue</translation> + </message> + <message> + <location filename="../lib/defs_sV.cpp" line="64"/> + <source>Linear</source> + <translation>Linéaire</translation> + </message> + <message utf8="true"> + <location filename="../lib/defs_sV.cpp" line="66"/> + <source>Bézier</source> + <translation>Bézier</translation> + </message> + <message> + <location filename="../lib/defs_sV.cpp" line="69"/> + <source>Unknown curve type</source> + <translation>Type de courbe inconnue</translation> + </message> + <message> + <location filename="../lib/defs_sV.cpp" line="82"/> + <source>Source axis</source> + <translation>Axe Source</translation> + </message> + <message> + <location filename="../lib/defs_sV.cpp" line="84"/> + <source>Output axis</source> + <translation>Axe Sortie</translation> + </message> + <message> + <location filename="../lib/defs_sV.cpp" line="87"/> + <source>Unknown axis</source> + <translation>Axe Inconnue</translation> + </message> + <message> + <location filename="../lib/defs_sV.cpp" line="95"/> + <source>Forward interpolation (fast)</source> + <translation>Interpolation avant (rapide)</translation> + </message> + <message> + <location filename="../lib/defs_sV.cpp" line="97"/> + <source>Forward interpolation (accurate)</source> + <translation>Interpolation avant (précis)</translation> + </message> + <message> + <location filename="../lib/defs_sV.cpp" line="99"/> + <source>Two-way interpolation (fast)</source> + <translation>Interpolation avant et arrière (rapide)</translation> + </message> + <message> + <location filename="../lib/defs_sV.cpp" line="101"/> + <source>Two-way interpolation (accurate)</source> + <translation>Interpolation avant et arrière (précis)</translation> + </message> + <message utf8="true"> + <location filename="../lib/defs_sV.cpp" line="103"/> + <source>Bézier interpolation</source> + <translation>Interpolation Bézier</translation> + </message> + <message> + <location filename="../lib/defs_sV.cpp" line="106"/> + <source>Unknown interpolation</source> + <translation>Interpolation inconnue</translation> + </message> + <message> + <location filename="../lib/defs_sV.cpp" line="114"/> + <source>Stacking</source> + <translation>Empillement</translation> + </message> + <message> + <location filename="../lib/defs_sV.cpp" line="116"/> + <source>Convolution</source> + <translation></translation> + </message> + <message> + <location filename="../lib/defs_sV.cpp" line="118"/> + <source>Nearest (no blurring)</source> + <translation>Le plus proche (pas de flou)</translation> + </message> + <message> + <location filename="../project/interpolator_sV.cpp" line="13"/> + <source>Requested frame %1: Not within valid range. (%2 frames)</source> + <translation>L'image demandé %1: Est hors borne. (%2 images)</translation> + </message> + <message> + <location filename="../project/motionBlur_sV.cpp" line="90"/> + <source>Range too small: Start frame is %1, end frame is %2. Using normal interpolation.</source> + <translation>Borne trop petite: L'image de départ est %1, celle de fin est %2. En utilisant une interpolation normale.</translation> + </message> + <message> + <location filename="../project/videoRenderTarget_sV.cpp" line="61"/> + <source>Video could not be prepared (error code %1). +%2</source> + <translation>La vidéo n'as pas pu être préparé (code d'erreur %1). %2</translation> + </message> + <message> + <location filename="../project/xmlProjectRW_sV.cpp" line="159"/> + <source>Cannot write to %1; please check if you have write permissions.</source> + <translation>Écriture impossible sur %1: merci de vérifier vos permissions d'écriture.</translation> + </message> + <message utf8="true"> + <location filename="../project/xmlProjectRW_sV.cpp" line="305"/> + <source>Unknown frame source “%1”. Cannot load the project.</source> + <translation>Image source inconnue "%1". Le projet ne sera pas chargé.</translation> + </message> + <message> + <location filename="../project/xmlProjectRW_sV.cpp" line="314"/> + <source>Cannot read from file %1. (Opening in read-only mode failed.)</source> + <translation>Impossible de lire le fichier %1. (l'ouverture en lecture seule a échoué)</translation> + </message> + <message> + <location filename="../project/xmlProjectRW_sV.cpp" line="321"/> + <source>Invalid project file: %1</source> + <translation>Fichier de projet invalide: %1</translation> + </message> + <message> + <location filename="../slowmoUI/canvasTools.cpp" line="39"/> + <source>%1 s</source> + <translation>%1 s</translation> + </message> + <message> + <location filename="../slowmoUI/canvasTools.cpp" line="41"/> + <source>%1 min %2 s</source> + <translation>%1 min %2 s</translation> + </message> + <message> + <location filename="../slowmoUI/canvasTools.cpp" line="45"/> + <source> +Frame %1</source> + <translation>Image %1</translation> + </message> + <message> + <location filename="../slowmoUI/canvasTools.cpp" line="75"/> + <source>%1 %</source> + <translation>%1 %</translation> + </message> +</context> +<context> + <name>RenderPreview</name> + <message> + <location filename="../slowmoUI/renderPreview.ui" line="14"/> + <source>Render preview</source> + <translation>Prévisualisation de rendu</translation> + </message> + <message> + <location filename="../slowmoUI/renderPreview.ui" line="51"/> + <source>This is an information message.</source> + <translation>Ceci est un message d'information.</translation> + </message> + <message> + <location filename="../slowmoUI/renderPreview.cpp" line="61"/> + <source>Cannot render preview, no frames loaded.</source> + <translation>Impossible de faire une prévisualisation, aucune images chargées.</translation> + </message> + <message> + <location filename="../slowmoUI/renderPreview.cpp" line="65"/> + <source>Cannot render preview at the curve position since no curve is available.</source> + <translation>Impossible de faire un rendu a la position de courbe tant que la courbe n'est pas disponible.</translation> + </message> + <message> + <location filename="../slowmoUI/renderPreview.cpp" line="69"/> + <source>Rendering preview at output time %1 s (might take some time) ...</source> + <translation>Rendu de la prévisualisation au temps %1 (cela peu encore prendre du temps) ...</translation> + </message> + <message> + <location filename="../slowmoUI/renderPreview.cpp" line="72"/> + <source>Preview is still being rendered.</source> + <translation>La prévisualisation est toujours en cours.</translation> + </message> + <message> + <location filename="../slowmoUI/renderPreview.cpp" line="88"/> + <source>Cannot render at output time %1 s; Not within the curve.</source> + <translation>Impossible de faire le rendu au temps %1 ; Il n'est pas contenu dans la courbe.</translation> + </message> + <message> + <location filename="../slowmoUI/renderPreview.cpp" line="98"/> + <source>Preview rendering finished.</source> + <translation>Rendu de la prévisualisation terminé.</translation> + </message> +</context> +<context> + <name>RenderTask_sV</name> + <message> + <location filename="../project/renderTask_sV.cpp" line="102"/> + <source>Rendering aborted.</source> + <translation>Rendu annulé.</translation> + </message> + <message utf8="true"> + <location filename="../project/renderTask_sV.cpp" line="110"/> + <source>Rendering Slow-Mo …</source> + <translation>Rendu Slow-Mo ...</translation> + </message> + <message> + <location filename="../project/renderTask_sV.cpp" line="121"/> + <source>No rendering target given! Aborting rendering.</source> + <translation>Aucune cible de rendu donné! Annulation du rendu.</translation> + </message> + <message> + <location filename="../project/renderTask_sV.cpp" line="126"/> + <source>Empty frame source, cannot be rendered.</source> + <translation>Image source vide, rendu impossible.</translation> + </message> + <message> + <location filename="../project/renderTask_sV.cpp" line="143"/> + <source>Rendering frame %1 @ %2 s from input position: %3 s (frame %4)</source> + <translation>Rendu de l'image %1 @ %2 s depuis la position d'entrée : %3 s (image %4)</translation> + </message> +</context> +<context> + <name>RenderingDialog</name> + <message> + <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="14"/> + <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="46"/> + <source>Rendering settings</source> + <translation>Paramètres de rendu</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="40"/> + <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="43"/> + <source>a</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="54"/> + <source>Full Project</source> + <translation>Projet entier</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="64"/> + <source>Tag section</source> + <translation>Section par tags</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="71"/> + <source>Custom section</source> + <translation>Section personnalisée</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="116"/> + <source>to</source> + <translation>à</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="192"/> + <source>Frames per second:</source> + <translation>Images par seconde :</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="284"/> + <source>Size:</source> + <translation>Taille :</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="310"/> + <source>Interpolation:</source> + <translation>Interpolation :</translation> + </message> + <message utf8="true"> + <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="340"/> + <source>For two frames A and B, the two-way interpolations calculate both the flows A→B and B→A, which leads to smoother transitions between them. Forward interpolations only calculate A→B; Twice as fast, but usually less smooth.</source> + <translation>Pour deux images A et B, l'interpolation "avant-arrière" calcule les deux flux A→B et B→A, ce qui genère des transitions plus fluide entre elles. L'interpolation "avant" ne calcule que A→B; deux fois plus rapide, mais générallement moins fluide.</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="366"/> + <source>Optical Flow</source> + <translation>Flux Optique</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="372"/> + <source>Optical flow</source> + <translation>Flux optique</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="380"/> + <source>buildFlow lambda</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="428"/> + <source>Use a higher value for high-quality footage and larger images.</source> + <translation>Une valeur haute produit des vidéos haute-qualité et des images plus grosses.</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="445"/> + <source>The lambda is only used with the GPU based Optical Flow algorithm. There is no general rule which value is best, so it is usually a good idea to render a short part with a low (5) and a high (50) lambda to see the differences, and then try to find the best value between.</source> + <translation>Le lambda est uniquement utilisé pour l'algorithme de de Flux Optique basé sur le GPU. Il n'y a pas de régle général pour le choix de la meilleur valeur. C'est générallement une bonne idée d'effectuer des tests sur un extrait avec un faible (5) et un haut (50) lambda pour finallement trouver la meilleure valeur entre les deux.</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="474"/> + <source>Motion Blur</source> + <translation></translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="480"/> + <source>Motion blur</source> + <translation></translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="486"/> + <source>Motion blur will only be applied for segments on which it is enabled.</source> + <translation>Motion blur ne seras appliqué uniquement pour les segments sur lequel il est activé.</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="496"/> + <source>Stacking blur (Uses more disk space, but is faster for repeated rendering.)</source> + <translation>Stacking blur. (Utilise plus d'espace disque mais plus rapide pour des rendus répétés)</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="505"/> + <source>Maximum samples</source> + <translation>Samples maximum</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="538"/> + <source>Samples for slow motion</source> + <translation>Samples pour le slow motion</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="570"/> + <source>Convolution blur (Smoother than stacking, usually the better choice.)</source> + <translation>Convolution blur (Plus fluide que stacking, générallement un meilleur choix)</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="577"/> + <source>Nearest (no blurring)</source> + <translation></translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="601"/> + <source>Output</source> + <translation>Sortie</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="609"/> + <source>Target:</source> + <translation>Cible :</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="619"/> + <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="711"/> + <source>Video</source> + <translation>Vidéo</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="626"/> + <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="651"/> + <source>Images</source> + <translation>Images</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="657"/> + <source>The %1 in the filename pattern is mandatory and will be replaced by the frame number.</source> + <translation>Le %1 dans le modèle du nom de fichier est obligatoire, il sera remplacé par le numéro de l'image.</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="666"/> + <source>Output directory</source> + <translation>Dossier de sortie</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="676"/> + <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="739"/> + <source>Browse</source> + <translation>Parcourir</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="683"/> + <source>Filename pattern</source> + <translation>Modèle du nom de fichier</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="693"/> + <source>rendered-%1.jpg</source> + <translation>rendu-%1.jpg</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="717"/> + <source>Videos will be encoded with ffmpeg. If additional arguments are left empty, defaults will be used. The video format is determined by ffmpeg according to the file suffix.</source> + <translation>Les vidéos seront encodées avec ffmpeg. Si aucun paramètres additionels ne sont donnés, ceux par défaut seront utilisés. Le format de la vidéo est déterminé par ffmpeg suivant le suffixe du fichier.</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="729"/> + <source>Output file</source> + <translation>Fichier de sortie</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="746"/> + <source>Optional arguments</source> + <translation>Paramètre optionnels</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="806"/> + <source>Will *not* save the project!</source> + <translation>Ceci n'enregistrera *pas* le projet!</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="809"/> + <source>&Save settings</source> + <translation>&Enregistrer les paramètres</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="816"/> + <source>&Abort</source> + <translation>&Annuler</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/renderingDialog.ui" line="823"/> + <source>&Ok</source> + <translation>&Ok</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/renderingDialog.cpp" line="94"/> + <source>Original size</source> + <translation>Taille original</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/renderingDialog.cpp" line="95"/> + <source>Small</source> + <translation>Miniature</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/renderingDialog.cpp" line="244"/> + <source><Start></source> + <translation><Début></translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/renderingDialog.cpp" line="249"/> + <source><End></source> + <translation><Fin></translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/renderingDialog.cpp" line="360"/> + <source>Start time must be < end time!</source> + <translation>Le temps de début doit être < au temps de fin!</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/renderingDialog.cpp" line="363"/> + <source>Rendering from %1 s to %2 s.</source> + <translation>Rendu en cours de %1 s à %2 s.</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/renderingDialog.cpp" line="398"/> + <source>Output directory for rendered images</source> + <translation>Dossier de sortie pour le rendu des images</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/renderingDialog.cpp" line="410"/> + <source>Output video file</source> + <translation>Fichier vidéo de sortie</translation> + </message> +</context> +<context> + <name>ShortcutListDialog</name> + <message> + <location filename="../slowmoFlowEdit/shortcutListDialog.ui" line="20"/> + <source>Flow Editor shortcuts</source> + <translation>Raccourcis de l'Éditeur de flux</translation> + </message> +</context> +<context> + <name>ShutterFunctionDialog</name> + <message> + <location filename="../slowmoUI/dialogues/shutterFunctionDialog.ui" line="14"/> + <source>Shutter Functions</source> + <translation>Fonctions de l'obturateur</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/shutterFunctionDialog.ui" line="22"/> + <source><</source> + <translation><</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/shutterFunctionDialog.ui" line="29"/> + <source>Segment %1</source> + <translation>Segment %1</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/shutterFunctionDialog.ui" line="36"/> + <source>></source> + <translation>></translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/shutterFunctionDialog.ui" line="70"/> + <source>+</source> + <translation>+</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/shutterFunctionDialog.ui" line="77"/> + <source>-</source> + <translation>-</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/shutterFunctionDialog.ui" line="100"/> + <source>shutterFunc1</source> + <translation>obturateurFunc1</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/shutterFunctionDialog.ui" line="123"/> + <location filename="../slowmoUI/dialogues/shutterFunctionDialog.cpp" line="184"/> + <source>Used: %1 times</source> + <translation>Utilisé : %1 fois</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/shutterFunctionDialog.ui" line="164"/> + <source>// header +(function foo(args...) {</source> + <translation></translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/shutterFunctionDialog.ui" line="202"/> + <source>return 0;</source> + <translation></translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/shutterFunctionDialog.ui" line="215"/> + <source>// footer +})</source> + <translation></translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/shutterFunctionDialog.ui" line="230"/> + <source><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Bitstream Vera Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Math functions are available in the Math namespace:</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Monospace';">Math.PI, Math.cos(...), Math.pow(base. exponent) etc.</span></p> +</body></html></source> + <translation></translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/shutterFunctionDialog.ui" line="293"/> + <source>Close</source> + <translation>Fermer</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/shutterFunctionDialog.cpp" line="95"/> + <source>Segment %1 (total number: %2)</source> + <translation>Segment %1 (sur un total de %2)</translation> + </message> +</context> +<context> + <name>TagAddDialog</name> + <message> + <location filename="../slowmoUI/dialogues/tagAddDialog.ui" line="14"/> + <source>Add tag</source> + <translation>Ajouter un tag</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/tagAddDialog.ui" line="20"/> + <source>Change the tag type with Arrows up/down.</source> + <translation>Changez le type du tag avec les flèches haut/bas.</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/tagAddDialog.ui" line="45"/> + <source>Source Tag</source> + <translation>Tag Source</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/tagAddDialog.ui" line="65"/> + <source>Output Tag</source> + <translation>Tag Sortie</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/tagAddDialog.ui" line="154"/> + <source>Abort</source> + <translation>Annuler</translation> + </message> + <message> + <location filename="../slowmoUI/dialogues/tagAddDialog.ui" line="161"/> + <source>Ok</source> + <translation>Ok</translation> + </message> +</context> +<context> + <name>VideoFrameSource_sV</name> + <message> + <location filename="../project/videoFrameSource_sV.cpp" line="30"/> + <source>Video file %1 does not exist!</source> + <translation>Le fichier vidéo %1 n'existe pas !</translation> + </message> + <message> + <location filename="../project/videoFrameSource_sV.cpp" line="38"/> + <source>Video is invalid, no streams found in %1</source> + <translation>La vidéo n'est pas valide, aucun flux trouvé dans %1</translation> + </message> + <message> + <location filename="../project/videoFrameSource_sV.cpp" line="175"/> + <source>ffmpeg/avconv executable not found! Cannot load video. +(It is also possible that it took a little long to respond due to high workload, so you might want to try again.) +Please download the 32-bit static ffmpeg build from ffmpeg.zeranoe.com and extract ffmpeg.exe in the same directory as slowmoUI.exe.</source> + <translation>Le programme ffmpeg/avconv n'as pas été trouvé ! Impossible de charger la vidéo. +(Il est également possible qu'il ai mis du temps à répondre du à une importante charge processus, vous pouvez avoir envie de retenter) +Merci d'installer ffmpeg.exe, 32-bit static build depuis ffmpeg.zeranoe.com, dans le même dossier que slowmoUI.exe.</translation> + </message> + <message> + <location filename="../project/videoFrameSource_sV.cpp" line="188"/> + <source>Extracting thumbnail-sized frames from the video file</source> + <translation>Extraction d'images miniatures depuis le fichier vidéo</translation> + </message> + <message> + <location filename="../project/videoFrameSource_sV.cpp" line="213"/> + <source>Extracting original-sized frames from the video file</source> + <translation>Extraction d'images à la taille originale depuis le fichier vidéo</translation> + </message> + <message> + <location filename="../project/videoFrameSource_sV.cpp" line="269"/> + <source>Frame %1 of %2</source> + <translation>Image %1 sur %2</translation> + </message> +</context> +</TS>
View file
slowmoVideo-0.6.tar.xz/src/tr/slowmoVideo_it.qm
Changed
(renamed from src/slowmoVideo/tr/slowmoVideo_it.qm)
View file
slowmoVideo-0.6.tar.xz/src/tr/slowmoVideo_it.ts
Changed
(renamed from src/slowmoVideo/tr/slowmoVideo_it.ts)
View file
slowmoVideo-0.6.tar.xz/src/unittests
Added
+(directory)
View file
slowmoVideo-0.6.tar.xz/src/unittests/CMakeLists.txt
Added
@@ -0,0 +1,20 @@ + +set(SRCS + testFlowRW_sV.cpp + testFlowField_sV.cpp + testVector_sV.cpp + testIntMatrix_sV.cpp + testXmlProjectRW_sV.cpp + testDefs_sV.cpp + testShutterFunction_sV.cpp + testProject_sV.cpp + testNodeList_sV.cpp + testAll.cpp +) + +include_directories(${FFMPEG_INCLUDE_PATHS}) +add_executable(UnitTests ${SRCS}) +qt5_use_modules(UnitTests Concurrent Core Test) +target_link_libraries(UnitTests sVproj sVflowtools ${EXTERNAL_LIBS}) + +add_test(UnitTests UnitTests)
View file
slowmoVideo-0.6.tar.xz/src/unittests/testAll.cpp
Changed
(renamed from src/slowmoVideo/unittests/testAll.cpp)
View file
slowmoVideo-0.6.tar.xz/src/unittests/testDefs_sV.cpp
Changed
(renamed from src/slowmoVideo/unittests/testDefs_sV.cpp)
View file
slowmoVideo-0.6.tar.xz/src/unittests/testDefs_sV.h
Changed
(renamed from src/slowmoVideo/unittests/testDefs_sV.h)
View file
slowmoVideo-0.6.tar.xz/src/unittests/testFlowField_sV.cpp
Added
@@ -0,0 +1,98 @@ +#include "testFlowField_sV.h" +#include "../lib/kernel_sV.h" +#include "../lib/flowTools_sV.h" + +#include <iostream> +#include <flowField_sV.h> + +void TestFlowField_sV::slotTestConstructorOpenGL() +{ + const int width = 2; + const int height = 2; + + FlowField_sV field(width, height); + for (int i = 0; i < 2*width*height; i++) { + field.data()i = i; + } + + float *glData = new float3*width*height; + float *pData = glData; + for (int i = 0; i < width*height; i++) { + *(pData++) = field.data()2*i+0; + *(pData++) = field.data()2*i+1; + pData++; + } + + FlowField_sV *glField = new FlowField_sV(width, height, glData, FlowField_sV::GLFormat_RGB); + + QVERIFY(field == *glField); + + delete glData; + delete glField; +} + +void TestFlowField_sV::slotTestGaussKernel() +{ + Kernel_sV kernel(2,2); + kernel.gauss(); + std::cout << kernel; + QVERIFY(fabs(kernel(0,0)-1) < .001); + QVERIFY(fabs(kernel(-1,-1)-.135) < .001); + QVERIFY(kernel(-1,-1) == kernel(1,1)); + + kernel = Kernel_sV(3,1); + kernel.gauss(); + std::cout << kernel; + QVERIFY(fabs(kernel(0,0)-1) < .001); + QVERIFY(fabs(kernel(-3,-1)) < .001); + +} + +void TestFlowField_sV::slotTestMedian() +{ + int *values = new int4; + + values0 = 0; values1 = 0; + values2 = 0; values3 = 2; + FlowField_sV f1(2,2); + initFlowField(&f1, values); + + values0 = 0; values1 = 1; + values2 = 0; values3 = 1; + FlowField_sV f2(2,2); + initFlowField(&f2, values); + + values0 = 0; values1 = 2; + values2 = 1; values3 = 0; + FlowField_sV f3(2,2); + initFlowField(&f3, values); + + FlowField_sV *outField = FlowTools_sV::median(&f1, &f2, &f3); + + values0 = 0; values1 = 1; + values2 = 0; values3 = 1; + + QVERIFY(outField->x(0,0) == values0); + QVERIFY(outField->x(1,0) == values1); + QVERIFY(outField->x(0,1) == values2); + QVERIFY(outField->x(1,1) == values3); + QVERIFY(outField->y(0,0) == values0); + QVERIFY(outField->y(1,0) == values1); + QVERIFY(outField->y(0,1) == values2); + QVERIFY(outField->y(1,1) == values3); + + delete values; + delete outField; +} + +void TestFlowField_sV::initFlowField(FlowField_sV *field, int *values) +{ + int c = 0; + for (int y = 0; y < field->height(); y++) { + for (int x = 0; x < field->width(); x++) { + field->rx(x,y) = valuesc; + field->ry(x,y) = valuesc; + c++; + } + } +}
View file
slowmoVideo-0.6.tar.xz/src/unittests/testFlowField_sV.h
Changed
(renamed from src/slowmoVideo/unittests/testFlowField_sV.h)
View file
slowmoVideo-0.6.tar.xz/src/unittests/testFlowRW_sV.cpp
Added
@@ -0,0 +1,57 @@ +#include "testFlowRW_sV.h" + +#include <QDebug> +#include <string> +#include <flowField_sV.h> +#include <flowRW_sV.h> + +void TestFlowRW_sV::testWriteAndRead() +{ + const std::string filename("/tmp/unittestFlowField_sV.sVflow"); + + const int width = 3; + const int height = 2; + FlowField_sV *field = new FlowField_sV(width, height); + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + field->setX(x, y, x/float(y+1)); + field->setY(x, y, x/float(y+2)); + } + } + FlowRW_sV::save(filename, field); + + FlowField_sV *loadedField = FlowRW_sV::load(filename); + + QVERIFY(*field == *loadedField); + + delete field; + delete loadedField; +} +void TestFlowRW_sV::testWriteAndReadFail() +{ + const std::string filename("/tmp/unittestFlowField_sV.sVflow"); + + const int width = 3; + const int height = 2; + FlowField_sV *field = new FlowField_sV(width, height); + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + field->setX(x, y, x/float(y+1)); + field->setY(x, y, x/float(y+2)); + } + } + FlowRW_sV::save(filename, field); + + + + field->setX(width-1, height-1, -3.1415927); + FlowField_sV *loadedField = FlowRW_sV::load(filename); + + qDebug() << "Equal? " << (field->x(width-1, height-1) == loadedField->x(width-1, height-1)); + + QVERIFY( !( *field == *loadedField ) ); + + delete field; + delete loadedField; +} +
View file
slowmoVideo-0.6.tar.xz/src/unittests/testFlowRW_sV.h
Changed
(renamed from src/slowmoVideo/unittests/testFlowRW_sV.h)
View file
slowmoVideo-0.6.tar.xz/src/unittests/testIntMatrix_sV.cpp
Changed
(renamed from src/slowmoVideo/unittests/testIntMatrix_sV.cpp)
View file
slowmoVideo-0.6.tar.xz/src/unittests/testIntMatrix_sV.h
Changed
(renamed from src/slowmoVideo/unittests/testIntMatrix_sV.h)
View file
slowmoVideo-0.6.tar.xz/src/unittests/testLog.cpp
Added
@@ -0,0 +1,28 @@ +#include <QApplication> +#include <QPointer> +#include <QDebug> +#include "logbrowser.h" + +QPointer<LogBrowser> logBrowser; + +void myMessageOutput(QtMsgType type, const char *msg) +{ + if(logBrowser) + logBrowser->outputMessage( type, msg ); +} + +int main(int argc, char *argv) +{ + QApplication a(argc, argv); + +logBrowser = new LogBrowser; + qInstallMsgHandler(myMessageOutput); + +qDebug() << "test for debug"; + int result = a.exec(); + qDebug() << "application exec return result =" << result; + +delete logBrowser; + return result; +} +
View file
slowmoVideo-0.6.tar.xz/src/unittests/testNodeList_sV.cpp
Changed
(renamed from src/slowmoVideo/unittests/testNodeList_sV.cpp)
View file
slowmoVideo-0.6.tar.xz/src/unittests/testNodeList_sV.h
Changed
(renamed from src/slowmoVideo/unittests/testNodeList_sV.h)
View file
slowmoVideo-0.6.tar.xz/src/unittests/testProject_sV.cpp
Changed
(renamed from src/slowmoVideo/unittests/testProject_sV.cpp)
View file
slowmoVideo-0.6.tar.xz/src/unittests/testProject_sV.h
Changed
(renamed from src/slowmoVideo/unittests/testProject_sV.h)
View file
slowmoVideo-0.6.tar.xz/src/unittests/testShutterFunction_sV.cpp
Changed
(renamed from src/slowmoVideo/unittests/testShutterFunction_sV.cpp)
View file
slowmoVideo-0.6.tar.xz/src/unittests/testShutterFunction_sV.h
Changed
(renamed from src/slowmoVideo/unittests/testShutterFunction_sV.h)
View file
slowmoVideo-0.6.tar.xz/src/unittests/testVector_sV.cpp
Changed
(renamed from src/slowmoVideo/unittests/testVector_sV.cpp)
View file
slowmoVideo-0.6.tar.xz/src/unittests/testVector_sV.h
Changed
(renamed from src/slowmoVideo/unittests/testVector_sV.h)
View file
slowmoVideo-0.6.tar.xz/src/unittests/testXmlProjectRW_sV.cpp
Changed
(renamed from src/slowmoVideo/unittests/testXmlProjectRW_sV.cpp)
View file
slowmoVideo-0.6.tar.xz/src/unittests/testXmlProjectRW_sV.h
Changed
(renamed from src/slowmoVideo/unittests/testXmlProjectRW_sV.h)
View file
slowmoVideo-0.6.tar.xz/src/version.h.in
Added
@@ -0,0 +1,14 @@ +/* + * slowmovideo version information + */ +#ifndef _VER_INFO_H +#define _VER_INFO_H 1 + +#define SLOWMOVIDEO_VERSION_MAJOR @PROJECT_VERSION_MAJOR@ +#define SLOWMOVIDEO_VERSION_MINOR @PROJECT_VERSION_MINOR@ +#define SLOWMOVIDEO_VERSION_PATCH @PROJECT_VERSION_PATCH@ + +#define SLOWMOVIDEO_VERSION_SHA1 "@PROJECT_VERSION_SHA1@" +#define SLOWMOVIDEO_VERSION_FULL "@VERSION@" + +#endif
View file
slowmoVideo-0.6.tar.xz/src/visualizeFlow
Added
+(directory)
View file
slowmoVideo-0.6.tar.xz/src/visualizeFlow/CMakeLists.txt
Added
@@ -0,0 +1,11 @@ + +include_directories(..) + +set(SRCS + visualizeFlow.cpp +) + +add_executable(slowmoVisualizeFlow ${SRCS}) +target_link_libraries(slowmoVisualizeFlow sVvis sVflowtools) + +install(TARGETS slowmoVisualizeFlow DESTINATION ${DEST})
View file
slowmoVideo-0.6.tar.xz/src/visualizeFlow/visualizeFlow.cpp
Added
@@ -0,0 +1,123 @@ +/* +slowmoVideo creates slow-motion videos from normal-speed videos. +Copyright (C) 2011 Simon A. Eugster (Granjow) <simon.eu@gmail.com> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +*/ + + +#include "flowRW_sV.h" +#include "lib/flowVisualization_sV.h" +#include "lib/flowTools_sV.h" + +#include <QImage> +#include <QtCore/QDebug> + +#include <iostream> + +char *myName; + +void printUsage() { + std::cout << "Usage: " << std::endl; + std::cout << "\t" << myName << " <flow data> <output image>" << std::endl; + std::cout << "\t" << myName << " diff <flow1> <flow2> <output image>" << std::endl; + std::cout << "\t" << myName << " ref (writes an HSV reference image)" << std::endl; +} + +QImage reference() { + const int width = 1024, height = 1024; + float cX = width/2.0; + float cY = height/2.0; + + FlowField_sV field(width, height); + + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + field.setX(x,y, x-cX); + field.setY(x,y, y-cY); + } + } + + return FlowVisualization_sV::colourizeFlow(&field, FlowVisualization_sV::HSV, 1.0); +} + +void colourizeFlow(int argc, char *argv) +{ + if (argc <= 2) { + printUsage(); + exit(-1); + } + std::string inputFile = argv1; + QString outputFile(argv2); + + FlowField_sV *flowField; + try { + flowField = FlowRW_sV::load(inputFile); + } catch (FlowRW_sV::FlowRWError &err) { + std::cout << err.what() << std::endl; + exit(-2); + } + + std::cout << "Flow file loaded. Width: " << flowField->width() << ", height: " << flowField->height() << std::endl; + + /// \todo make visualization type configurable + QImage img = FlowVisualization_sV::colourizeFlow(flowField, FlowVisualization_sV::WXY); + + std::cout << "Saving " << outputFile.toStdString() << " ..." << std::endl; + img.save(outputFile); + + delete flowField; +} + +void diffFlow(int argc, char *argv) +{ + if (argc <= 4) { + printUsage(); + exit(-1); + } + FlowField_sV *leftFlow = FlowRW_sV::load(argv2); + FlowField_sV *rightFlow = FlowRW_sV::load(argv3); + FlowField_sV flowDifference(leftFlow->width(), leftFlow->height()); + + if (strcmp("diffSigned", argv1) == 0) { + FlowTools_sV::signedDifference(*leftFlow, *rightFlow, flowDifference); + } else { + FlowTools_sV::difference(*leftFlow, *rightFlow, flowDifference); + } + + int d; + QImage img(flowDifference.width(), flowDifference.height(), QImage::Format_ARGB32); + for (int y = 0; y < img.height(); y++) { + for (int x = 0; x < img.width(); x++) { + d = 128 + flowDifference.x(x,y)+flowDifference.y(x,y); + if (d > 255) { d = 255; } + if (d < 0) { d = 0; } + img.setPixel(x, y, qRgb(d,d,d)); + } + } + img.save(argv4); + + delete leftFlow; + delete rightFlow; +} + +int main(int argc, char *argv) +{ + myName = argv0; + + if (argc <= 1) { + printUsage(); + exit(-1); + } + + if (strcmp("diff", argv1) == 0 || strcmp("diffSigned", argv1) == 0) { + diffFlow(argc, argv); + } else if (strcmp("ref", argv1) == 0) { + reference().save("reference.png"); + } else { + colourizeFlow(argc, argv); + } +}
View file
slowmoVideo-0.4.tar.gz/todo.org -> slowmoVideo-0.6.tar.xz/todo.org
Changed
@@ -1,6 +1,9 @@ #+STARTUP: showall #+STARTUP: nohideblocks +git filter-branch --index-filter 'git rm --cached -qr --ignore-unmatch -- . && git reset -q $GIT_COMMIT -- V3D src/V3D src/cmake Config V3D/Config' --prune-empty -- --all + + * UI 1/3 - X Always display some units (user feedback when scrolling)
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.