├── data ├── resources │ ├── header.png │ └── resources.qrc ├── screenshots │ ├── screenshot01.png │ ├── screenshot02.png │ └── screenshot03.png ├── icons │ ├── 16 │ │ ├── simplescreenrecorder.png │ │ ├── simplescreenrecorder-error.png │ │ ├── simplescreenrecorder-idle.png │ │ ├── simplescreenrecorder-paused.png │ │ └── simplescreenrecorder-recording.png │ ├── 22 │ │ ├── simplescreenrecorder.png │ │ ├── simplescreenrecorder-error.png │ │ ├── simplescreenrecorder-idle.png │ │ ├── simplescreenrecorder-paused.png │ │ └── simplescreenrecorder-recording.png │ ├── 24 │ │ ├── simplescreenrecorder.png │ │ ├── simplescreenrecorder-error.png │ │ ├── simplescreenrecorder-idle.png │ │ ├── simplescreenrecorder-paused.png │ │ └── simplescreenrecorder-recording.png │ ├── 32 │ │ ├── simplescreenrecorder.png │ │ ├── simplescreenrecorder-error.png │ │ ├── simplescreenrecorder-idle.png │ │ ├── simplescreenrecorder-paused.png │ │ └── simplescreenrecorder-recording.png │ ├── 48 │ │ ├── simplescreenrecorder.png │ │ ├── simplescreenrecorder-error.png │ │ ├── simplescreenrecorder-idle.png │ │ ├── simplescreenrecorder-paused.png │ │ └── simplescreenrecorder-recording.png │ ├── 64 │ │ ├── simplescreenrecorder.png │ │ ├── simplescreenrecorder-error.png │ │ ├── simplescreenrecorder-idle.png │ │ ├── simplescreenrecorder-paused.png │ │ └── simplescreenrecorder-recording.png │ ├── 96 │ │ ├── simplescreenrecorder.png │ │ ├── simplescreenrecorder-error.png │ │ ├── simplescreenrecorder-idle.png │ │ ├── simplescreenrecorder-paused.png │ │ └── simplescreenrecorder-recording.png │ ├── 128 │ │ ├── simplescreenrecorder.png │ │ ├── simplescreenrecorder-idle.png │ │ ├── simplescreenrecorder-error.png │ │ ├── simplescreenrecorder-paused.png │ │ └── simplescreenrecorder-recording.png │ ├── 192 │ │ ├── simplescreenrecorder.png │ │ ├── simplescreenrecorder-idle.png │ │ ├── simplescreenrecorder-error.png │ │ ├── simplescreenrecorder-paused.png │ │ └── simplescreenrecorder-recording.png │ └── 256 │ │ ├── simplescreenrecorder.png │ │ ├── simplescreenrecorder-idle.png │ │ ├── simplescreenrecorder-error.png │ │ ├── simplescreenrecorder-paused.png │ │ └── simplescreenrecorder-recording.png ├── output-profiles │ ├── YouTube.conf │ ├── High%20Quality%20Intermediate.conf │ ├── Live%20Stream%20%281000kbps%29.conf │ ├── Live%20Stream%20%282000kbps%29.conf │ └── Live%20Stream%20%283000kbps%29.conf ├── simplescreenrecorder.desktop ├── man │ ├── ssr-glinject.1 │ └── simplescreenrecorder.1 └── simplescreenrecorder.appdata.xml ├── src ├── update-translations ├── update-translations-clean ├── translations │ ├── list.txt │ └── CMakeLists.txt ├── AV │ ├── Output │ │ ├── X264Presets.h │ │ ├── OutputSettings.h │ │ ├── VideoEncoder.h │ │ ├── AudioEncoder.h │ │ ├── SyncDiagram.h │ │ ├── OutputManager.h │ │ ├── Muxer.h │ │ └── BaseEncoder.h │ ├── Input │ │ ├── SSRVideoStream.h │ │ ├── SSRVideoStreamWatcher.h │ │ ├── ALSAInput.h │ │ ├── PulseAudioInput.h │ │ ├── JACKInput.h │ │ ├── SSRVideoStreamReader.h │ │ ├── GLInjectInput.h │ │ ├── X11Input.h │ │ └── WlrInput.h │ ├── FastScaler_Scale.h │ ├── SimpleSynth.h │ ├── FastResampler_FirFilter.h │ ├── FastScaler_Scale_Generic.h │ ├── FastResampler.h │ ├── FastScaler.h │ ├── FastScaler_Convert.h │ ├── FastScaler_Scale_Generic.cpp │ ├── SourceSink.cpp │ ├── FastResampler_FirFilter_Fallback.cpp │ ├── SampleCast.h │ ├── FastResampler_FirFilter_SSE2.cpp │ ├── SourceSink.h │ └── AVWrapper.h ├── Benchmark.h ├── NVidia.h ├── GUI │ ├── PageDone.h │ ├── Icons.h │ ├── PageWelcome.h │ ├── HiddenScrollArea.cpp │ ├── HiddenScrollArea.h │ ├── DialogGLInject.h │ ├── PageDone.cpp │ ├── Icons.cpp │ ├── ElidedLabel.h │ ├── ProfileBox.h │ ├── AudioPreviewer.h │ ├── MainWindow.h │ ├── ElidedLabel.cpp │ ├── VideoPreviewer.h │ └── HotkeyListener.h ├── Main.h ├── common │ ├── MutexDataPair.h │ ├── Logger.h │ ├── Dialogs.h │ ├── CPUFeatures.h │ ├── Logger.cpp │ ├── TempBuffer.h │ ├── EnumStrings.h │ ├── Dialogs.cpp │ ├── CPUFeatures.cpp │ ├── QueueBuffer.h │ └── LockFreeMessageQueue.h ├── NVidia.cpp └── SimpleScreenRecorder.pro ├── .gitignore ├── postinstall ├── glinject ├── GLInject.pro ├── GLInject.h ├── CMakeLists.txt ├── GLXFrameGrabber.h ├── SSRVideoStreamWriter.h ├── ShmStructs.h ├── GLInject.cpp └── Global.h ├── cmake ├── FindJack.cmake ├── FindPulseAudio.cmake ├── FindWaylandProtocols.cmake ├── WaylandScanner.cmake └── FindFFmpeg.cmake ├── simple-uninstall ├── AUTHORS.md ├── todo.txt ├── scripts └── ssr-glinject ├── CMakeLists.txt └── simple-build-and-install /data/resources/header.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/foxcpp/ssr-wlroots/HEAD/data/resources/header.png -------------------------------------------------------------------------------- /data/screenshots/screenshot01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/foxcpp/ssr-wlroots/HEAD/data/screenshots/screenshot01.png -------------------------------------------------------------------------------- /data/screenshots/screenshot02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/foxcpp/ssr-wlroots/HEAD/data/screenshots/screenshot02.png -------------------------------------------------------------------------------- /data/screenshots/screenshot03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/foxcpp/ssr-wlroots/HEAD/data/screenshots/screenshot03.png -------------------------------------------------------------------------------- /data/icons/128/simplescreenrecorder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/foxcpp/ssr-wlroots/HEAD/data/icons/128/simplescreenrecorder.png -------------------------------------------------------------------------------- /data/icons/16/simplescreenrecorder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/foxcpp/ssr-wlroots/HEAD/data/icons/16/simplescreenrecorder.png -------------------------------------------------------------------------------- /data/icons/192/simplescreenrecorder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/foxcpp/ssr-wlroots/HEAD/data/icons/192/simplescreenrecorder.png -------------------------------------------------------------------------------- /data/icons/22/simplescreenrecorder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/foxcpp/ssr-wlroots/HEAD/data/icons/22/simplescreenrecorder.png -------------------------------------------------------------------------------- /data/icons/24/simplescreenrecorder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/foxcpp/ssr-wlroots/HEAD/data/icons/24/simplescreenrecorder.png -------------------------------------------------------------------------------- /data/icons/256/simplescreenrecorder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/foxcpp/ssr-wlroots/HEAD/data/icons/256/simplescreenrecorder.png -------------------------------------------------------------------------------- /data/icons/32/simplescreenrecorder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/foxcpp/ssr-wlroots/HEAD/data/icons/32/simplescreenrecorder.png -------------------------------------------------------------------------------- /data/icons/48/simplescreenrecorder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/foxcpp/ssr-wlroots/HEAD/data/icons/48/simplescreenrecorder.png -------------------------------------------------------------------------------- /data/icons/64/simplescreenrecorder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/foxcpp/ssr-wlroots/HEAD/data/icons/64/simplescreenrecorder.png -------------------------------------------------------------------------------- /data/icons/96/simplescreenrecorder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/foxcpp/ssr-wlroots/HEAD/data/icons/96/simplescreenrecorder.png -------------------------------------------------------------------------------- /data/icons/128/simplescreenrecorder-idle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/foxcpp/ssr-wlroots/HEAD/data/icons/128/simplescreenrecorder-idle.png -------------------------------------------------------------------------------- /data/icons/16/simplescreenrecorder-error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/foxcpp/ssr-wlroots/HEAD/data/icons/16/simplescreenrecorder-error.png -------------------------------------------------------------------------------- /data/icons/16/simplescreenrecorder-idle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/foxcpp/ssr-wlroots/HEAD/data/icons/16/simplescreenrecorder-idle.png -------------------------------------------------------------------------------- /data/icons/192/simplescreenrecorder-idle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/foxcpp/ssr-wlroots/HEAD/data/icons/192/simplescreenrecorder-idle.png -------------------------------------------------------------------------------- /data/icons/22/simplescreenrecorder-error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/foxcpp/ssr-wlroots/HEAD/data/icons/22/simplescreenrecorder-error.png -------------------------------------------------------------------------------- /data/icons/22/simplescreenrecorder-idle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/foxcpp/ssr-wlroots/HEAD/data/icons/22/simplescreenrecorder-idle.png -------------------------------------------------------------------------------- /data/icons/24/simplescreenrecorder-error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/foxcpp/ssr-wlroots/HEAD/data/icons/24/simplescreenrecorder-error.png -------------------------------------------------------------------------------- /data/icons/24/simplescreenrecorder-idle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/foxcpp/ssr-wlroots/HEAD/data/icons/24/simplescreenrecorder-idle.png -------------------------------------------------------------------------------- /data/icons/256/simplescreenrecorder-idle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/foxcpp/ssr-wlroots/HEAD/data/icons/256/simplescreenrecorder-idle.png -------------------------------------------------------------------------------- /data/icons/32/simplescreenrecorder-error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/foxcpp/ssr-wlroots/HEAD/data/icons/32/simplescreenrecorder-error.png -------------------------------------------------------------------------------- /data/icons/32/simplescreenrecorder-idle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/foxcpp/ssr-wlroots/HEAD/data/icons/32/simplescreenrecorder-idle.png -------------------------------------------------------------------------------- /data/icons/48/simplescreenrecorder-error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/foxcpp/ssr-wlroots/HEAD/data/icons/48/simplescreenrecorder-error.png -------------------------------------------------------------------------------- /data/icons/48/simplescreenrecorder-idle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/foxcpp/ssr-wlroots/HEAD/data/icons/48/simplescreenrecorder-idle.png -------------------------------------------------------------------------------- /data/icons/64/simplescreenrecorder-error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/foxcpp/ssr-wlroots/HEAD/data/icons/64/simplescreenrecorder-error.png -------------------------------------------------------------------------------- /data/icons/64/simplescreenrecorder-idle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/foxcpp/ssr-wlroots/HEAD/data/icons/64/simplescreenrecorder-idle.png -------------------------------------------------------------------------------- /data/icons/96/simplescreenrecorder-error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/foxcpp/ssr-wlroots/HEAD/data/icons/96/simplescreenrecorder-error.png -------------------------------------------------------------------------------- /data/icons/96/simplescreenrecorder-idle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/foxcpp/ssr-wlroots/HEAD/data/icons/96/simplescreenrecorder-idle.png -------------------------------------------------------------------------------- /data/icons/128/simplescreenrecorder-error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/foxcpp/ssr-wlroots/HEAD/data/icons/128/simplescreenrecorder-error.png -------------------------------------------------------------------------------- /data/icons/128/simplescreenrecorder-paused.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/foxcpp/ssr-wlroots/HEAD/data/icons/128/simplescreenrecorder-paused.png -------------------------------------------------------------------------------- /data/icons/16/simplescreenrecorder-paused.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/foxcpp/ssr-wlroots/HEAD/data/icons/16/simplescreenrecorder-paused.png -------------------------------------------------------------------------------- /data/icons/192/simplescreenrecorder-error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/foxcpp/ssr-wlroots/HEAD/data/icons/192/simplescreenrecorder-error.png -------------------------------------------------------------------------------- /data/icons/192/simplescreenrecorder-paused.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/foxcpp/ssr-wlroots/HEAD/data/icons/192/simplescreenrecorder-paused.png -------------------------------------------------------------------------------- /data/icons/22/simplescreenrecorder-paused.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/foxcpp/ssr-wlroots/HEAD/data/icons/22/simplescreenrecorder-paused.png -------------------------------------------------------------------------------- /data/icons/24/simplescreenrecorder-paused.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/foxcpp/ssr-wlroots/HEAD/data/icons/24/simplescreenrecorder-paused.png -------------------------------------------------------------------------------- /data/icons/256/simplescreenrecorder-error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/foxcpp/ssr-wlroots/HEAD/data/icons/256/simplescreenrecorder-error.png -------------------------------------------------------------------------------- /data/icons/256/simplescreenrecorder-paused.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/foxcpp/ssr-wlroots/HEAD/data/icons/256/simplescreenrecorder-paused.png -------------------------------------------------------------------------------- /data/icons/32/simplescreenrecorder-paused.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/foxcpp/ssr-wlroots/HEAD/data/icons/32/simplescreenrecorder-paused.png -------------------------------------------------------------------------------- /data/icons/48/simplescreenrecorder-paused.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/foxcpp/ssr-wlroots/HEAD/data/icons/48/simplescreenrecorder-paused.png -------------------------------------------------------------------------------- /data/icons/64/simplescreenrecorder-paused.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/foxcpp/ssr-wlroots/HEAD/data/icons/64/simplescreenrecorder-paused.png -------------------------------------------------------------------------------- /data/icons/96/simplescreenrecorder-paused.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/foxcpp/ssr-wlroots/HEAD/data/icons/96/simplescreenrecorder-paused.png -------------------------------------------------------------------------------- /data/icons/128/simplescreenrecorder-recording.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/foxcpp/ssr-wlroots/HEAD/data/icons/128/simplescreenrecorder-recording.png -------------------------------------------------------------------------------- /data/icons/16/simplescreenrecorder-recording.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/foxcpp/ssr-wlroots/HEAD/data/icons/16/simplescreenrecorder-recording.png -------------------------------------------------------------------------------- /data/icons/192/simplescreenrecorder-recording.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/foxcpp/ssr-wlroots/HEAD/data/icons/192/simplescreenrecorder-recording.png -------------------------------------------------------------------------------- /data/icons/22/simplescreenrecorder-recording.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/foxcpp/ssr-wlroots/HEAD/data/icons/22/simplescreenrecorder-recording.png -------------------------------------------------------------------------------- /data/icons/24/simplescreenrecorder-recording.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/foxcpp/ssr-wlroots/HEAD/data/icons/24/simplescreenrecorder-recording.png -------------------------------------------------------------------------------- /data/icons/256/simplescreenrecorder-recording.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/foxcpp/ssr-wlroots/HEAD/data/icons/256/simplescreenrecorder-recording.png -------------------------------------------------------------------------------- /data/icons/32/simplescreenrecorder-recording.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/foxcpp/ssr-wlroots/HEAD/data/icons/32/simplescreenrecorder-recording.png -------------------------------------------------------------------------------- /data/icons/48/simplescreenrecorder-recording.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/foxcpp/ssr-wlroots/HEAD/data/icons/48/simplescreenrecorder-recording.png -------------------------------------------------------------------------------- /data/icons/64/simplescreenrecorder-recording.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/foxcpp/ssr-wlroots/HEAD/data/icons/64/simplescreenrecorder-recording.png -------------------------------------------------------------------------------- /data/icons/96/simplescreenrecorder-recording.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/foxcpp/ssr-wlroots/HEAD/data/icons/96/simplescreenrecorder-recording.png -------------------------------------------------------------------------------- /data/resources/resources.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | header.png 4 | about.htm 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/update-translations: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | cd "$( dirname "${BASH_SOURCE[0]}" )" 5 | 6 | cd translations 7 | lupdate-qt4 .. -ts @list.txt 8 | -------------------------------------------------------------------------------- /src/update-translations-clean: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | cd "$( dirname "${BASH_SOURCE[0]}" )" 5 | 6 | cd translations 7 | lupdate-qt4 .. -no-obsolete -ts @list.txt 8 | -------------------------------------------------------------------------------- /data/output-profiles/YouTube.conf: -------------------------------------------------------------------------------- 1 | [output] 2 | file= 3 | separate_files=true 4 | container=mkv 5 | video_codec=h264 6 | video_h264_crf=23 7 | video_h264_preset=1 8 | video_allow_frame_skipping=true 9 | audio_codec=vorbis 10 | audio_kbit_rate=128 11 | -------------------------------------------------------------------------------- /data/output-profiles/High%20Quality%20Intermediate.conf: -------------------------------------------------------------------------------- 1 | [output] 2 | file= 3 | separate_files=true 4 | container=mkv 5 | video_codec=other 6 | video_codec_av=libx264 7 | video_kbit_rate=0 8 | video_options="preset=superfast,crf=15,keyint=1" 9 | video_allow_frame_skipping=true 10 | audio_codec=uncompressed 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | *.so 3 | *.o 4 | *.lo 5 | *.la 6 | *.tar.gz 7 | *.user 8 | *.orig 9 | *.autosave 10 | *.qm 11 | qrc_* 12 | moc_* 13 | Makefile 14 | autom4te.cache 15 | config.h 16 | config.log 17 | config.status 18 | libtool 19 | .deps 20 | .libs 21 | .dirstamp 22 | stamp-h1 23 | 24 | build-* 25 | src/simplescreenrecorder 26 | 27 | private-* 28 | -------------------------------------------------------------------------------- /data/output-profiles/Live%20Stream%20%281000kbps%29.conf: -------------------------------------------------------------------------------- 1 | [output] 2 | file=rtmp:// 3 | separate_files=false 4 | container=other 5 | container_av=flv 6 | video_codec=other 7 | video_codec_av=libx264 8 | video_kbit_rate=1000 9 | video_options="preset=faster,minrate=1000,maxrate=1000,bufsize=1000,keyint=60" 10 | video_allow_frame_skipping=false 11 | audio_codec=mp3 12 | audio_kbit_rate=128 13 | -------------------------------------------------------------------------------- /data/output-profiles/Live%20Stream%20%282000kbps%29.conf: -------------------------------------------------------------------------------- 1 | [output] 2 | file=rtmp:// 3 | separate_files=false 4 | container=other 5 | container_av=flv 6 | video_codec=other 7 | video_codec_av=libx264 8 | video_kbit_rate=2000 9 | video_options="preset=faster,minrate=2000,maxrate=2000,bufsize=2000,keyint=60" 10 | video_allow_frame_skipping=false 11 | audio_codec=mp3 12 | audio_kbit_rate=128 13 | -------------------------------------------------------------------------------- /data/output-profiles/Live%20Stream%20%283000kbps%29.conf: -------------------------------------------------------------------------------- 1 | [output] 2 | file=rtmp:// 3 | separate_files=false 4 | container=other 5 | container_av=flv 6 | video_codec=other 7 | video_codec_av=libx264 8 | video_kbit_rate=3000 9 | video_options="preset=faster,minrate=3000,maxrate=3000,bufsize=3000,keyint=60" 10 | video_allow_frame_skipping=false 11 | audio_codec=mp3 12 | audio_kbit_rate=128 13 | -------------------------------------------------------------------------------- /postinstall: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # You should run this (as root) after installation/uninstallation to make sure the libraries, desktop entry and icon will be found. 3 | 4 | set -e 5 | cd "$( dirname "${BASH_SOURCE[0]}" )" 6 | 7 | if [ x"$( whoami )" != x"root" ]; then 8 | echo "Error: postinstall should be run as root" 9 | exit 1 10 | fi 11 | 12 | ldconfig 13 | update-desktop-database -q 14 | gtk-update-icon-cache -q -t -f /usr/share/icons/hicolor || true 15 | -------------------------------------------------------------------------------- /glinject/GLInject.pro: -------------------------------------------------------------------------------- 1 | # Don't try to compile this with qmake! This file is only meant for Qt Creator, not for actual compilation. 2 | 3 | QT += core gui 4 | 5 | TARGET = GLInject 6 | TEMPLATE = app 7 | 8 | QMAKE_CXXFLAGS += -std=c++0x 9 | LIBS += -rt -ldl -lGL -lGLU -lX11 -lXfixes 10 | 11 | SOURCES += \ 12 | elfhacks.c \ 13 | GLInject.cpp \ 14 | GLXFrameGrabber.cpp \ 15 | Hook.cpp \ 16 | SSRVideoStreamWriter.cpp 17 | 18 | HEADERS += \ 19 | elfhacks.h \ 20 | GLInject.h \ 21 | Global.h \ 22 | GLXFrameGrabber.h \ 23 | ShmStructs.h \ 24 | SSRVideoStreamWriter.h 25 | -------------------------------------------------------------------------------- /data/simplescreenrecorder.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Type=Application 3 | Name=SimpleScreenRecorder 4 | Comment=A feature-rich screen recorder that supports X11 and OpenGL 5 | Comment[fr]=Un captureur d'écran complet qui supporte X11 et OpenGL 6 | Comment[id]=Perekam layar kaya fitur yang mendukung X11 dan OpenGL 7 | Comment[lt]=Funkcionali ekrano įrašymo programa, palaikanti X11 ir OpenGL 8 | Icon=simplescreenrecorder 9 | Exec=simplescreenrecorder --logfile 10 | Terminal=false 11 | Categories=AudioVideo;Video;Recorder;Qt; 12 | Keywords=screen recorder;screencast;live streaming;ssr; 13 | -------------------------------------------------------------------------------- /cmake/FindJack.cmake: -------------------------------------------------------------------------------- 1 | # rules for finding the Jack library 2 | 3 | find_package(PkgConfig REQUIRED) 4 | pkg_check_modules(PC_JACK jack) 5 | 6 | find_path(JACK_INCLUDE_DIR jack/jack.h HINTS ${PC_JACK_INCLUDEDIR} ${PC_JACK_INCLUDE_DIRS}) 7 | find_library(JACK_LIBRARY NAMES jack HINTS ${PC_JACK_LIBDIR} ${PC_JACK_LIBRARY_DIRS}) 8 | 9 | include(FindPackageHandleStandardArgs) 10 | find_package_handle_standard_args(Jack DEFAULT_MSG JACK_LIBRARY JACK_INCLUDE_DIR) 11 | 12 | mark_as_advanced(JACK_INCLUDE_DIR JACK_LIBRARY) 13 | 14 | set(JACK_INCLUDE_DIRS ${JACK_INCLUDE_DIR}) 15 | set(JACK_LIBRARIES ${JACK_LIBRARY}) 16 | -------------------------------------------------------------------------------- /simple-uninstall: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Run this if you used 'simple-build-and-install' and you want to uninstall the program again. 3 | 4 | set -e 5 | cd "$( dirname "${BASH_SOURCE[0]}" )" 6 | 7 | if [ x"$( whoami )" = x"root" ]; then 8 | echo "Error: don't run this script as root, this will mess up file permissions" 9 | exit 1 10 | fi 11 | 12 | echo "Entering build-release directory ..." 13 | cd build-release 14 | 15 | echo "Uninstalling ..." 16 | sudo xargs rm < install_manifest.txt 17 | 18 | echo "Leaving build-release directory ..." 19 | cd .. 20 | 21 | echo "Running post-install script ..." 22 | sudo ./postinstall 23 | 24 | echo "Done." 25 | -------------------------------------------------------------------------------- /src/translations/list.txt: -------------------------------------------------------------------------------- 1 | simplescreenrecorder_ar.ts 2 | simplescreenrecorder_bg.ts 3 | simplescreenrecorder_cs.ts 4 | simplescreenrecorder_de.ts 5 | simplescreenrecorder_el.ts 6 | simplescreenrecorder_es.ts 7 | simplescreenrecorder_fr.ts 8 | simplescreenrecorder_he.ts 9 | simplescreenrecorder_hu.ts 10 | simplescreenrecorder_id.ts 11 | simplescreenrecorder_it.ts 12 | simplescreenrecorder_ja.ts 13 | simplescreenrecorder_lt.ts 14 | simplescreenrecorder_nl.ts 15 | simplescreenrecorder_pl.ts 16 | simplescreenrecorder_pt_BR.ts 17 | simplescreenrecorder_ru.ts 18 | simplescreenrecorder_sr.ts 19 | simplescreenrecorder_sv.ts 20 | simplescreenrecorder_uk.ts 21 | simplescreenrecorder_zh_CN.ts 22 | simplescreenrecorder_zh_TW.ts 23 | -------------------------------------------------------------------------------- /cmake/FindPulseAudio.cmake: -------------------------------------------------------------------------------- 1 | # rules for finding the PulseAudio library 2 | 3 | find_package(PkgConfig REQUIRED) 4 | pkg_check_modules(PC_PULSEAUDIO libpulse) 5 | 6 | find_path(PULSEAUDIO_INCLUDE_DIR pulse/pulseaudio.h HINTS ${PC_PULSEAUDIO_INCLUDEDIR} ${PC_PULSEAUDIO_INCLUDE_DIRS}) 7 | find_library(PULSEAUDIO_LIBRARY NAMES pulse HINTS ${PC_PULSEAUDIO_LIBDIR} ${PC_PULSEAUDIO_LIBRARY_DIRS}) 8 | 9 | include(FindPackageHandleStandardArgs) 10 | find_package_handle_standard_args(PulseAudio DEFAULT_MSG PULSEAUDIO_LIBRARY PULSEAUDIO_INCLUDE_DIR) 11 | 12 | mark_as_advanced(PULSEAUDIO_INCLUDE_DIR PULSEAUDIO_LIBRARY) 13 | 14 | set(PULSEAUDIO_INCLUDE_DIRS ${PULSEAUDIO_INCLUDE_DIR}) 15 | set(PULSEAUDIO_LIBRARIES ${PULSEAUDIO_LIBRARY}) 16 | -------------------------------------------------------------------------------- /src/AV/Output/X264Presets.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Global.h" 3 | 4 | // This file was generated by 'x264-preset-translator.php', don't edit it. 5 | 6 | #if !SSR_USE_AVCODEC_PRIVATE_PRESET 7 | 8 | void X264Preset(AVCodecContext* cc, const char* preset); 9 | 10 | void X264Preset_ultrafast(AVCodecContext* cc); 11 | void X264Preset_superfast(AVCodecContext* cc); 12 | void X264Preset_veryfast(AVCodecContext* cc); 13 | void X264Preset_faster(AVCodecContext* cc); 14 | void X264Preset_fast(AVCodecContext* cc); 15 | void X264Preset_medium(AVCodecContext* cc); 16 | void X264Preset_slow(AVCodecContext* cc); 17 | void X264Preset_slower(AVCodecContext* cc); 18 | void X264Preset_veryslow(AVCodecContext* cc); 19 | void X264Preset_placebo(AVCodecContext* cc); 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /src/Benchmark.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2017 Maarten Baert 3 | 4 | This file is part of SimpleScreenRecorder. 5 | 6 | SimpleScreenRecorder is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | SimpleScreenRecorder is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with SimpleScreenRecorder. If not, see . 18 | */ 19 | 20 | #pragma once 21 | #include "Global.h" 22 | 23 | void Benchmark(); 24 | -------------------------------------------------------------------------------- /src/NVidia.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2017 Maarten Baert 3 | 4 | This file is part of SimpleScreenRecorder. 5 | 6 | SimpleScreenRecorder is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | SimpleScreenRecorder is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with SimpleScreenRecorder. If not, see . 18 | */ 19 | 20 | #pragma once 21 | #include "Global.h" 22 | 23 | bool NVidiaGetFlipping(); 24 | bool NVidiaSetFlipping(bool enable); 25 | -------------------------------------------------------------------------------- /cmake/FindWaylandProtocols.cmake: -------------------------------------------------------------------------------- 1 | find_package(PkgConfig) 2 | 3 | pkg_check_modules(WaylandProtocols QUIET wayland-protocols>=${WaylandProtocols_FIND_VERSION}) 4 | 5 | execute_process(COMMAND ${PKG_CONFIG_EXECUTABLE} --variable=pkgdatadir wayland-protocols 6 | OUTPUT_VARIABLE WaylandProtocols_PKGDATADIR 7 | RESULT_VARIABLE _pkgconfig_failed) 8 | if (_pkgconfig_failed) 9 | message(FATAL_ERROR "Missing wayland-protocols pkgdatadir") 10 | endif() 11 | 12 | string(REGEX REPLACE "[\r\n]" "" WaylandProtocols_PKGDATADIR "${WaylandProtocols_PKGDATADIR}") 13 | 14 | find_package_handle_standard_args(WaylandProtocols 15 | FOUND_VAR 16 | WaylandProtocols_FOUND 17 | REQUIRED_VARS 18 | WaylandProtocols_PKGDATADIR 19 | VERSION_VAR 20 | WaylandProtocols_VERSION 21 | HANDLE_COMPONENTS 22 | ) 23 | 24 | set(WAYLAND_PROTOCOLS_FOUND ${WaylandProtocols_FOUND}) 25 | set(WAYLAND_PROTOCOLS_PKGDATADIR ${WaylandProtocols_PKGDATADIR}) 26 | set(WAYLAND_PROTOCOLS_VERSION ${WaylandProtocols_VERSION}) 27 | -------------------------------------------------------------------------------- /src/GUI/PageDone.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2017 Maarten Baert 3 | 4 | This file is part of SimpleScreenRecorder. 5 | 6 | SimpleScreenRecorder is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | SimpleScreenRecorder is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with SimpleScreenRecorder. If not, see . 18 | */ 19 | 20 | #pragma once 21 | #include "Global.h" 22 | 23 | class MainWindow; 24 | 25 | class PageDone : public QWidget { 26 | Q_OBJECT 27 | 28 | private: 29 | MainWindow *m_main_window; 30 | 31 | public: 32 | PageDone(MainWindow* main_window); 33 | 34 | }; 35 | -------------------------------------------------------------------------------- /src/GUI/Icons.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2017 Maarten Baert 3 | 4 | This file is part of SimpleScreenRecorder. 5 | 6 | SimpleScreenRecorder is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | SimpleScreenRecorder is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with SimpleScreenRecorder. If not, see . 18 | */ 19 | 20 | #pragma once 21 | #include "Global.h" 22 | 23 | extern QIcon g_icon_ssr, g_icon_ssr_idle, g_icon_ssr_error, g_icon_ssr_paused, g_icon_ssr_recording; 24 | extern QIcon g_icon_go_home, g_icon_go_previous, g_icon_go_next; 25 | extern QIcon g_icon_pause, g_icon_record; 26 | extern QIcon g_icon_cancel, g_icon_save, g_icon_quit; 27 | extern QIcon g_icon_microphone; 28 | 29 | void LoadIcons(); 30 | -------------------------------------------------------------------------------- /AUTHORS.md: -------------------------------------------------------------------------------- 1 | SimpleScreenRecorder contributors 2 | ================================= 3 | 4 | Programming 5 | ----------- 6 | 7 | - Maarten Baert 8 | - Boran Car (GLInject hotkey workaround) 9 | - Dubslow (profiles) 10 | - Dmitry Kostenko ('simpleui' patches) 11 | 12 | Graphics 13 | -------- 14 | 15 | - David Revoy (icon) 16 | - Mrallowski (original camera lens from openclipart.org) 17 | - Maarten Baert (header) 18 | 19 | Build system 20 | ------------ 21 | 22 | - Maarten Baert 23 | - Michał Walenciak (switch to cmake) 24 | 25 | Translations 26 | ------------ 27 | 28 | - Arabic: Abdulla 29 | - Bulgarian: Svetoslav Sashkov 30 | - Czech: Radek Steiger 31 | - German: Manuel Schömburg, AlexMI 32 | - Greek: Nick Thom 33 | - Spanish: Dani Rodríguez 34 | - French: Mario Roger 35 | - Hebrew: GreenLunar 36 | - Hungarian: ViBE, Balázs Úr 37 | - Indonesian: Arif Budiman 38 | - Italian: Bersil 39 | - Japanese: Tou Omiya 40 | - Lithuanian: welaq 41 | - Dutch: Maarten Baert 42 | - Polish: Szamanx0, Vetyt Yhonay, Michał Walenciak 43 | - Brazilian Portuguese: Paulo Milliet Roque, Rafael Ferreira 44 | - Russian: Dima Koshel 45 | - Swedish: Åke Engelbrektson 46 | - Ukrainian: Rom Gyrfalco 47 | - Simplified Chinese: Weitian Leung 48 | - Traditional Chinese: Estea Chen 49 | -------------------------------------------------------------------------------- /src/AV/Input/SSRVideoStream.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2017 Maarten Baert 3 | 4 | This file is part of SimpleScreenRecorder. 5 | 6 | SimpleScreenRecorder is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | SimpleScreenRecorder is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with SimpleScreenRecorder. If not, see . 18 | */ 19 | 20 | #pragma once 21 | #include "Global.h" 22 | 23 | struct SSRVideoStream { 24 | std::string m_stream_name; 25 | int64_t m_creation_time; 26 | unsigned int m_process_id; 27 | inline bool operator==(const SSRVideoStream& other) const { 28 | return (m_stream_name == other.m_stream_name); 29 | } 30 | inline bool operator<(const SSRVideoStream& other) const { 31 | return (m_creation_time < other.m_creation_time); 32 | } 33 | }; 34 | -------------------------------------------------------------------------------- /src/GUI/PageWelcome.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2017 Maarten Baert 3 | 4 | This file is part of SimpleScreenRecorder. 5 | 6 | SimpleScreenRecorder is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | SimpleScreenRecorder is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with SimpleScreenRecorder. If not, see . 18 | */ 19 | 20 | #pragma once 21 | #include "Global.h" 22 | 23 | class MainWindow; 24 | 25 | class PageWelcome : public QWidget { 26 | Q_OBJECT 27 | 28 | private: 29 | MainWindow *m_main_window; 30 | 31 | public: 32 | PageWelcome(MainWindow* main_window); 33 | 34 | private slots: 35 | void AboutDialog(); 36 | 37 | }; 38 | 39 | class DialogAbout : public QDialog { 40 | Q_OBJECT 41 | 42 | private: 43 | 44 | public: 45 | DialogAbout(PageWelcome* parent); 46 | 47 | }; 48 | -------------------------------------------------------------------------------- /src/Main.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2017 Maarten Baert 3 | 4 | This file is part of SimpleScreenRecorder. 5 | 6 | SimpleScreenRecorder is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | SimpleScreenRecorder is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with SimpleScreenRecorder. If not, see . 18 | */ 19 | 20 | #pragma once 21 | #include "Global.h" 22 | 23 | extern bool g_option_logfile; 24 | extern QString g_option_statsfile; 25 | extern bool g_option_syncdiagram; 26 | extern bool g_option_systray; 27 | extern bool g_option_start_hidden; 28 | 29 | QString GetApplicationSystemDir(const QString& subdir = QString()); 30 | QString GetApplicationUserDir(const QString& subdir = QString()); 31 | QString GetVersionInfo(); 32 | 33 | bool NVidiaGetFlipping(); 34 | bool NVidiaDisableFlipping(); 35 | -------------------------------------------------------------------------------- /src/AV/FastScaler_Scale.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2017 Maarten Baert 3 | 4 | This file is part of SimpleScreenRecorder. 5 | 6 | SimpleScreenRecorder is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | SimpleScreenRecorder is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with SimpleScreenRecorder. If not, see . 18 | */ 19 | 20 | #pragma once 21 | #include "Global.h" 22 | 23 | void Scale_BGRA_Fallback(unsigned int in_w, unsigned int in_h, const uint8_t* in_data, int in_stride, 24 | unsigned int out_w, unsigned int out_h, uint8_t* out_data, int out_stride); 25 | 26 | #if SSR_USE_X86_ASM 27 | void Scale_BGRA_SSSE3(unsigned int in_w, unsigned int in_h, const uint8_t* in_data, int in_stride, 28 | unsigned int out_w, unsigned int out_h, uint8_t* out_data, int out_stride); 29 | #endif 30 | -------------------------------------------------------------------------------- /src/GUI/HiddenScrollArea.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2017 Maarten Baert 3 | 4 | This file is part of SimpleScreenRecorder. 5 | 6 | SimpleScreenRecorder is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | SimpleScreenRecorder is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with SimpleScreenRecorder. If not, see . 18 | */ 19 | 20 | #include "HiddenScrollArea.h" 21 | 22 | HiddenScrollArea::HiddenScrollArea(QWidget* parent) : QScrollArea(parent) { 23 | setWidgetResizable(true); 24 | setFrameShape(QFrame::NoFrame); 25 | } 26 | 27 | HiddenScrollArea::~HiddenScrollArea() { 28 | // nothing 29 | } 30 | 31 | QSize HiddenScrollArea::sizeHint() const { 32 | return widget()->sizeHint(); 33 | } 34 | 35 | QSize HiddenScrollArea::minimumSizeHint() const { 36 | return widget()->minimumSizeHint(); 37 | } 38 | -------------------------------------------------------------------------------- /src/translations/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # translations for 'simplescreenrecorder' executable 2 | 3 | find_program(LRELEASE lrelease) 4 | 5 | if(LRELEASE) 6 | 7 | set(translations 8 | ar 9 | bg 10 | cs 11 | de 12 | el 13 | es 14 | fr 15 | he 16 | hu 17 | id 18 | it 19 | ja 20 | lt 21 | nl 22 | pl 23 | pt_BR 24 | ru 25 | sr 26 | sv 27 | uk 28 | zh_CN 29 | zh_TW 30 | ) 31 | 32 | set(qm_files) 33 | 34 | foreach(tr IN LISTS translations) 35 | 36 | # qm generation rules 37 | add_custom_command( 38 | OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/simplescreenrecorder_${tr}.qm 39 | COMMAND ${LRELEASE} -silent ${PROJECT_SOURCE_DIR}/src/translations/simplescreenrecorder_${tr}.ts -qm ${CMAKE_CURRENT_BINARY_DIR}/simplescreenrecorder_${tr}.qm 40 | DEPENDS ${PROJECT_SOURCE_DIR}/src/translations/simplescreenrecorder_${tr}.ts 41 | ) 42 | 43 | # installation rules 44 | install( 45 | FILES ${CMAKE_CURRENT_BINARY_DIR}/simplescreenrecorder_${tr}.qm 46 | DESTINATION ${CMAKE_INSTALL_FULL_DATADIR}/simplescreenrecorder/translations 47 | ) 48 | 49 | # remember qm files 50 | list(APPEND qm_files 51 | ${CMAKE_CURRENT_BINARY_DIR}/simplescreenrecorder_${tr}.qm 52 | ) 53 | 54 | endforeach() 55 | 56 | # main target 57 | add_custom_target(translations ALL 58 | DEPENDS ${qm_files} 59 | ) 60 | 61 | endif() 62 | -------------------------------------------------------------------------------- /todo.txt: -------------------------------------------------------------------------------- 1 | Testing: 2 | - New GLInject implementation. 3 | - Refactored output backend. 4 | - Input + output profiles. 5 | 6 | In progress: 7 | 8 | Todo: 9 | - Highlight mouse clicks (optional) [https://github.com/MaartenBaert/ssr/issues/10] 10 | - Command-line options for recording + skipping pages + systray. 11 | - Multiple audio inputs/outputs. 12 | - X11Input should track resolution changes. 13 | - Show recorded area while recording. 14 | - Check disk space (Muxer). 15 | - Record active monitor [https://github.com/MaartenBaert/ssr/issues/337] 16 | - Add shadowplay-like functionality 17 | 18 | Wishlist: 19 | - Improve interface for small screens. 20 | - FPS counter of GLInject. (overlay + option to record?) 21 | - Built-in re-encoding after recording. 22 | - clean up Global.h 23 | - Easier GLInject application selection (as an alternative to entering the command). 24 | - Timelapse recording, i.e. recording at a slow speed but playing it back faster (without sound obviously). 25 | - Cursor highlighting. 26 | - Webcam support (V4L2 input) 27 | 28 | Not sure yet: 29 | - Fixed cursor position when using 'follow cursor'? 30 | - redesigned interface? (https://github.com/swick/glc2/issues/1) 31 | - audio effects (equalizer, noise gate, duck)? 32 | - if possible, force fixed size on OpenGL applications? (optional of course) 33 | - Planar sample/pixel formats for inputs (source/sink). (why?) 34 | -------------------------------------------------------------------------------- /src/GUI/HiddenScrollArea.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2017 Maarten Baert 3 | 4 | This file is part of SimpleScreenRecorder. 5 | 6 | SimpleScreenRecorder is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | SimpleScreenRecorder is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with SimpleScreenRecorder. If not, see . 18 | */ 19 | 20 | #pragma once 21 | #include "Global.h" 22 | 23 | // A scroll area that tries to stay invisible if possible. The goal is to keep SSR functional even when the screen 24 | // resolution is too small to show the full GUI, but without affecting the behaviour under normal conditions. 25 | class HiddenScrollArea : public QScrollArea { 26 | Q_OBJECT 27 | 28 | public: 29 | HiddenScrollArea(QWidget* parent); 30 | ~HiddenScrollArea(); 31 | 32 | virtual QSize sizeHint() const override; 33 | virtual QSize minimumSizeHint() const override; 34 | 35 | }; 36 | -------------------------------------------------------------------------------- /data/man/ssr-glinject.1: -------------------------------------------------------------------------------- 1 | .TH SSR-GLINJECT "1" "March 2015" "SimpleScreenRecorder" "User Commands" 2 | .SH NAME 3 | ssr-glinject \- Run a command while injecting the SimpleScreenRecorder GLInject library. 4 | .SH SYNOPSIS 5 | .B ssr-glinject 6 | [\fI\,OPTIONS\/\fR] [\fI\,--\/\fR] \fI\,COMMAND\/\fR 7 | .SH DESCRIPTION 8 | This script uses LD_PRELOAD to inject the GLInject library into the given 9 | command, so that SimpleScreenRecorder can record it. It should be safe to use 10 | this on all applications (including command-line programs and shell scripts). 11 | If the program doesn't use OpenGL, it should have no effect. If you find a 12 | program that crashes or behaves incorrectly when GLInject is used, please submit 13 | a bug report. 14 | .SH OPTIONS 15 | .TP 16 | \fB\-\-help\fR 17 | Show help message. 18 | .TP 19 | \fB\-\-glx\-debug\fR 20 | Enables GLX debugging. This may reduce the performance 21 | and print lots of error messages, but it is useful to 22 | track down bugs. 23 | .TP 24 | \fB\-\-relax\-permissions\fR 25 | Uses mode 666 instead of 600 for shared memory, so that 26 | other users can record the stream. This is insecure and 27 | should not be used on a computer that can be accessed by 28 | other users that you don't trust. 29 | .TP 30 | \fB\-\-channel\fR=\fI\,CHANNEL\/\fR 31 | Channel name to use. The default is 'channel\-USERNAME'. 32 | .SH "SEE ALSO" 33 | More documentation can be found at 34 | \%http://www.maartenbaert.be/simplescreenrecorder/. 35 | -------------------------------------------------------------------------------- /glinject/GLInject.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2017 Maarten Baert 3 | 4 | Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. 5 | 6 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 7 | */ 8 | 9 | #pragma once 10 | #include "Global.h" 11 | 12 | #include 13 | #include 14 | 15 | class GLXFrameGrabber; 16 | 17 | class GLInject { 18 | 19 | public: 20 | 21 | private: 22 | std::vector m_glx_frame_grabbers; 23 | 24 | public: 25 | GLInject(); 26 | ~GLInject(); 27 | 28 | GLXFrameGrabber* NewGLXFrameGrabber(Display* display, Window window, GLXDrawable drawable); 29 | GLXFrameGrabber* FindGLXFrameGrabber(Display* display, GLXDrawable drawable); 30 | void DeleteGLXFrameGrabberByWindow(Display* display, Window window); 31 | void DeleteGLXFrameGrabberByDrawable(Display* display, GLXDrawable drawable); 32 | 33 | }; 34 | -------------------------------------------------------------------------------- /src/common/MutexDataPair.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2017 Maarten Baert 3 | 4 | This file is part of SimpleScreenRecorder. 5 | 6 | SimpleScreenRecorder is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | SimpleScreenRecorder is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with SimpleScreenRecorder. If not, see . 18 | */ 19 | 20 | #pragma once 21 | #include "Global.h" 22 | 23 | template 24 | class MutexDataPair { 25 | 26 | public: 27 | class Lock { 28 | private: 29 | std::unique_lock m_lock; 30 | T *m_data; 31 | public: 32 | inline Lock(MutexDataPair* parent) : m_lock(parent->m_mutex), m_data(&parent->m_data) {} 33 | inline T* operator->() { return m_data; } 34 | inline T* get() { return m_data; } 35 | inline std::unique_lock& lock() { return m_lock; } 36 | }; 37 | 38 | private: 39 | std::mutex m_mutex; 40 | T m_data; 41 | 42 | public: 43 | inline T* data() { return &m_data; } // useful in some rare cases (e.g. callback functions) 44 | 45 | }; 46 | -------------------------------------------------------------------------------- /glinject/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 'libssr-glinject' library 2 | 3 | find_package(Threads REQUIRED) 4 | find_package(X11 REQUIRED) 5 | find_package(OpenGL REQUIRED) 6 | 7 | set(sources 8 | elfhacks.c 9 | elfhacks.h 10 | GLInject.cpp 11 | GLInject.h 12 | Global.h 13 | GLXFrameGrabber.cpp 14 | GLXFrameGrabber.h 15 | Hook.cpp 16 | ShmStructs.h 17 | SSRVideoStreamWriter.cpp 18 | SSRVideoStreamWriter.h 19 | ) 20 | 21 | set(include_directories 22 | ${X11_X11_INCLUDE_PATH} 23 | ${X11_Xfixes_INCLUDE_PATH} 24 | ${OPENGL_INCLUDE_DIR} 25 | ) 26 | 27 | set(link_libraries 28 | ${CMAKE_THREAD_LIBS_INIT} 29 | ${X11_X11_LIB} 30 | ${X11_Xfixes_LIB} 31 | ${OPENGL_LIBRARIES} 32 | -lrt 33 | ${CMAKE_DL_LIBS} 34 | ) 35 | 36 | add_library(ssr-glinject SHARED ${sources}) 37 | target_include_directories(ssr-glinject PRIVATE ${include_directories}) 38 | target_link_libraries(ssr-glinject PRIVATE ${link_libraries}) 39 | install(TARGETS ssr-glinject LIBRARY DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR}) 40 | 41 | if(ENABLE_32BIT_GLINJECT) 42 | 43 | add_library(ssr-glinject32 SHARED ${sources}) 44 | target_include_directories(ssr-glinject32 PRIVATE ${include_directories}) 45 | target_link_libraries(ssr-glinject32 PRIVATE ${link_libraries}) 46 | install(TARGETS ssr-glinject32 LIBRARY DESTINATION ${CMAKE_INSTALL_FULL_LIB32DIR}) 47 | 48 | set_target_properties(ssr-glinject32 PROPERTIES COMPILE_FLAGS -m32 LINK_FLAGS -m32) 49 | set_target_properties(ssr-glinject32 PROPERTIES OUTPUT_NAME ssr-glinject LIBRARY_OUTPUT_DIRECTORY "lib32") 50 | 51 | endif() 52 | -------------------------------------------------------------------------------- /src/NVidia.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2017 Maarten Baert 3 | 4 | This file is part of SimpleScreenRecorder. 5 | 6 | SimpleScreenRecorder is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | SimpleScreenRecorder is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with SimpleScreenRecorder. If not, see . 18 | */ 19 | 20 | #include "NVidia.h" 21 | 22 | bool NVidiaGetFlipping() { 23 | QString program = "nvidia-settings"; 24 | QStringList args; 25 | args << "-tq" << "AllowFlipping"; 26 | QProcess p; 27 | p.start(program, args); 28 | p.waitForFinished(); 29 | if(p.exitCode() != 0) 30 | return false; 31 | QString result = p.readAll(); 32 | return (result.trimmed() == "1"); 33 | } 34 | 35 | bool NVidiaSetFlipping(bool enable) { 36 | QString program = "nvidia-settings"; 37 | QStringList args; 38 | args << "-a" << ((enable)? "AllowFlipping=1" : "AllowFlipping=0"); 39 | QProcess p; 40 | p.start(program, args); 41 | p.waitForFinished(); 42 | if(p.exitCode() != 0) 43 | return false; 44 | return (NVidiaGetFlipping() == enable); 45 | } 46 | -------------------------------------------------------------------------------- /src/GUI/DialogGLInject.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2013 Maarten Baert 3 | 4 | This file is part of SimpleScreenRecorder. 5 | 6 | SimpleScreenRecorder is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | SimpleScreenRecorder is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with SimpleScreenRecorder. If not, see . 18 | */ 19 | 20 | #pragma once 21 | #include "Global.h" 22 | 23 | #if SSR_USE_OPENGL_RECORDING 24 | 25 | class SSRVideoStream; 26 | class SSRVideoStreamWatcher; 27 | 28 | class PageInput; 29 | 30 | class DialogGLInject : public QDialog { 31 | Q_OBJECT 32 | 33 | private: 34 | PageInput *m_parent; 35 | 36 | QLineEdit *m_lineedit_channel; 37 | QCheckBox *m_checkbox_relax_permissions; 38 | 39 | QLineEdit *m_lineedit_command, *m_lineedit_working_directory; 40 | QCheckBox *m_checkbox_auto_launch; 41 | 42 | QCheckBox *m_checkbox_limit_fps; 43 | 44 | public: 45 | DialogGLInject(PageInput* parent); 46 | ~DialogGLInject(); 47 | 48 | private slots: 49 | void OnWriteBack(); 50 | void OnLaunchNow(); 51 | 52 | }; 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /src/common/Logger.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2017 Maarten Baert 3 | 4 | This file is part of SimpleScreenRecorder. 5 | 6 | SimpleScreenRecorder is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | SimpleScreenRecorder is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with SimpleScreenRecorder. If not, see . 18 | */ 19 | 20 | #pragma once 21 | #include "Global.h" 22 | 23 | class Logger : public QObject { 24 | Q_OBJECT 25 | 26 | public: 27 | enum enum_type { 28 | TYPE_INFO, 29 | TYPE_WARNING, 30 | TYPE_ERROR 31 | }; 32 | 33 | private: 34 | std::mutex m_mutex; 35 | 36 | static Logger *s_instance; 37 | 38 | public: 39 | Logger(); 40 | ~Logger(); 41 | 42 | // These functions are thread-safe. 43 | static void LogInfo(const QString& str); 44 | static void LogWarning(const QString& str); 45 | static void LogError(const QString& str); 46 | 47 | inline static Logger* GetInstance() { assert(s_instance != NULL); return s_instance; } 48 | 49 | signals: 50 | void NewLine(Logger::enum_type type, QString str); 51 | 52 | }; 53 | 54 | Q_DECLARE_METATYPE(Logger::enum_type) 55 | -------------------------------------------------------------------------------- /src/common/Dialogs.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2017 Maarten Baert 3 | 4 | This file is part of SimpleScreenRecorder. 5 | 6 | SimpleScreenRecorder is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | SimpleScreenRecorder is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with SimpleScreenRecorder. If not, see . 18 | */ 19 | 20 | #pragma once 21 | #include "Global.h" 22 | 23 | // Buttons that can be used with the MessageBox function. 24 | enum enum_button : int { 25 | BUTTON_NONE = 0x0000, 26 | BUTTON_OK = 0x0001, 27 | BUTTON_CANCEL = 0x0002, 28 | BUTTON_YES = 0x0004, 29 | BUTTON_YES_ALWAYS = 0x0008, 30 | BUTTON_NO = 0x0010, 31 | BUTTON_NO_NEVER = 0x0020, 32 | }; 33 | 34 | // Shows a standard Qt dialog with translated buttons. 35 | enum_button MessageBox(QMessageBox::Icon icon, QWidget* parent, const QString& title, const QString& text, int buttons = BUTTON_OK, enum_button default_button = BUTTON_NONE); 36 | 37 | // Shows a simple dialog that asks the user to enter a string. 38 | QString InputBox(QWidget* parent, const QString& title, const QString& text, const QString& value); 39 | -------------------------------------------------------------------------------- /glinject/GLXFrameGrabber.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2017 Maarten Baert 3 | 4 | Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. 5 | 6 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 7 | */ 8 | 9 | #pragma once 10 | #include "Global.h" 11 | 12 | #include "SSRVideoStreamWriter.h" 13 | 14 | #include 15 | #include 16 | 17 | class GLXFrameGrabber { 18 | 19 | private: 20 | unsigned int m_id; 21 | Display *m_x11_display; 22 | Window m_x11_window; 23 | GLXDrawable m_glx_drawable; 24 | 25 | unsigned int m_gl_version; 26 | bool m_debug, m_has_xfixes; 27 | bool m_warn_too_small, m_warn_too_large; 28 | 29 | SSRVideoStreamWriter *m_stream_writer; 30 | 31 | public: 32 | GLXFrameGrabber(Display* display, Window window, GLXDrawable drawable); 33 | ~GLXFrameGrabber(); 34 | 35 | private: 36 | void Init(); 37 | void Free(); 38 | 39 | public: 40 | void GrabFrame(); 41 | 42 | public: 43 | inline Display* GetX11Display() { return m_x11_display; } 44 | inline Window GetX11Window() { return m_x11_window; } 45 | inline GLXDrawable GetGLXDrawable() { return m_glx_drawable; } 46 | 47 | }; 48 | -------------------------------------------------------------------------------- /src/GUI/PageDone.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2017 Maarten Baert 3 | 4 | This file is part of SimpleScreenRecorder. 5 | 6 | SimpleScreenRecorder is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | SimpleScreenRecorder is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with SimpleScreenRecorder. If not, see . 18 | */ 19 | 20 | #include "PageDone.h" 21 | 22 | #include "Icons.h" 23 | #include "MainWindow.h" 24 | 25 | PageDone::PageDone(MainWindow* main_window) 26 | : QWidget(main_window->centralWidget()) { 27 | 28 | m_main_window = main_window; 29 | 30 | QLabel *label_done = new QLabel(tr("The recording has been saved. You can edit the video now, or re-encode it with better settings to " 31 | "make the file smaller (the default settings are optimized for quality and speed, not file size)."), this); 32 | label_done->setWordWrap(true); 33 | QPushButton *button_back = new QPushButton(g_icon_go_home, tr("Back to the start screen"), this); 34 | 35 | connect(button_back, SIGNAL(clicked()), m_main_window, SLOT(GoPageWelcome())); 36 | 37 | QVBoxLayout *layout_page = new QVBoxLayout(this); 38 | layout_page->addWidget(label_done); 39 | layout_page->addStretch(); 40 | layout_page->addWidget(button_back); 41 | 42 | } 43 | -------------------------------------------------------------------------------- /cmake/WaylandScanner.cmake: -------------------------------------------------------------------------------- 1 | 2 | find_package(PkgConfig REQUIRED) 3 | pkg_check_modules(WAYLAND_CLIENT wayland-client>=1.13.0 REQUIRED) 4 | 5 | find_program(WAYLAND_SCANNER_EXE NAMES wayland-scanner) 6 | 7 | function(wayland_generate_proto PATH) 8 | get_filename_component(FILENAME ${PATH} NAME) 9 | string(REGEX REPLACE "\\.[^.]*$" "" FILENAME_NOEXT ${FILENAME}) 10 | 11 | add_custom_command( 12 | OUTPUT ${FILENAME_NOEXT}-client-protocol.h 13 | COMMAND ${WAYLAND_SCANNER_EXE} client-header 14 | < ${PATH} 15 | > ${CMAKE_CURRENT_BINARY_DIR}/${FILENAME_NOEXT}-client-protocol.h 16 | DEPENDS ${PATH} 17 | COMMENT "Generating ${FILENAME_NOEXT} protocol header" 18 | ) 19 | add_custom_command( 20 | OUTPUT ${FILENAME_NOEXT}-protocol.c 21 | COMMAND ${WAYLAND_SCANNER_EXE} private-code 22 | < ${PATH} 23 | > ${CMAKE_CURRENT_BINARY_DIR}/${FILENAME_NOEXT}-protocol.c 24 | DEPENDS ${PATH} 25 | COMMENT "Generating ${FILENAME_NOEXT} protocol source code" 26 | ) 27 | endfunction() 28 | 29 | function(wayland_proto_library NAME) 30 | set(proto_headers "") 31 | set(proto_sources "") 32 | foreach(proto IN ITEMS ${ARGN}) 33 | list(APPEND proto_headers ${CMAKE_CURRENT_BINARY_DIR}/${proto}-client-protocol.h) 34 | list(APPEND proto_sources ${CMAKE_CURRENT_BINARY_DIR}/${proto}-protocol.c) 35 | endforeach() 36 | 37 | add_library(${NAME} STATIC ${proto_headers} ${proto_sources}) 38 | target_include_directories(${NAME} PUBLIC 39 | ${CMAKE_CURRENT_BINARY_DIR} 40 | ${WAYLAND_CLIENT_INCLUDE_DIRS} 41 | ) 42 | target_link_libraries(${NAME} PUBLIC 43 | ${WAYLAND_CLIENT_LIBRARIES} 44 | ) 45 | endfunction() 46 | -------------------------------------------------------------------------------- /src/common/CPUFeatures.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2017 Maarten Baert 3 | 4 | This file is part of SimpleScreenRecorder. 5 | 6 | SimpleScreenRecorder is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | SimpleScreenRecorder is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with SimpleScreenRecorder. If not, see . 18 | */ 19 | 20 | #pragma once 21 | #include "Global.h" 22 | 23 | #if SSR_USE_X86_ASM 24 | 25 | class CPUFeatures { 26 | 27 | private: 28 | static bool s_mmx; 29 | static bool s_sse, s_sse2, s_sse3, s_ssse3, s_sse41, s_sse42; 30 | static bool s_avx, s_avx2; 31 | static bool s_bmi1, s_bmi2; 32 | 33 | public: 34 | static void Detect(); 35 | 36 | inline static bool HasMMX() { return s_mmx; } 37 | inline static bool HasSSE() { return s_sse; } 38 | inline static bool HasSSE2() { return s_sse2; } 39 | inline static bool HasSSE3() { return s_sse3; } 40 | inline static bool HasSSSE3() { return s_ssse3; } 41 | inline static bool HasSSE41() { return s_sse41; } 42 | inline static bool HasSSE42() { return s_sse42; } 43 | inline static bool HasAVX() { return s_avx; } 44 | inline static bool HasAVX2() { return s_avx2; } 45 | inline static bool HasBMI1() { return s_bmi1; } 46 | inline static bool HasBMI2() { return s_bmi2; } 47 | 48 | }; 49 | 50 | #endif // SSR_USE_X86_ASM 51 | -------------------------------------------------------------------------------- /src/AV/Output/OutputSettings.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2017 Maarten Baert 3 | 4 | This file is part of SimpleScreenRecorder. 5 | 6 | SimpleScreenRecorder is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | SimpleScreenRecorder is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with SimpleScreenRecorder. If not, see . 18 | */ 19 | 20 | #pragma once 21 | #include "Global.h" 22 | 23 | struct OutputSettings { 24 | 25 | QString file; 26 | QString container_avname; 27 | 28 | QString video_codec_avname; 29 | unsigned int video_kbit_rate; 30 | std::vector > video_options; 31 | unsigned int video_width, video_height; 32 | unsigned int video_frame_rate; 33 | bool video_allow_frame_skipping; 34 | 35 | QString audio_codec_avname; 36 | unsigned int audio_kbit_rate; 37 | std::vector > audio_options; 38 | unsigned int audio_channels, audio_sample_rate; 39 | 40 | }; 41 | 42 | struct OutputFormat { 43 | 44 | bool m_video_enabled; 45 | unsigned int m_video_width, m_video_height; 46 | unsigned int m_video_frame_rate; 47 | AVPixelFormat m_video_pixel_format; 48 | 49 | bool m_audio_enabled; 50 | unsigned int m_audio_channels, m_audio_sample_rate; 51 | unsigned int m_audio_frame_size; 52 | AVSampleFormat m_audio_sample_format; 53 | 54 | }; 55 | -------------------------------------------------------------------------------- /src/AV/Input/SSRVideoStreamWatcher.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2017 Maarten Baert 3 | 4 | This file is part of SimpleScreenRecorder. 5 | 6 | SimpleScreenRecorder is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | SimpleScreenRecorder is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with SimpleScreenRecorder. If not, see . 18 | */ 19 | 20 | #pragma once 21 | #include "Global.h" 22 | 23 | #include "SSRVideoStream.h" 24 | 25 | #include "../glinject/ShmStructs.h" 26 | 27 | class SSRVideoStreamWatcher { 28 | 29 | public: 30 | typedef void (*AddCallback)(const SSRVideoStream&, void*); 31 | typedef void (*RemoveCallback)(const SSRVideoStream&, size_t, void*); 32 | 33 | private: 34 | std::string m_channel_directory; 35 | bool m_relax_permissions; 36 | 37 | int m_fd_notify; 38 | 39 | std::vector m_streams; 40 | 41 | public: 42 | SSRVideoStreamWatcher(const std::string& channel, bool relax_permissions); 43 | ~SSRVideoStreamWatcher(); 44 | 45 | private: 46 | void Init(); 47 | void Free(); 48 | 49 | public: 50 | // Handles all changes since the last call to this function. 51 | void HandleChanges(AddCallback add_callback, RemoveCallback remove_callback, void* userdata); 52 | 53 | // Returns a list of streams that are currently active. 54 | inline const std::vector& GetStreams() { return m_streams; } 55 | 56 | }; 57 | -------------------------------------------------------------------------------- /data/simplescreenrecorder.appdata.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | simplescreenrecorder.desktop 4 | CC0-1.0 5 | GPL-3.0+ 6 | SimpleScreenRecorder 7 | A feature-rich screen recorder that supports X11 and OpenGL 8 | 9 |

SimpleScreenRecorder is a feature-rich screen recorder that supports X11 and OpenGL. It has a Qt-based graphical user interface. It can record the entire screen or part of it, or record OpenGL applications directly. The recording can be paused and resumed at any time. Many different file formats and codecs are supported.

10 |

Key features:

11 |
    12 |
  • Synchronizes audio and video properly.
  • 13 |
  • Reduces the video frame rate if your computer is too slow.
  • 14 |
  • Fully multithreaded: small delays in any of the components will never block the other components, resulting is smoother video and better performance on computers with multiple processors.
  • 15 |
  • Can also do live streaming (experimental).
  • 16 |
17 |
18 | 19 | 20 | http://files.maartenbaert.be/simplescreenrecorder/screenshot01.png 21 | The input settings page 22 | 23 | 24 | http://files.maartenbaert.be/simplescreenrecorder/screenshot02.png 25 | The output settings page 26 | 27 | 28 | http://files.maartenbaert.be/simplescreenrecorder/screenshot03.png 29 | The recording page 30 | 31 | 32 | http://www.maartenbaert.be/simplescreenrecorder/ 33 |
-------------------------------------------------------------------------------- /src/AV/SimpleSynth.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2017 Maarten Baert 3 | 4 | This file is part of SimpleScreenRecorder. 5 | 6 | SimpleScreenRecorder is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | SimpleScreenRecorder is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with SimpleScreenRecorder. If not, see . 18 | */ 19 | 20 | #pragma once 21 | #include "Global.h" 22 | 23 | #if SSR_USE_ALSA 24 | 25 | #include "MutexDataPair.h" 26 | 27 | #include 28 | 29 | class SimpleSynth { 30 | 31 | public: 32 | struct Note { 33 | unsigned int m_time, m_duration_in, m_duration_out; 34 | float m_frequency, m_amplitude; 35 | }; 36 | 37 | private: 38 | struct SharedData { 39 | std::vector m_notes; 40 | unsigned int m_current_time; 41 | }; 42 | typedef MutexDataPair::Lock SharedLock; 43 | 44 | private: 45 | QString m_sink_name; 46 | unsigned int m_sample_rate; 47 | 48 | snd_pcm_t *m_alsa_pcm; 49 | unsigned int m_period_size, m_buffer_size; 50 | 51 | std::thread m_thread; 52 | MutexDataPair m_shared_data; 53 | std::atomic m_should_stop, m_error_occurred; 54 | 55 | public: 56 | SimpleSynth(const QString& sink_name, unsigned int sample_rate); 57 | ~SimpleSynth(); 58 | 59 | // This function is thread-safe. 60 | void PlaySequence(const Note* notes, unsigned int note_count); 61 | 62 | private: 63 | void Init(); 64 | void Free(); 65 | 66 | void SynthThread(); 67 | 68 | }; 69 | 70 | #endif 71 | -------------------------------------------------------------------------------- /src/AV/FastResampler_FirFilter.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2017 Maarten Baert 3 | 4 | This file is part of SimpleScreenRecorder. 5 | 6 | SimpleScreenRecorder is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | SimpleScreenRecorder is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with SimpleScreenRecorder. If not, see . 18 | */ 19 | 20 | #pragma once 21 | #include "Global.h" 22 | 23 | typedef void (*FirFilter2Ptr)(unsigned int, unsigned int, float*, float*, float, float*, float*); 24 | 25 | void FastResampler_FirFilter2_C1_Fallback(unsigned int channels, unsigned int filter_length, float* coef1, float* coef2, float frac, float* input, float* output); 26 | void FastResampler_FirFilter2_C2_Fallback(unsigned int channels, unsigned int filter_length, float* coef1, float* coef2, float frac, float* input, float* output); 27 | void FastResampler_FirFilter2_Cn_Fallback(unsigned int channels, unsigned int filter_length, float* coef1, float* coef2, float frac, float* input, float* output); 28 | 29 | #if SSR_USE_X86_ASM 30 | void FastResampler_FirFilter2_C1_SSE2(unsigned int channels, unsigned int filter_length, float* coef1, float* coef2, float frac, float* input, float* output); 31 | void FastResampler_FirFilter2_C2_SSE2(unsigned int channels, unsigned int filter_length, float* coef1, float* coef2, float frac, float* input, float* output); 32 | void FastResampler_FirFilter2_Cn_SSE2(unsigned int channels, unsigned int filter_length, float* coef1, float* coef2, float frac, float* input, float* output); 33 | #endif 34 | -------------------------------------------------------------------------------- /src/common/Logger.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2017 Maarten Baert 3 | 4 | This file is part of SimpleScreenRecorder. 5 | 6 | SimpleScreenRecorder is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | SimpleScreenRecorder is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with SimpleScreenRecorder. If not, see . 18 | */ 19 | 20 | #include "Logger.h" 21 | 22 | #include "Main.h" 23 | 24 | Logger *Logger::s_instance = NULL; 25 | 26 | Logger::Logger() { 27 | assert(s_instance == NULL); 28 | qRegisterMetaType(); 29 | s_instance = this; 30 | } 31 | 32 | Logger::~Logger() { 33 | assert(s_instance == this); 34 | s_instance = NULL; 35 | } 36 | 37 | void Logger::LogInfo(const QString& str) { 38 | assert(s_instance != NULL); 39 | std::lock_guard lock(s_instance->m_mutex); Q_UNUSED(lock); 40 | fprintf(stderr, "%s\n", str.toLocal8Bit().constData()); 41 | emit s_instance->NewLine(TYPE_INFO, str); 42 | } 43 | 44 | void Logger::LogWarning(const QString& str) { 45 | assert(s_instance != NULL); 46 | std::lock_guard lock(s_instance->m_mutex); Q_UNUSED(lock); 47 | fprintf(stderr, "\033[1;33m%s\033[0m\n", str.toLocal8Bit().constData()); 48 | emit s_instance->NewLine(TYPE_WARNING, str); 49 | } 50 | 51 | void Logger::LogError(const QString& str) { 52 | assert(s_instance != NULL); 53 | std::lock_guard lock(s_instance->m_mutex); Q_UNUSED(lock); 54 | fprintf(stderr, "\033[1;31m%s\033[0m\n", str.toLocal8Bit().constData()); 55 | emit s_instance->NewLine(TYPE_ERROR, str); 56 | } 57 | -------------------------------------------------------------------------------- /src/AV/Input/ALSAInput.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2017 Maarten Baert 3 | 4 | This file is part of SimpleScreenRecorder. 5 | 6 | SimpleScreenRecorder is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | SimpleScreenRecorder is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with SimpleScreenRecorder. If not, see . 18 | */ 19 | 20 | #pragma once 21 | #include "Global.h" 22 | 23 | #if SSR_USE_ALSA 24 | 25 | #include "SourceSink.h" 26 | #include "MutexDataPair.h" 27 | 28 | #include 29 | 30 | class ALSAInput : public AudioSource { 31 | 32 | public: 33 | struct Source { 34 | std::string m_name, m_description; 35 | inline Source(const std::string& name, const std::string& description) : m_name(name), m_description(description) {} 36 | }; 37 | 38 | private: 39 | static const int64_t START_DELAY; 40 | 41 | private: 42 | QString m_source_name; 43 | unsigned int m_sample_rate, m_channels; 44 | unsigned int m_period_size, m_buffer_size; 45 | 46 | snd_pcm_t *m_alsa_pcm; 47 | 48 | std::thread m_thread; 49 | std::atomic m_should_stop, m_error_occurred; 50 | 51 | public: 52 | ALSAInput(const QString& source_name, unsigned int sample_rate); 53 | ~ALSAInput(); 54 | 55 | // Returns whether an error has occurred in the input thread. 56 | // This function is thread-safe. 57 | inline bool HasErrorOccurred() { return m_error_occurred; } 58 | 59 | public: 60 | static std::vector GetSourceList(); 61 | 62 | private: 63 | void Init(); 64 | void Free(); 65 | 66 | void InputThread(); 67 | 68 | }; 69 | 70 | #endif 71 | -------------------------------------------------------------------------------- /data/man/simplescreenrecorder.1: -------------------------------------------------------------------------------- 1 | .TH SIMPLESCREENRECORDER "1" "March 2015" "SimpleScreenRecorder" "SimpleScreenRecorder Manual" 2 | .SH NAME 3 | simplescreenrecorder \- A feature-rich screen recorder that supports X11 and OpenGL. 4 | .SH SYNOPSIS 5 | .B simplescreenrecorder 6 | [\fI\,OPTIONS\/\fR] 7 | .SH DESCRIPTION 8 | SimpleScreenRecorder is a feature-rich screen recorder that supports X11 and 9 | OpenGL. It has a Qt-based graphical user interface. It can record the entire 10 | screen or part of it, or record OpenGL applications directly. The recording 11 | can be paused and resumed at any time. Many different file formats and codecs 12 | are supported. 13 | .SH OPTIONS 14 | .TP 15 | \fB\-\-help\fR 16 | Show help message. 17 | .TP 18 | \fB\-\-version\fR 19 | Show version and quit. 20 | .TP 21 | \fB\-\-logfile\fR 22 | Write log to \fI\,~/.ssr/log\-DATE_TIME.txt\/\fP instead of stdout. 23 | .TP 24 | \fB\-\-statsfile\fR[=\fI\,FILE\/\fR] 25 | Write recording statistics to \fI\,FILE\/\fR. If \fI\,FILE\/\fR is omitted, 26 | \fI\,/dev/shm/simplescreenrecorder\-stats\-PID\/\fP is used. It will 27 | be updated continuously and deleted when the recording 28 | page is closed. 29 | .TP 30 | \fB\-\-syncdiagram\fR 31 | Show synchronization diagram (for debugging). 32 | .TP 33 | \fB\-\-no\-systray\fR 34 | Don't show the system tray icon. 35 | .TP 36 | \fB\-\-start\-hidden\fR 37 | Start the application in hidden form. 38 | .SH "FILE LOCATIONS" 39 | The files used by SimpleScreenRecorder can be found in the following locations: 40 | .PP 41 | Settings: 42 | .RS 43 | ~/.ssr/settings.conf 44 | .RE 45 | .PP 46 | Logs: 47 | .RS 48 | ~/.ssr/logs/ 49 | .RE 50 | .PP 51 | Input profiles: 52 | .RS 53 | /usr/share/simplescreenrecorder/input-profiles/ 54 | .br 55 | ~/.ssr/input-profiles/ 56 | .RE 57 | .PP 58 | Output profiles: 59 | .RS 60 | /usr/share/simplescreenrecorder/output-profiles/ 61 | .br 62 | ~/.ssr/output-profiles/ 63 | .RE 64 | .PP 65 | Translations: 66 | .RS 67 | /usr/share/simplescreenrecorder/translations/ 68 | .RE 69 | .SH "SEE ALSO" 70 | More documentation can be found at: 71 | .br 72 | http://www.maartenbaert.be/simplescreenrecorder/ 73 | -------------------------------------------------------------------------------- /src/AV/Output/VideoEncoder.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2017 Maarten Baert 3 | 4 | This file is part of SimpleScreenRecorder. 5 | 6 | SimpleScreenRecorder is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | SimpleScreenRecorder is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with SimpleScreenRecorder. If not, see . 18 | */ 19 | 20 | #pragma once 21 | #include "Global.h" 22 | 23 | #include "BaseEncoder.h" 24 | 25 | class VideoEncoder : public BaseEncoder { 26 | 27 | private: 28 | struct PixelFormatData { 29 | QString m_name; 30 | AVPixelFormat m_format; 31 | bool m_is_yuv; 32 | }; 33 | 34 | private: 35 | static const std::vector SUPPORTED_PIXEL_FORMATS; 36 | 37 | private: 38 | #if !SSR_USE_AVCODEC_ENCODE_VIDEO2 39 | std::vector m_temp_buffer; 40 | #endif 41 | 42 | public: 43 | VideoEncoder(Muxer* muxer, AVStream* stream, AVCodecContext* codec_context, AVCodec* codec, AVDictionary** options); 44 | ~VideoEncoder(); 45 | 46 | // Returns the required pixel format. 47 | AVPixelFormat GetPixelFormat(); 48 | 49 | unsigned int GetWidth(); 50 | unsigned int GetHeight(); 51 | unsigned int GetFrameRate(); 52 | 53 | public: 54 | static bool AVCodecIsSupported(const QString& codec_name); 55 | static void PrepareStream(AVStream* stream, AVCodecContext* codec_context, AVCodec* codec, AVDictionary** options, const std::vector >& codec_options, 56 | unsigned int bit_rate, unsigned int width, unsigned int height, unsigned int frame_rate); 57 | 58 | private: 59 | virtual bool EncodeFrame(AVFrameWrapper* frame) override; 60 | 61 | }; 62 | -------------------------------------------------------------------------------- /cmake/FindFFmpeg.cmake: -------------------------------------------------------------------------------- 1 | # rules for finding the FFmpeg libraries 2 | 3 | find_package(PkgConfig REQUIRED) 4 | pkg_check_modules(PC_FFMPEG libavformat libavcodec libavutil libswscale) 5 | 6 | find_path(AVFORMAT_INCLUDE_DIR libavformat/avformat.h HINTS ${PC_FFMPEG_LIBAVFORMAT_INCLUDEDIR} ${PC_FFMPEG_INCLUDE_DIRS}) 7 | find_library(AVFORMAT_LIBRARY NAMES avformat HINTS ${PC_FFMPEG_LIBAVFORMAT_LIBDIR} ${PC_FFMPEG_LIBRARY_DIRS}) 8 | 9 | find_path(AVCODEC_INCLUDE_DIR libavcodec/avcodec.h HINTS ${PC_FFMPEG_LIBAVCODEC_INCLUDEDIR} ${PC_FFMPEG_INCLUDE_DIRS}) 10 | find_library(AVCODEC_LIBRARY NAMES avcodec HINTS ${PC_FFMPEG_LIBAVCODEC_LIBDIR} ${PC_FFMPEG_LIBRARY_DIRS}) 11 | 12 | find_path(AVUTIL_INCLUDE_DIR libavutil/avutil.h HINTS ${PC_FFMPEG_LIBAVUTIL_INCLUDEDIR} ${PC_FFMPEG_INCLUDE_DIRS}) 13 | find_library(AVUTIL_LIBRARY NAMES avutil HINTS ${PC_FFMPEG_LIBAVUTIL_LIBDIR} ${PC_FFMPEG_LIBRARY_DIRS}) 14 | 15 | find_path(SWSCALE_INCLUDE_DIR libswscale/swscale.h HINTS ${PC_FFMPEG_LIBSWSCALE_INCLUDEDIR} ${PC_FFMPEG_INCLUDE_DIRS}) 16 | find_library(SWSCALE_LIBRARY NAMES swscale HINTS ${PC_FFMPEG_LIBSWSCALE_LIBDIR} ${PC_FFMPEG_LIBRARY_DIRS}) 17 | 18 | include(FindPackageHandleStandardArgs) 19 | find_package_handle_standard_args(AVFormat DEFAULT_MSG AVFORMAT_LIBRARY AVFORMAT_INCLUDE_DIR) 20 | find_package_handle_standard_args(AVCodec DEFAULT_MSG AVCODEC_LIBRARY AVCODEC_INCLUDE_DIR) 21 | find_package_handle_standard_args(AVUtil DEFAULT_MSG AVUTIL_LIBRARY AVUTIL_INCLUDE_DIR) 22 | find_package_handle_standard_args(SWScale DEFAULT_MSG SWSCALE_LIBRARY SWSCALE_INCLUDE_DIR) 23 | 24 | mark_as_advanced(AVFORMAT_INCLUDE_DIR AVFORMAT_LIBRARY) 25 | mark_as_advanced(AVCODEC_INCLUDE_DIR AVCODEC_LIBRARY) 26 | mark_as_advanced(AVUTIL_INCLUDE_DIR AVUTIL_LIBRARY) 27 | mark_as_advanced(SWSCALE_INCLUDE_DIR SWSCALE_LIBRARY) 28 | 29 | set(FFMPEG_INCLUDE_DIRS ${AVFORMAT_INCLUDE_DIR} ${AVCODEC_INCLUDE_DIR} ${AVUTIL_INCLUDE_DIR} ${SWSCALE_INCLUDE_DIR}) 30 | set(FFMPEG_LIBRARIES ${AVFORMAT_LIBRARY} ${AVCODEC_LIBRARY} ${AVUTIL_LIBRARY} ${SWSCALE_LIBRARY}) 31 | 32 | if(${AVFORMAT_FOUND} AND ${AVCODEC_FOUND} AND ${AVUTIL_FOUND} AND ${SWSCALE_FOUND}) 33 | set(FFMPEG_FOUND TRUE) 34 | else() 35 | set(FFMPEG_FOUND FALSE) 36 | endif() 37 | -------------------------------------------------------------------------------- /src/AV/FastScaler_Scale_Generic.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2017 Maarten Baert 3 | 4 | This file is part of SimpleScreenRecorder. 5 | 6 | SimpleScreenRecorder is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | SimpleScreenRecorder is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with SimpleScreenRecorder. If not, see . 18 | */ 19 | 20 | #pragma once 21 | #include "Global.h" 22 | 23 | inline uint64_t vec4x16(uint16_t x) { 24 | return ((uint64_t) x << 48) | ((uint64_t) x << 32) | ((uint64_t) x << 16) | ((uint64_t) x); 25 | } 26 | 27 | inline void Bilinear_MapIndex(unsigned int out_i, unsigned int in_w, unsigned int out_w, unsigned int mipmap, unsigned int& offset, unsigned int& fraction) { 28 | uint64_t inter = (((uint64_t) out_i << 8) + 128) * (uint64_t) in_w; 29 | unsigned int div = out_w << mipmap; 30 | int64_t ii = (int64_t) ((inter + (uint64_t) (div >> 1)) / (uint64_t) div) - 128; 31 | int off = ii >> 8; 32 | int max_offset = (int) ((in_w - 1) >> mipmap) - 1; 33 | if(off < 0) { 34 | offset = 0; 35 | fraction = 0; 36 | } else if(off > max_offset) { 37 | offset = max_offset; 38 | fraction = 256; 39 | } else { 40 | offset = off; 41 | fraction = ii & 255; 42 | } 43 | } 44 | 45 | typedef void (*MipMapFunction)(unsigned int, unsigned int, const uint8_t*, int, uint8_t*, int, unsigned int, unsigned int); 46 | typedef void (*BilinearFunction)(unsigned int, unsigned int, const uint8_t*, int, unsigned int, unsigned int, uint8_t*, int, unsigned int, unsigned int); 47 | 48 | void Scale_BGRA_Generic(unsigned int in_w, unsigned int in_h, const uint8_t* in_data, int in_stride, 49 | unsigned int out_w, unsigned int out_h, uint8_t* out_data, int out_stride, 50 | MipMapFunction mipmap_function, BilinearFunction bilinear_function); 51 | -------------------------------------------------------------------------------- /src/GUI/Icons.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2017 Maarten Baert 3 | 4 | This file is part of SimpleScreenRecorder. 5 | 6 | SimpleScreenRecorder is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | SimpleScreenRecorder is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with SimpleScreenRecorder. If not, see . 18 | */ 19 | 20 | #include "Icons.h" 21 | 22 | QIcon g_icon_ssr, g_icon_ssr_idle, g_icon_ssr_error, g_icon_ssr_paused, g_icon_ssr_recording; 23 | QIcon g_icon_go_home, g_icon_go_previous, g_icon_go_next; 24 | QIcon g_icon_pause, g_icon_record; 25 | QIcon g_icon_cancel, g_icon_save, g_icon_quit; 26 | QIcon g_icon_microphone; 27 | 28 | void LoadIcons() { 29 | 30 | g_icon_ssr = QIcon::fromTheme("simplescreenrecorder"); 31 | g_icon_ssr_idle = QIcon::fromTheme("simplescreenrecorder-idle"); 32 | g_icon_ssr_error = QIcon::fromTheme("simplescreenrecorder-error"); 33 | g_icon_ssr_paused = QIcon::fromTheme("simplescreenrecorder-paused"); 34 | g_icon_ssr_recording = QIcon::fromTheme("simplescreenrecorder-recording"); 35 | 36 | g_icon_go_home = QIcon::fromTheme("go-home"); 37 | if(QApplication::layoutDirection() == Qt::RightToLeft) { 38 | g_icon_go_previous = QIcon::fromTheme("go-next"); 39 | g_icon_go_next = QIcon::fromTheme("go-previous"); 40 | } else { 41 | g_icon_go_previous = QIcon::fromTheme("go-previous"); 42 | g_icon_go_next = QIcon::fromTheme("go-next"); 43 | } 44 | 45 | g_icon_pause = QIcon::fromTheme("media-playback-pause"); 46 | g_icon_record = QIcon::fromTheme("media-record"); 47 | 48 | g_icon_cancel = QIcon::fromTheme("process-stop"); 49 | g_icon_save = QIcon::fromTheme("document-save"); 50 | g_icon_quit = QIcon::fromTheme("application-exit"); 51 | 52 | g_icon_microphone = QIcon::fromTheme("audio-input-microphone"); 53 | 54 | } 55 | -------------------------------------------------------------------------------- /glinject/SSRVideoStreamWriter.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2017 Maarten Baert 3 | 4 | Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. 5 | 6 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 7 | */ 8 | 9 | #pragma once 10 | #include "Global.h" 11 | 12 | #include "ShmStructs.h" 13 | 14 | class SSRVideoStreamWriter { 15 | 16 | private: 17 | struct FrameData { 18 | std::string m_filename_frame; 19 | int m_fd_frame; 20 | void *m_mmap_ptr_frame; 21 | size_t m_mmap_size_frame; 22 | }; 23 | 24 | private: 25 | std::string m_channel_directory, m_filename_main; 26 | size_t m_page_size; 27 | unsigned int m_width, m_height; 28 | int m_stride; 29 | 30 | int64_t m_next_frame_time; 31 | 32 | int m_fd_main, m_file_lock; 33 | void *m_mmap_ptr_main; 34 | size_t m_mmap_size_main; 35 | 36 | FrameData m_frame_data[GLINJECT_RING_BUFFER_SIZE]; 37 | 38 | public: 39 | SSRVideoStreamWriter(const std::string& channel, const std::string& source); 40 | ~SSRVideoStreamWriter(); 41 | 42 | private: 43 | void Init(); 44 | void Free(); 45 | 46 | GLInjectHeader* GetGLInjectHeader(); 47 | GLInjectFrameInfo* GetGLInjectFrameInfo(unsigned int frame); 48 | 49 | public: 50 | // Updates the size of the video stream. 51 | void UpdateSize(unsigned int width, unsigned int height, int stride); 52 | 53 | // Should be called for every new frame. It will determine whether the frame should be captured. 54 | // If it should be captured, it will allocate shared memory for the frame and return a pointer. Otherwise it returns NULL. 55 | void* NewFrame(unsigned int* flags); 56 | 57 | // Writes the allocated frame to the ring buffer after it has been captured. 58 | void NextFrame(); 59 | 60 | }; 61 | -------------------------------------------------------------------------------- /scripts/ssr-glinject: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | usage() { 6 | echo "Usage: ssr-glinject [OPTIONS] [--] COMMAND" >& 2 7 | echo "" >& 2 8 | echo "Options:" >& 2 9 | echo " --help Show this help message." >& 2 10 | echo " --glx-debug Enables GLX debugging. This may reduce the performance" >& 2 11 | echo " and print lots of error messages, but it is useful to" >& 2 12 | echo " track down bugs." >& 2 13 | echo " --relax-permissions Uses mode 666 instead of 600 for shared memory, so that" >& 2 14 | echo " other users can record the stream. This is insecure and" >& 2 15 | echo " should not be used on a computer that can be accessed by" >& 2 16 | echo " other users that you don't trust." >& 2 17 | echo " --channel=CHANNEL Channel name to use. The default is 'channel-USERNAME'." >& 2 18 | echo "" >& 2 19 | echo "This script uses LD_PRELOAD to inject the GLInject library into the given" >& 2 20 | echo "command, so that SimpleScreenRecorder can record it. It should be safe to use" >& 2 21 | echo "this on all applications (including command-line programs and shell scripts)." >& 2 22 | echo "If the program doesn't use OpenGL, it should have no effect. If you find a" >& 2 23 | echo "program that crashes or behaves incorrectly when GLInject is used, please submit" >& 2 24 | echo "a bug report." >& 2 25 | } 26 | 27 | export SSR_GLX_DEBUG=0 28 | export SSR_STREAM_RELAX_PERMISSIONS=0 29 | 30 | while [ $# -gt 0 ] 31 | do 32 | if [ x"$1" = x"--" ] 33 | then 34 | shift 35 | break 36 | elif [ x"$1" = x"--help" ] 37 | then 38 | usage 39 | exit 40 | elif [ x"$1" = x"--glx-debug" ] 41 | then 42 | export SSR_GLX_DEBUG=1 43 | shift 44 | elif [ x"$1" = x"--relax-permissions" ] 45 | then 46 | export SSR_STREAM_RELAX_PERMISSIONS=1 47 | shift 48 | elif [ x"${1:0:10}" = x"--channel=" ] 49 | then 50 | export SSR_CHANNEL="${1:10}" 51 | shift 52 | elif [ x"${1:0:1}" = x"-" ] 53 | then 54 | echo "ssr-glinject: Unknown option '$1'!" >& 2 55 | usage 56 | exit 1 57 | else 58 | break 59 | fi 60 | done 61 | 62 | echo "ssr-glinject: LD_PRELOAD = $LD_PRELOAD:libssr-glinject.so" 63 | echo "ssr-glinject: command = $@" 64 | LD_PRELOAD="$LD_PRELOAD:libssr-glinject.so" "$@" 65 | -------------------------------------------------------------------------------- /src/common/TempBuffer.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2017 Maarten Baert 3 | 4 | This file is part of SimpleScreenRecorder. 5 | 6 | SimpleScreenRecorder is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | SimpleScreenRecorder is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with SimpleScreenRecorder. If not, see . 18 | */ 19 | 20 | #pragma once 21 | #include "Global.h" 22 | 23 | // This is a simple class that allocates temporary buffers efficiently by reusing memory to avoid new memory allocations. 24 | // It is more efficient than std::vector because it doesn't copy data or initialize it to zero. 25 | // The amount of allocated memory will only grow, not shrink (i.e. like std::vector). 26 | // The 'GetSize' function will always report the actual size, which can be larger than the requested size. 27 | 28 | #define TEMPBUFFER_ALIGN 16 29 | 30 | template 31 | class TempBuffer { 32 | 33 | private: 34 | T *m_data; 35 | size_t m_size; 36 | 37 | public: 38 | inline TempBuffer() { 39 | m_data = NULL; 40 | m_size = 0; 41 | } 42 | inline ~TempBuffer() { 43 | free(m_data); 44 | } 45 | inline void Alloc(size_t size, bool copy = false) { 46 | if(size > m_size) { 47 | if(m_size != 0) 48 | size += size / 4; 49 | void *temp; 50 | if(posix_memalign(&temp, TEMPBUFFER_ALIGN, sizeof(T) * size) != 0) 51 | throw std::bad_alloc(); 52 | if(copy) 53 | memcpy(temp, m_data, sizeof(T) * m_size); 54 | free(m_data); 55 | m_data = (T*) temp; 56 | m_size = size; 57 | } 58 | } 59 | 60 | public: 61 | inline T* GetData() { return m_data; } 62 | inline size_t GetSize() { return m_size; } 63 | inline T& operator[](size_t i) { return m_data[i]; } 64 | 65 | // noncopyable 66 | TempBuffer(const TempBuffer&) = delete; 67 | TempBuffer& operator=(const TempBuffer&) = delete; 68 | 69 | }; 70 | -------------------------------------------------------------------------------- /src/AV/Output/AudioEncoder.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2017 Maarten Baert 3 | 4 | This file is part of SimpleScreenRecorder. 5 | 6 | SimpleScreenRecorder is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | SimpleScreenRecorder is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with SimpleScreenRecorder. If not, see . 18 | */ 19 | 20 | #pragma once 21 | #include "Global.h" 22 | 23 | #include "BaseEncoder.h" 24 | 25 | class AudioEncoder : public BaseEncoder { 26 | 27 | private: 28 | struct SampleFormatData { 29 | QString m_name; 30 | AVSampleFormat m_format; 31 | }; 32 | 33 | private: 34 | static const std::vector SUPPORTED_SAMPLE_FORMATS; 35 | static const unsigned int DEFAULT_FRAME_SAMPLES; 36 | 37 | private: 38 | #if !SSR_USE_AVCODEC_ENCODE_AUDIO2 39 | std::vector m_temp_buffer; 40 | #endif 41 | 42 | public: 43 | AudioEncoder(Muxer* muxer, AVStream* stream, AVCodecContext* codec_context, AVCodec* codec, AVDictionary** options); 44 | ~AudioEncoder(); 45 | 46 | // Returns the required frame size, i.e. the number of samples (for each channel). 47 | unsigned int GetFrameSize(); 48 | 49 | // Returns the required sample format. 50 | AVSampleFormat GetSampleFormat(); 51 | 52 | // Returns the number of audio channels. 53 | unsigned int GetChannels(); 54 | 55 | // Returns the audio sample rate. 56 | unsigned int GetSampleRate(); 57 | 58 | public: 59 | static bool AVCodecIsSupported(const QString& codec_name); 60 | static void PrepareStream(AVStream* stream, AVCodecContext* codec_context, AVCodec* codec, AVDictionary** options, const std::vector >& codec_options, 61 | unsigned int bit_rate, unsigned int channels, unsigned int sample_rate); 62 | 63 | private: 64 | virtual bool EncodeFrame(AVFrameWrapper* frame) override; 65 | 66 | }; 67 | -------------------------------------------------------------------------------- /src/AV/FastResampler.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2017 Maarten Baert 3 | 4 | This file is part of SimpleScreenRecorder. 5 | 6 | SimpleScreenRecorder is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | SimpleScreenRecorder is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with SimpleScreenRecorder. If not, see . 18 | */ 19 | 20 | #pragma once 21 | #include "Global.h" 22 | #include "TempBuffer.h" 23 | #include "QueueBuffer.h" 24 | 25 | #include "FastResampler_FirFilter.h" 26 | 27 | #include 28 | 29 | class FastResampler { 30 | 31 | private: 32 | #if SSR_USE_X86_ASM 33 | // CPU feature detection 34 | bool m_use_sse2; 35 | #endif 36 | 37 | // settings 38 | unsigned int m_channels; 39 | float m_gain; 40 | double m_resample_ratio, m_drift_ratio; 41 | 42 | // filter coefficient sets 43 | unsigned int m_filter_length, m_filter_rows; 44 | TempBuffer m_filter_coefficients; 45 | 46 | // resampler state 47 | double m_time; 48 | QueueBuffer m_samples_memory; 49 | 50 | // function pointers 51 | FirFilter2Ptr m_firfilter2_ptr; 52 | 53 | public: 54 | FastResampler(unsigned int channels, float gain); 55 | 56 | // Processes input audio and writes the resampled audio to a queue. 'samples_in' can be NULL to flush the resampler. 57 | unsigned int Resample(double resample_ratio, double drift_ratio, const float* samples_in, unsigned int sample_count_in, TempBuffer* samples_out, unsigned int sample_offset_out); 58 | 59 | // Returns the total resampler latency in input samples. 60 | double GetInputLatency(); 61 | 62 | // Returns the total resampler latency in output samples. 63 | double GetOutputLatency(); 64 | 65 | private: 66 | void UpdateFilterCoefficients(); 67 | void ResetResamplerState(); 68 | 69 | std::pair ResampleBatch(float* samples_in, unsigned int sample_count_in, float* samples_out); 70 | 71 | }; 72 | -------------------------------------------------------------------------------- /src/GUI/ElidedLabel.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2017 Maarten Baert 3 | 4 | Original code written by Jason Gedge and placed in the public domain. 5 | http://gedgedev.blogspot.be/2010/12/elided-labels-in-qt.html 6 | This is a slightly modified version. 7 | 8 | This file is part of SimpleScreenRecorder. 9 | 10 | SimpleScreenRecorder is free software: you can redistribute it and/or modify 11 | it under the terms of the GNU General Public License as published by 12 | the Free Software Foundation, either version 3 of the License, or 13 | (at your option) any later version. 14 | 15 | SimpleScreenRecorder is distributed in the hope that it will be useful, 16 | but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | GNU General Public License for more details. 19 | 20 | You should have received a copy of the GNU General Public License 21 | along with SimpleScreenRecorder. If not, see . 22 | */ 23 | 24 | #pragma once 25 | #include "Global.h" 26 | 27 | // A label that elides its text when not enough geometry is available to show all of the text. 28 | // Currently only capable of one-line. 29 | class ElidedLabel : public QLabel { 30 | Q_OBJECT 31 | 32 | private: 33 | Qt::TextElideMode m_elide_mode; 34 | QString m_cached_elided_text; 35 | 36 | public: 37 | ElidedLabel(QWidget* parent = NULL, Qt::WindowFlags f = 0); 38 | ElidedLabel(const QString& txt, QWidget* parent = NULL, Qt::WindowFlags f = 0); 39 | ElidedLabel(const QString& txt, Qt::TextElideMode elideMode = Qt::ElideRight, QWidget* parent = NULL, Qt::WindowFlags f = 0); 40 | 41 | public: 42 | // Set the elide mode used for displaying text. 43 | inline void setElideMode(Qt::TextElideMode elideMode) { 44 | m_elide_mode = elideMode; 45 | updateGeometry(); 46 | } 47 | 48 | // Get the elide mode currently used to display text. 49 | inline Qt::TextElideMode elideMode() const { 50 | return m_elide_mode; 51 | } 52 | 53 | public: // QLabel overrides 54 | void setText(const QString&); // note: not virtual so no polymorphism ... 55 | 56 | protected: // QLabel overrides 57 | virtual void paintEvent(QPaintEvent*) override; 58 | virtual void resizeEvent(QResizeEvent*) override; 59 | 60 | protected: 61 | // Cache the elided text so as to not recompute it every paint event 62 | void cacheElidedText(int w); 63 | 64 | }; 65 | -------------------------------------------------------------------------------- /src/AV/Output/SyncDiagram.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2017 Maarten Baert 3 | 4 | This file is part of SimpleScreenRecorder. 5 | 6 | SimpleScreenRecorder is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | SimpleScreenRecorder is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with SimpleScreenRecorder. If not, see . 18 | */ 19 | 20 | #pragma once 21 | #include "Global.h" 22 | 23 | #include "MutexDataPair.h" 24 | 25 | class SyncDiagram : public QWidget { 26 | Q_OBJECT 27 | 28 | private: 29 | struct TimeBlock { 30 | double m_time_begin, m_time_end; 31 | QColor m_color; 32 | }; 33 | struct TimeChannel { 34 | QString m_name; 35 | double m_current_time, m_time_shift, m_time_shift_v; 36 | std::deque m_time_blocks; 37 | }; 38 | struct SharedData { 39 | std::vector m_time_channels; 40 | }; 41 | typedef MutexDataPair::Lock SharedLock; 42 | 43 | private: 44 | static constexpr int CHANNEL_HEIGHT = 20, CHANNEL_SPACING = 10, MARGIN_RIGHT = 50; 45 | static constexpr double PIXELS_PER_SECOND = 400.0; 46 | 47 | private: 48 | MutexDataPair m_shared_data; 49 | 50 | int m_height; 51 | QFont m_font; 52 | QTimer *m_update_timer; 53 | 54 | public: 55 | SyncDiagram(size_t channels); 56 | ~SyncDiagram(); 57 | 58 | // These functions are thread-safe. 59 | void SetChannelName(size_t channel, const QString& name); 60 | void SetCurrentTime(size_t channel, double current_time); 61 | void AddBlock(size_t channel, double time_begin, double time_end, const QColor& color); 62 | void Update(); 63 | 64 | public: 65 | virtual QSize minimumSizeHint() const override { return QSize(200, m_height); } 66 | virtual QSize sizeHint() const override { return QSize(800, m_height); } 67 | 68 | protected: 69 | virtual void paintEvent(QPaintEvent* event) override; 70 | 71 | signals: 72 | void NeedsUpdate(); 73 | 74 | private slots: 75 | void DelayedUpdate(); 76 | 77 | }; 78 | -------------------------------------------------------------------------------- /src/AV/FastScaler.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2017 Maarten Baert 3 | 4 | This file is part of SimpleScreenRecorder. 5 | 6 | SimpleScreenRecorder is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | SimpleScreenRecorder is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with SimpleScreenRecorder. If not, see . 18 | */ 19 | 20 | #pragma once 21 | #include "Global.h" 22 | 23 | #include "AVWrapper.h" 24 | 25 | class FastScaler { 26 | 27 | private: 28 | #if SSR_USE_X86_ASM 29 | bool m_warn_alignment; 30 | #endif 31 | 32 | bool m_warn_swscale; 33 | SwsContext *m_sws_context; 34 | 35 | public: 36 | FastScaler(); 37 | ~FastScaler(); 38 | void Scale(unsigned int in_width, unsigned int in_height, AVPixelFormat in_format, const uint8_t* const* in_data, const int* in_stride, 39 | unsigned int out_width, unsigned int out_height, AVPixelFormat out_format, uint8_t* const* out_data, const int* out_stride); 40 | 41 | private: 42 | void Convert_BGRA_YUV444(unsigned int width, unsigned int height, const uint8_t* in_data, int in_stride, uint8_t* const out_data[3], const int out_stride[3]); 43 | void Convert_BGRA_YUV422(unsigned int width, unsigned int height, const uint8_t* in_data, int in_stride, uint8_t* const out_data[3], const int out_stride[3]); 44 | void Convert_BGRA_YUV420(unsigned int width, unsigned int height, const uint8_t* in_data, int in_stride, uint8_t* const out_data[3], const int out_stride[3]); 45 | void Convert_BGRA_NV12(unsigned int width, unsigned int height, const uint8_t* in_data, int in_stride, uint8_t* const out_data[2], const int out_stride[2]); 46 | void Convert_BGRA_BGR(unsigned int width, unsigned int height, const uint8_t* in_data, int in_stride, uint8_t* out_data, int out_stride); 47 | void Scale_BGRA(unsigned int in_width, unsigned int in_height, const uint8_t* in_data, int in_stride, 48 | unsigned int out_width, unsigned int out_height, uint8_t* out_data, int out_stride); 49 | 50 | }; 51 | -------------------------------------------------------------------------------- /src/GUI/ProfileBox.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2017 Maarten Baert 3 | 4 | This file is part of SimpleScreenRecorder. 5 | 6 | SimpleScreenRecorder is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | SimpleScreenRecorder is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with SimpleScreenRecorder. If not, see . 18 | */ 19 | 20 | #pragma once 21 | #include "Global.h" 22 | 23 | class ProfileBox : public QGroupBox { 24 | Q_OBJECT 25 | 26 | public: 27 | typedef void (*LoadCallback)(QSettings*, void*); 28 | typedef void (*SaveCallback)(QSettings*, void*); 29 | 30 | private: 31 | struct Profile { 32 | QString m_name; 33 | bool m_can_delete; 34 | bool operator<(const Profile& other) const { return (m_name < other.m_name); } 35 | }; 36 | 37 | private: 38 | QString m_type; 39 | LoadCallback m_load_callback; 40 | SaveCallback m_save_callback; 41 | void *m_userdata; 42 | 43 | std::vector m_profiles; 44 | 45 | QComboBox *m_combobox_profiles; 46 | QPushButton *m_pushbutton_save, *m_pushbutton_new, *m_pushbutton_delete; 47 | 48 | public: 49 | ProfileBox(const QString& title, QWidget* parent, const QString& type, LoadCallback load_callback, SaveCallback save_callback, void* userdata); 50 | 51 | QString GetProfileName(); 52 | unsigned int FindProfile(const QString& name); 53 | 54 | private: 55 | void LoadProfiles(); 56 | void LoadProfilesFromDir(std::vector* profiles, const QString& path, bool can_delete); 57 | void UpdateProfileFields(); 58 | 59 | private slots: 60 | void OnProfileChange(); 61 | void OnProfileSave(); 62 | void OnProfileNew(); 63 | void OnProfileDelete(); 64 | 65 | public: 66 | inline unsigned int GetProfile() { return clamp(m_combobox_profiles->currentIndex(), 0, (int) m_profiles.size()); } 67 | inline void SetProfile(unsigned int profile) { m_combobox_profiles->setCurrentIndex(clamp(profile, 0u, (unsigned int) m_profiles.size())); UpdateProfileFields(); } 68 | 69 | }; 70 | -------------------------------------------------------------------------------- /src/AV/FastScaler_Convert.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2017 Maarten Baert 3 | 4 | This file is part of SimpleScreenRecorder. 5 | 6 | SimpleScreenRecorder is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | SimpleScreenRecorder is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with SimpleScreenRecorder. If not, see . 18 | */ 19 | 20 | #pragma once 21 | #include "Global.h" 22 | 23 | void Convert_BGRA_YUV444_Fallback(unsigned int w, unsigned int h, const uint8_t* in_data, int in_stride, uint8_t* const out_data[3], const int out_stride[3]); 24 | void Convert_BGRA_YUV422_Fallback(unsigned int w, unsigned int h, const uint8_t* in_data, int in_stride, uint8_t* const out_data[3], const int out_stride[3]); 25 | void Convert_BGRA_YUV420_Fallback(unsigned int w, unsigned int h, const uint8_t* in_data, int in_stride, uint8_t* const out_data[3], const int out_stride[3]); 26 | void Convert_BGRA_NV12_Fallback(unsigned int w, unsigned int h, const uint8_t* in_data, int in_stride, uint8_t* const out_data[2], const int out_stride[2]); 27 | void Convert_BGRA_BGR_Fallback(unsigned int w, unsigned int h, const uint8_t* in_data, int in_stride, uint8_t* out_data, int out_stride); 28 | 29 | #if SSR_USE_X86_ASM 30 | void Convert_BGRA_YUV444_SSSE3(unsigned int w, unsigned int h, const uint8_t* in_data, int in_stride, uint8_t* const out_data[3], const int out_stride[3]); 31 | void Convert_BGRA_YUV422_SSSE3(unsigned int w, unsigned int h, const uint8_t* in_data, int in_stride, uint8_t* const out_data[3], const int out_stride[3]); 32 | void Convert_BGRA_YUV420_SSSE3(unsigned int w, unsigned int h, const uint8_t* in_data, int in_stride, uint8_t* const out_data[3], const int out_stride[3]); 33 | void Convert_BGRA_NV12_SSSE3(unsigned int w, unsigned int h, const uint8_t* in_data, int in_stride, uint8_t* const out_data[2], const int out_stride[2]); 34 | void Convert_BGRA_BGR_SSSE3(unsigned int w, unsigned int h, const uint8_t* in_data, int in_stride, uint8_t* out_data, int out_stride); 35 | #endif 36 | -------------------------------------------------------------------------------- /src/AV/Input/PulseAudioInput.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2017 Maarten Baert 3 | 4 | This file is part of SimpleScreenRecorder. 5 | 6 | SimpleScreenRecorder is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | SimpleScreenRecorder is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with SimpleScreenRecorder. If not, see . 18 | */ 19 | 20 | #pragma once 21 | #include "Global.h" 22 | 23 | #if SSR_USE_PULSEAUDIO 24 | 25 | #include "SourceSink.h" 26 | #include "MutexDataPair.h" 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | class PulseAudioInput : public AudioSource { 35 | 36 | public: 37 | struct Source { 38 | std::string m_name, m_description; 39 | inline Source(const std::string& name, const std::string& description) : m_name(name), m_description(description) {} 40 | }; 41 | 42 | private: 43 | static const int64_t START_DELAY; 44 | 45 | private: 46 | QString m_source_name; 47 | unsigned int m_sample_rate, m_channels; 48 | 49 | pa_mainloop *m_pa_mainloop; 50 | pa_context *m_pa_context; 51 | pa_stream *m_pa_stream; 52 | unsigned int m_pa_period_size; 53 | 54 | bool m_stream_is_monitor; 55 | bool m_stream_suspended, m_stream_moved; 56 | 57 | std::thread m_thread; 58 | std::atomic m_should_stop, m_error_occurred; 59 | 60 | public: 61 | PulseAudioInput(const QString& source_name, unsigned int sample_rate); 62 | ~PulseAudioInput(); 63 | 64 | // Returns whether an error has occurred in the input thread. 65 | // This function is thread-safe. 66 | inline bool HasErrorOccurred() { return m_error_occurred; } 67 | 68 | public: 69 | static std::vector GetSourceList(); 70 | 71 | private: 72 | void Init(); 73 | void Free(); 74 | 75 | void DetectMonitor(); 76 | 77 | static void SourceInfoCallback(pa_context* context, const pa_source_info* info, int eol, void* userdata); 78 | static void SuspendedCallback(pa_stream* stream, void* userdata); 79 | static void MovedCallback(pa_stream* stream, void* userdata); 80 | 81 | void InputThread(); 82 | 83 | }; 84 | 85 | #endif 86 | -------------------------------------------------------------------------------- /src/AV/FastScaler_Scale_Generic.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2017 Maarten Baert 3 | 4 | This file is part of SimpleScreenRecorder. 5 | 6 | SimpleScreenRecorder is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | SimpleScreenRecorder is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with SimpleScreenRecorder. If not, see . 18 | */ 19 | 20 | #include "FastScaler_Scale_Generic.h" 21 | 22 | #include "TempBuffer.h" 23 | 24 | void Scale_BGRA_Generic(unsigned int in_w, unsigned int in_h, const uint8_t* in_data, int in_stride, 25 | unsigned int out_w, unsigned int out_h, uint8_t* out_data, int out_stride, 26 | MipMapFunction mipmap_function, BilinearFunction bilinear_function) { 27 | 28 | // no scaling? 29 | if(in_w == out_w && in_h == out_h) { 30 | if(in_stride == out_stride) { 31 | memcpy(out_data, in_data, in_stride * in_h); 32 | } else { 33 | for(unsigned int out_j = 0; out_j < out_h; ++out_j) { 34 | memcpy(out_data, in_data, in_w * 4); 35 | in_data += in_stride; 36 | out_data += out_stride; 37 | } 38 | } 39 | return; 40 | } 41 | 42 | // calculate mipmap factors 43 | unsigned int mx = 0, my = 0; 44 | while((out_w << (mx + 1)) <= in_w) ++mx; 45 | while((out_h << (my + 1)) <= in_h) ++my; 46 | if(mx + my > 8) { 47 | if(mx <= 4) 48 | my = 8 - mx; 49 | else if(my <= 4) 50 | mx = 8 - my; 51 | else 52 | mx = my = 4; 53 | } 54 | 55 | // pure mipmap scaling? 56 | if((out_w << mx) == in_w && (out_h << my) == in_h) { 57 | mipmap_function(in_w, in_h, in_data, in_stride, out_data, out_stride, mx, my); 58 | return; 59 | } 60 | 61 | // create mipmap 62 | TempBuffer mipmap; 63 | if(mx != 0 || my != 0) { 64 | unsigned int mipmap_w = ((in_w - 1) >> mx) + 1, mipmap_h = ((in_h - 1) >> my) + 1; 65 | int mipmap_stride = grow_align16(mipmap_w * 4); 66 | mipmap.Alloc(mipmap_stride * mipmap_h); 67 | mipmap_function(in_w, in_h, in_data, in_stride, mipmap.GetData(), mipmap_stride, mx, my); 68 | in_data = mipmap.GetData(); 69 | in_stride = mipmap_stride; 70 | } 71 | 72 | bilinear_function(in_w, in_h, in_data, in_stride, out_w, out_h, out_data, out_stride, mx, my); 73 | 74 | } 75 | 76 | -------------------------------------------------------------------------------- /src/GUI/AudioPreviewer.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2017 Maarten Baert 3 | 4 | This file is part of SimpleScreenRecorder. 5 | 6 | SimpleScreenRecorder is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | SimpleScreenRecorder is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with SimpleScreenRecorder. If not, see . 18 | */ 19 | 20 | #pragma once 21 | #include "Global.h" 22 | 23 | #include "SampleCast.h" 24 | #include "SourceSink.h" 25 | #include "MutexDataPair.h" 26 | 27 | class AudioPreviewer : public QWidget, public AudioSink { 28 | Q_OBJECT 29 | 30 | private: 31 | struct ChannelData { 32 | float m_current_peak, m_current_rms; 33 | float m_next_peak, m_next_rms; 34 | inline ChannelData() { m_current_peak = m_current_rms = m_next_peak = m_next_rms = 0.0f; } 35 | template 36 | inline void Analyze(IN sample) { 37 | float val = fabs(SampleCast(sample)); 38 | m_next_peak = fmax(m_next_peak, val); 39 | m_next_rms += val * val; 40 | } 41 | }; 42 | struct SharedData { 43 | std::vector m_channel_data; 44 | unsigned int m_next_samples; 45 | int64_t m_next_frame_time; 46 | unsigned int m_frame_rate; 47 | }; 48 | typedef MutexDataPair::Lock SharedLock; 49 | 50 | private: 51 | MutexDataPair m_shared_data; 52 | 53 | public: 54 | AudioPreviewer(QWidget* parent); 55 | ~AudioPreviewer(); 56 | 57 | // Resets the preview. 58 | // This function is thread-safe. 59 | void Reset(); 60 | 61 | // Changes the preview frame rate. 62 | // This function is thread-safe. 63 | void SetFrameRate(unsigned int frame_rate); 64 | 65 | // Reads audio samples from the audio source. 66 | // This function is thread-safe. 67 | virtual void ReadAudioSamples(unsigned int channels, unsigned int sample_rate, AVSampleFormat format, unsigned int sample_count, const uint8_t* data, int64_t timestamp) override; 68 | 69 | virtual QSize minimumSizeHint() const override { return QSize(100, 21); } 70 | virtual QSize sizeHint() const override { return QSize(100, 21); } 71 | 72 | protected: 73 | virtual void paintEvent(QPaintEvent* event) override; 74 | 75 | signals: 76 | void NeedsUpdate(); 77 | 78 | }; 79 | -------------------------------------------------------------------------------- /src/GUI/MainWindow.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2017 Maarten Baert 3 | 4 | This file is part of SimpleScreenRecorder. 5 | 6 | SimpleScreenRecorder is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | SimpleScreenRecorder is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with SimpleScreenRecorder. If not, see . 18 | */ 19 | 20 | #pragma once 21 | #include "Global.h" 22 | 23 | class PageWelcome; 24 | class PageInput; 25 | class PageOutput; 26 | class PageRecord; 27 | class PageDone; 28 | 29 | class MainWindow : public QMainWindow { 30 | Q_OBJECT 31 | 32 | public: 33 | enum enum_nvidia_disable_flipping { 34 | NVIDIA_DISABLE_FLIPPING_ASK, 35 | NVIDIA_DISABLE_FLIPPING_YES, 36 | NVIDIA_DISABLE_FLIPPING_NO, 37 | NVIDIA_DISABLE_FLIPPING_COUNT // must be last 38 | }; 39 | 40 | public: 41 | static const QString WINDOW_CAPTION; 42 | 43 | private: 44 | enum_nvidia_disable_flipping m_nvidia_disable_flipping; 45 | bool m_nvidia_reenable_flipping; 46 | 47 | QRect m_old_geometry; 48 | 49 | QStackedLayout *m_stacked_layout; 50 | PageWelcome *m_page_welcome; 51 | PageInput *m_page_input; 52 | PageOutput *m_page_output; 53 | PageRecord *m_page_record; 54 | PageDone *m_page_done; 55 | 56 | public: 57 | MainWindow(); 58 | ~MainWindow(); 59 | 60 | void LoadSettings(); 61 | void SaveSettings(); 62 | 63 | bool Validate(); 64 | 65 | protected: 66 | virtual void closeEvent(QCloseEvent* event) override; 67 | 68 | public: 69 | inline PageInput* GetPageInput() { return m_page_input; } 70 | inline PageOutput* GetPageOutput() { return m_page_output; } 71 | 72 | inline enum_nvidia_disable_flipping GetNVidiaDisableFlipping() { return m_nvidia_disable_flipping; } 73 | 74 | inline void SetNVidiaDisableFlipping(enum_nvidia_disable_flipping flipping) { m_nvidia_disable_flipping = (enum_nvidia_disable_flipping) clamp((unsigned int) flipping, 0u, (unsigned int) NVIDIA_DISABLE_FLIPPING_COUNT - 1); } 75 | 76 | public slots: 77 | void GoPageWelcome(); 78 | void GoPageInput(); 79 | void GoPageOutput(); 80 | void GoPageRecord(); 81 | void GoPageDone(); 82 | 83 | void OnShowHide(); 84 | void OnSysTrayActivated(QSystemTrayIcon::ActivationReason reason); 85 | 86 | }; 87 | -------------------------------------------------------------------------------- /src/common/EnumStrings.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2017 Maarten Baert 3 | 4 | This file is part of SimpleScreenRecorder. 5 | 6 | SimpleScreenRecorder is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | SimpleScreenRecorder is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with SimpleScreenRecorder. If not, see . 18 | */ 19 | 20 | #pragma once 21 | #include "Global.h" 22 | 23 | template 24 | class EnumStrings { 25 | 26 | private: 27 | static const EnumStrings SINGLETON; 28 | 29 | private: 30 | std::vector > m_to_string, m_from_string; 31 | 32 | private: 33 | inline static bool CompareFirst(const std::pair& a, const std::pair& b) { return (a.first < b.first); } 34 | inline static bool CompareSecond(const std::pair& a, const std::pair& b) { return (a.second < b.second); } 35 | 36 | public: 37 | EnumStrings(std::initializer_list > list) { 38 | m_to_string = m_from_string = list; 39 | std::sort(m_to_string.begin(), m_to_string.end(), CompareFirst); 40 | std::sort(m_from_string.begin(), m_from_string.end(), CompareSecond); 41 | } 42 | inline static QString ToString(E value) { 43 | auto it = std::lower_bound(SINGLETON.m_to_string.begin(), SINGLETON.m_to_string.end(), std::make_pair(value, QString()), CompareFirst); 44 | if(it == SINGLETON.m_to_string.end() || it->first != value) { 45 | assert(false); 46 | return QString(); 47 | } 48 | return it->second; 49 | } 50 | inline static E FromString(const QString& string, E fallback) { 51 | auto it = std::lower_bound(SINGLETON.m_from_string.begin(), SINGLETON.m_from_string.end(), std::make_pair((E) 0, string), CompareSecond); 52 | if(it == SINGLETON.m_from_string.end() || it->second != string) 53 | return fallback; 54 | return it->first; 55 | } 56 | 57 | }; 58 | 59 | template 60 | inline QString EnumToString(E value) { return EnumStrings::ToString(value); } 61 | template 62 | inline E StringToEnum(const QString& string, E fallback) { return EnumStrings::FromString(string, fallback); } 63 | 64 | #define ENUMSTRINGS(E) template<> const EnumStrings EnumStrings::SINGLETON 65 | -------------------------------------------------------------------------------- /src/GUI/ElidedLabel.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2017 Maarten Baert 3 | 4 | Original code written by Jason Gedge and placed in the public domain. 5 | http://gedgedev.blogspot.be/2010/12/elided-labels-in-qt.html 6 | This is a slightly modified version. 7 | 8 | This file is part of SimpleScreenRecorder. 9 | 10 | SimpleScreenRecorder is free software: you can redistribute it and/or modify 11 | it under the terms of the GNU General Public License as published by 12 | the Free Software Foundation, either version 3 of the License, or 13 | (at your option) any later version. 14 | 15 | SimpleScreenRecorder is distributed in the hope that it will be useful, 16 | but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | GNU General Public License for more details. 19 | 20 | You should have received a copy of the GNU General Public License 21 | along with SimpleScreenRecorder. If not, see . 22 | */ 23 | 24 | #include "ElidedLabel.h" 25 | 26 | #include 27 | #include 28 | 29 | ElidedLabel::ElidedLabel(QWidget* parent, Qt::WindowFlags f) 30 | : QLabel(parent, f), m_elide_mode(Qt::ElideRight) { 31 | setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Preferred); 32 | } 33 | 34 | ElidedLabel::ElidedLabel(const QString& txt, QWidget* parent, Qt::WindowFlags f) 35 | : QLabel(txt, parent, f), m_elide_mode(Qt::ElideRight) { 36 | setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Preferred); 37 | } 38 | 39 | ElidedLabel::ElidedLabel(const QString& txt, Qt::TextElideMode elideMode, QWidget* parent, Qt::WindowFlags f) 40 | : QLabel(txt, parent, f), m_elide_mode(elideMode) { 41 | setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Preferred); 42 | } 43 | 44 | void ElidedLabel::setText(const QString& txt) { 45 | QLabel::setText(txt); 46 | cacheElidedText(geometry().width()); 47 | setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Preferred); 48 | } 49 | 50 | void ElidedLabel::cacheElidedText(int w) { 51 | m_cached_elided_text = fontMetrics().elidedText(text(), m_elide_mode, w, (buddy() == NULL)? 0 : Qt::TextShowMnemonic); 52 | } 53 | 54 | void ElidedLabel::resizeEvent(QResizeEvent* e) { 55 | QLabel::resizeEvent(e); 56 | cacheElidedText(e->size().width()); 57 | } 58 | 59 | void ElidedLabel::paintEvent(QPaintEvent* e) { 60 | if(m_elide_mode == Qt::ElideNone) { 61 | QLabel::paintEvent(e); 62 | } else { 63 | QPainter p(this); 64 | p.drawText(0, 0, geometry().width(), geometry().height(), 65 | QStyle::visualAlignment(text().isRightToLeft()? Qt::RightToLeft : Qt::LeftToRight, alignment()) | ((buddy() == NULL)? 0 : Qt::TextShowMnemonic), 66 | m_cached_elided_text); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/GUI/VideoPreviewer.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2017 Maarten Baert 3 | 4 | This file is part of SimpleScreenRecorder. 5 | 6 | SimpleScreenRecorder is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | SimpleScreenRecorder is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with SimpleScreenRecorder. If not, see . 18 | */ 19 | 20 | #pragma once 21 | #include "Global.h" 22 | 23 | #include "SourceSink.h" 24 | #include "MutexDataPair.h" 25 | #include "FastScaler.h" 26 | #include "TempBuffer.h" 27 | 28 | class VideoPreviewer : public QWidget, public VideoSink { 29 | Q_OBJECT 30 | 31 | private: 32 | struct SharedData { 33 | 34 | // current image 35 | std::shared_ptr > m_image_buffer; 36 | int m_image_stride; 37 | QSize m_image_size; 38 | 39 | // frame rate control 40 | unsigned int m_frame_rate; 41 | int64_t m_next_frame_time; 42 | 43 | // widget properties 44 | bool m_is_visible; 45 | QSize m_source_size, m_widget_size; 46 | 47 | }; 48 | typedef MutexDataPair::Lock SharedLock; 49 | 50 | private: 51 | FastScaler m_fast_scaler; 52 | 53 | MutexDataPair m_shared_data; 54 | 55 | public: 56 | VideoPreviewer(QWidget* parent); 57 | ~VideoPreviewer(); 58 | 59 | // Resets the preview. 60 | // This function is thread-safe. 61 | void Reset(); 62 | 63 | // Changes the preview frame rate. 64 | // This function is thread-safe. 65 | void SetFrameRate(unsigned int frame_rate); 66 | 67 | // Returns the preferred next video timestamp. 68 | // This function is thread-safe. 69 | virtual int64_t GetNextVideoTimestamp() override; 70 | 71 | // Reads a video frame from the video source. 72 | // This function is thread-safe. 73 | virtual void ReadVideoFrame(unsigned int width, unsigned int height, const uint8_t* data, int stride, AVPixelFormat format, int64_t timestamp) override; 74 | 75 | virtual QSize sizeHint() const override { return QSize(100, 100); } 76 | 77 | protected: 78 | virtual void showEvent(QShowEvent* event) override; 79 | virtual void hideEvent(QHideEvent* event) override; 80 | virtual void resizeEvent(QResizeEvent* event) override; 81 | virtual void paintEvent(QPaintEvent* event) override; 82 | 83 | signals: 84 | void NeedsUpdate(); 85 | 86 | }; 87 | -------------------------------------------------------------------------------- /src/AV/Input/JACKInput.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2017 Maarten Baert 3 | 4 | This file is part of SimpleScreenRecorder. 5 | 6 | SimpleScreenRecorder is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | SimpleScreenRecorder is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with SimpleScreenRecorder. If not, see . 18 | */ 19 | 20 | #pragma once 21 | #include "Global.h" 22 | 23 | #if SSR_USE_JACK 24 | 25 | #include "SourceSink.h" 26 | #include "LockFreeMessageQueue.h" 27 | 28 | #include 29 | 30 | class JACKInput : public AudioSource { 31 | 32 | public: 33 | static const unsigned int RING_BUFFER_SIZE; 34 | 35 | private: 36 | enum enum_eventtype : int { 37 | EVENTTYPE_HOLE, 38 | EVENTTYPE_DATA, 39 | }; 40 | struct EventData { 41 | int64_t m_timestamp; 42 | unsigned int m_sample_rate, m_sample_count; 43 | }; 44 | struct ConnectCommand { 45 | bool m_connect; 46 | std::string m_source, m_destination; 47 | }; 48 | struct SharedData { 49 | std::vector m_connect_commands; 50 | }; 51 | typedef MutexDataPair::Lock SharedLock; 52 | 53 | private: 54 | bool m_connect_system_capture, m_connect_system_playback; 55 | unsigned int m_channels; 56 | 57 | std::atomic m_jackthread_sample_rate; 58 | std::atomic m_jackthread_hole; 59 | 60 | LockFreeMessageQueue m_message_queue; 61 | 62 | jack_client_t *m_jack_client; 63 | std::vector m_jack_ports; 64 | 65 | std::thread m_thread; 66 | MutexDataPair m_shared_data; 67 | std::atomic m_should_stop, m_error_occurred; 68 | 69 | public: 70 | JACKInput(bool connect_system_capture, bool connect_system_playback); 71 | ~JACKInput(); 72 | 73 | // Returns whether an error has occurred in the input thread. 74 | // This function is thread-safe. 75 | inline bool HasErrorOccurred() { return m_error_occurred; } 76 | 77 | private: 78 | void Init(); 79 | void Free(); 80 | 81 | static int ProcessCallback(jack_nframes_t nframes, void* arg); 82 | static int SampleRateCallback(jack_nframes_t nframes, void* arg); 83 | static int XRunCallback(void* arg); 84 | static void PortConnectCallback(jack_port_id_t a, jack_port_id_t b, int connect, void* arg); 85 | 86 | void InputThread(); 87 | 88 | }; 89 | 90 | #endif 91 | -------------------------------------------------------------------------------- /glinject/ShmStructs.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2017 Maarten Baert 3 | 4 | Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. 5 | 6 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 7 | */ 8 | 9 | #pragma once 10 | 11 | /* 12 | A captured video stream is transmitted to SimpleScreenRecorder using shared memory files (i.e. files in /dev/shm). 13 | The system is entirely lock-free and thread-safe, but supports only a single reader and a single writer. 14 | 15 | There are two types of files: 16 | 17 | >>>> /dev/shm/ssr-video-PID-SOURCE-DESCRIPTION <<<< 18 | > PID is the process ID of the application, SOURCE is the source of the stream (should be unique for this process), DESCRIPTION can be anything. 19 | > This file contains a GLInjectHeader struct followed by a GLInjectFrameInfo struct for each frame in the ring buffer. 20 | 21 | >>>> /dev/shm/ssr-videoframeNUM-PID-SOURCE-DESCRIPTION <<<< 22 | > NUM is the position of the frame in the ring buffer (starting from zero). 23 | > This file contains one video frame. The file size is not constant, it may be enlarged when the video frame size changes. The size can only increase, not decrease. 24 | 25 | */ 26 | 27 | // Disable padding to make sure the 32-bit and 64-bit libs are compatible. 28 | #pragma pack(push, 1) 29 | 30 | #define GLINJECT_RING_BUFFER_SIZE 4 31 | 32 | #define GLINJECT_IDENTIFIER 0x8af7a476 33 | 34 | #define GLINJECT_FLAG_CAPTURE_ENABLED 0x0001 35 | #define GLINJECT_FLAG_RECORD_CURSOR 0x0002 36 | #define GLINJECT_FLAG_LIMIT_FPS 0x0004 37 | 38 | struct GLInjectHeader { 39 | 40 | // identifier 41 | uint32_t identifier; 42 | 43 | // ring buffer 44 | uint32_t ring_buffer_read_pos, ring_buffer_write_pos; 45 | 46 | // video stream info: set by the captured application 47 | uint32_t current_width, current_height; 48 | uint32_t frame_counter; 49 | 50 | // capture parameters: set by SimpleScreenRecorder 51 | uint32_t capture_flags; 52 | uint32_t capture_target_fps; 53 | 54 | }; 55 | 56 | struct GLInjectFrameInfo { 57 | 58 | // frame info: set by the captured application 59 | int64_t timestamp; 60 | uint32_t width, height; 61 | int32_t stride; // stride can be negative, this means the frame is upside-down (this is typical for OpenGL) 62 | 63 | }; 64 | 65 | #pragma pack(pop) 66 | -------------------------------------------------------------------------------- /glinject/GLInject.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2017 Maarten Baert 3 | 4 | Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. 5 | 6 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 7 | */ 8 | 9 | #include "Global.h" 10 | #include "GLInject.h" 11 | 12 | #include "GLXFrameGrabber.h" 13 | 14 | GLInject::GLInject() { 15 | 16 | #ifdef __x86_64__ 17 | fprintf(stderr, "[SSR-GLInject] Library loaded (64-bit).\n"); 18 | #else 19 | fprintf(stderr, "[SSR-GLInject] Library loaded (32-bit).\n"); 20 | #endif 21 | 22 | } 23 | 24 | GLInject::~GLInject() { 25 | 26 | while(!m_glx_frame_grabbers.empty()) { 27 | delete m_glx_frame_grabbers.back(); 28 | m_glx_frame_grabbers.pop_back(); 29 | } 30 | 31 | fprintf(stderr, "[SSR-GLInject] Library unloaded.\n"); 32 | 33 | } 34 | 35 | GLXFrameGrabber* GLInject::NewGLXFrameGrabber(Display* display, Window window, GLXDrawable drawable) { 36 | GLXFrameGrabber *fg = FindGLXFrameGrabber(display, drawable); 37 | if(fg == NULL) { 38 | fg = new GLXFrameGrabber(display, window, drawable); 39 | m_glx_frame_grabbers.push_back(fg); 40 | } 41 | return fg; 42 | } 43 | 44 | GLXFrameGrabber* GLInject::FindGLXFrameGrabber(Display* display, GLXDrawable drawable) { 45 | for(unsigned int i = 0; i < m_glx_frame_grabbers.size(); ++i) { 46 | if(m_glx_frame_grabbers[i]->GetX11Display() == display && m_glx_frame_grabbers[i]->GetGLXDrawable() == drawable) 47 | return m_glx_frame_grabbers[i]; 48 | } 49 | return NULL; 50 | } 51 | 52 | void GLInject::DeleteGLXFrameGrabberByWindow(Display* display, Window window) { 53 | for(unsigned int i = m_glx_frame_grabbers.size(); i > 0; ) { 54 | --i; 55 | if(m_glx_frame_grabbers[i]->GetX11Display() == display && m_glx_frame_grabbers[i]->GetX11Window() == window) { 56 | delete m_glx_frame_grabbers[i]; 57 | m_glx_frame_grabbers[i] = m_glx_frame_grabbers.back(); 58 | m_glx_frame_grabbers.pop_back(); 59 | } 60 | } 61 | } 62 | 63 | void GLInject::DeleteGLXFrameGrabberByDrawable(Display* display, GLXDrawable drawable) { 64 | for(unsigned int i = m_glx_frame_grabbers.size(); i > 0; ) { 65 | --i; 66 | if(m_glx_frame_grabbers[i]->GetX11Display() == display && m_glx_frame_grabbers[i]->GetGLXDrawable() == drawable) { 67 | delete m_glx_frame_grabbers[i]; 68 | m_glx_frame_grabbers[i] = m_glx_frame_grabbers.back(); 69 | m_glx_frame_grabbers.pop_back(); 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/AV/Input/SSRVideoStreamReader.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2017 Maarten Baert 3 | 4 | This file is part of SimpleScreenRecorder. 5 | 6 | SimpleScreenRecorder is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | SimpleScreenRecorder is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with SimpleScreenRecorder. If not, see . 18 | */ 19 | 20 | #pragma once 21 | #include "Global.h" 22 | 23 | #include "SSRVideoStream.h" 24 | 25 | #include "../glinject/ShmStructs.h" 26 | 27 | class SSRVideoStreamReader { 28 | 29 | private: 30 | struct FrameData { 31 | std::string m_filename_frame; 32 | int m_fd_frame; 33 | void *m_mmap_ptr_frame; 34 | size_t m_mmap_size_frame; 35 | }; 36 | 37 | private: 38 | SSRVideoStream m_stream; 39 | std::string m_channel_directory, m_filename_main; 40 | size_t m_page_size; 41 | 42 | int64_t m_fps_last_timestamp; 43 | uint32_t m_fps_last_counter; 44 | double m_fps_current; 45 | 46 | int m_fd_main, m_file_lock; 47 | void *m_mmap_ptr_main; 48 | size_t m_mmap_size_main; 49 | 50 | FrameData m_frame_data[GLINJECT_RING_BUFFER_SIZE]; 51 | 52 | public: 53 | SSRVideoStreamReader(const std::string& channel, const SSRVideoStream& stream); 54 | ~SSRVideoStreamReader(); 55 | 56 | private: 57 | void Init(); 58 | void Free(); 59 | 60 | public: 61 | // Reads the current size of the stream. If the stream hasn't been started yet, this will be 0x0. 62 | void GetCurrentSize(unsigned int* width, unsigned int* height); 63 | 64 | // Returns the current fps. 65 | double GetFPS(); 66 | 67 | // Changes the capture parameters. 68 | void ChangeCaptureParameters(unsigned int flags, unsigned int target_fps); 69 | 70 | // Clears the ring buffer (i.e. drops all frames). 71 | void Clear(); 72 | 73 | // Checks whether a new frame is available, and returns a pointer to the frame memory if it is. Otherwise it returns NULL. 74 | void* GetFrame(int64_t* timestamp, unsigned int* width, unsigned int* height, int* stride); 75 | 76 | // Drops the current frame and goes to the next frame. 77 | void NextFrame(); 78 | 79 | public: 80 | 81 | // Returns the stream that is being read. 82 | inline const SSRVideoStream& GetStream() { return m_stream; } 83 | 84 | private: 85 | inline GLInjectHeader* GetGLInjectHeader() { return (GLInjectHeader*) m_mmap_ptr_main; } 86 | inline GLInjectFrameInfo* GetGLInjectFrameInfo(unsigned int frame) { return (GLInjectFrameInfo*) ((char*) m_mmap_ptr_main + sizeof(GLInjectHeader) + frame * sizeof(GLInjectFrameInfo)); } 87 | 88 | }; 89 | -------------------------------------------------------------------------------- /src/GUI/HotkeyListener.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2017 Maarten Baert 3 | 4 | This file is part of SimpleScreenRecorder. 5 | 6 | SimpleScreenRecorder is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | SimpleScreenRecorder is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with SimpleScreenRecorder. If not, see . 18 | */ 19 | 20 | #pragma once 21 | #include "Global.h" 22 | 23 | struct Hotkey { 24 | unsigned int m_keycode, m_modifiers; 25 | inline bool operator==(const Hotkey& other) const { return (m_keycode == other.m_keycode && m_modifiers == other.m_modifiers); } 26 | inline bool operator<(const Hotkey& other) const { return (m_keycode < other.m_keycode || (m_keycode == other.m_keycode && m_modifiers < other.m_modifiers)); } 27 | }; 28 | 29 | class HotkeyCallback; 30 | typedef std::multimap::iterator HotkeyIterator; 31 | 32 | class HotkeyCallback : public QObject { 33 | Q_OBJECT 34 | 35 | private: 36 | bool m_is_bound; 37 | HotkeyIterator m_iterator; 38 | 39 | public: 40 | HotkeyCallback(); 41 | ~HotkeyCallback(); 42 | 43 | // X11 modifiers: 44 | // - Ctrl = ControlMask 45 | // - Shift = ShiftMask 46 | // - Alt = Mod1Mask 47 | // - Super = Mod4Mask 48 | void Bind(unsigned int keysym, unsigned int modifiers); 49 | void Unbind(); 50 | 51 | public: // internal 52 | void Trigger(); 53 | 54 | signals: 55 | void Triggered(); // important: always use a queued connection for consistent results 56 | 57 | }; 58 | 59 | class HotkeyListener : public QObject { 60 | Q_OBJECT 61 | 62 | private: 63 | std::multimap m_callbacks; 64 | 65 | Display *m_x11_display; 66 | int m_x11_screen; 67 | Window m_x11_root; 68 | 69 | bool m_has_xinput2; 70 | int m_xinput2_opcode; 71 | unsigned int m_xinput2_raw_modifiers; 72 | unsigned long m_xinput2_ignore_serial; 73 | std::set m_xinput2_master_keyboards; 74 | 75 | static HotkeyListener *s_instance; 76 | 77 | public: 78 | HotkeyListener(); 79 | ~HotkeyListener(); 80 | 81 | private: 82 | void Init(); 83 | void Free(); 84 | 85 | void GrabHotkey(const Hotkey& hotkey, bool enable); 86 | void ProcessHotkey(const Hotkey& hotkey); 87 | 88 | public: 89 | inline static HotkeyListener* GetInstance() { assert(s_instance != NULL); return s_instance; } 90 | 91 | public: // internal 92 | HotkeyIterator BindCallback(unsigned int keysym, unsigned int modifiers, HotkeyCallback* callback); 93 | void UnbindCallback(HotkeyIterator it); 94 | 95 | private slots: 96 | void ProcessEvents(); 97 | 98 | }; 99 | -------------------------------------------------------------------------------- /src/AV/Input/GLInjectInput.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2017 Maarten Baert 3 | 4 | This file is part of SimpleScreenRecorder. 5 | 6 | SimpleScreenRecorder is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | SimpleScreenRecorder is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with SimpleScreenRecorder. If not, see . 18 | */ 19 | 20 | #pragma once 21 | #include "Global.h" 22 | 23 | #if SSR_USE_OPENGL_RECORDING 24 | 25 | #include "SourceSink.h" 26 | #include "MutexDataPair.h" 27 | 28 | class SSRVideoStream; 29 | class SSRVideoStreamWatcher; 30 | class SSRVideoStreamReader; 31 | 32 | class GLInjectInput : public VideoSource { 33 | 34 | private: 35 | struct SharedData { 36 | bool m_capturing; 37 | std::unique_ptr m_stream_watcher; 38 | std::unique_ptr m_stream_reader; 39 | }; 40 | typedef MutexDataPair::Lock SharedLock; 41 | 42 | private: 43 | static const int64_t MAX_COMMUNICATION_LATENCY; 44 | 45 | private: 46 | QString m_channel; 47 | bool m_relax_permissions; 48 | unsigned int m_flags; 49 | unsigned int m_target_fps; 50 | 51 | std::thread m_thread; 52 | MutexDataPair m_shared_data; 53 | std::atomic m_should_stop, m_error_occurred; 54 | 55 | public: 56 | GLInjectInput(const QString& channel, bool relax_permissions, bool record_cursor, bool limit_fps, unsigned int target_fps); 57 | ~GLInjectInput(); 58 | 59 | // Reads the current size of the stream. If the stream hasn't been started yet, this will be 0x0. 60 | // This function is thread-safe. 61 | void GetCurrentSize(unsigned int* width, unsigned int* height); 62 | 63 | // Returns the total number of captured frames. 64 | // This function is thread-safe. 65 | double GetFPS(); 66 | 67 | // Start/stop capturing. 68 | // This function is thread-safe. 69 | void SetCapturing(bool capturing); 70 | 71 | // Returns whether an error has occurred in the input thread. 72 | // This function is thread-safe. 73 | inline bool HasErrorOccurred() { return m_error_occurred; } 74 | 75 | static bool LaunchApplication(const QString& channel, bool relax_permissions, const QString& command, const QString& working_directory); 76 | 77 | private: 78 | void Init(); 79 | void Free(); 80 | 81 | bool SwitchStream(SharedData* lock, const SSRVideoStream& stream); 82 | 83 | static void StreamAddCallback(const SSRVideoStream& stream, void* userdata); 84 | static void StreamRemoveCallback(const SSRVideoStream& stream, size_t pos, void* userdata); 85 | 86 | void InputThread(); 87 | 88 | }; 89 | 90 | #endif 91 | -------------------------------------------------------------------------------- /src/AV/Input/X11Input.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2017 Maarten Baert 3 | 4 | This file is part of SimpleScreenRecorder. 5 | 6 | SimpleScreenRecorder is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | SimpleScreenRecorder is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with SimpleScreenRecorder. If not, see . 18 | */ 19 | 20 | #pragma once 21 | #include "Global.h" 22 | 23 | #include "SourceSink.h" 24 | #include "MutexDataPair.h" 25 | 26 | class X11Input : public VideoSource { 27 | 28 | private: 29 | struct Rect { 30 | unsigned int m_x1, m_y1, m_x2, m_y2; 31 | inline Rect() {} 32 | inline Rect(unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2) : m_x1(x1), m_y1(y1), m_x2(x2), m_y2(y2) {} 33 | }; 34 | struct SharedData { 35 | unsigned int m_current_width, m_current_height; 36 | }; 37 | typedef MutexDataPair::Lock SharedLock; 38 | 39 | private: 40 | unsigned int m_x, m_y, m_width, m_height; 41 | bool m_record_cursor, m_follow_cursor, m_follow_fullscreen; 42 | 43 | std::atomic m_frame_counter; 44 | int64_t m_fps_last_timestamp; 45 | uint32_t m_fps_last_counter; 46 | double m_fps_current; 47 | 48 | Display *m_x11_display; 49 | int m_x11_screen; 50 | Window m_x11_root; 51 | Visual *m_x11_visual; 52 | int m_x11_depth; 53 | bool m_x11_use_shm; 54 | XImage *m_x11_image; 55 | XShmSegmentInfo m_x11_shm_info; 56 | bool m_x11_shm_server_attached; 57 | 58 | Rect m_screen_bbox; 59 | std::vector m_screen_rects; 60 | std::vector m_screen_dead_space; 61 | 62 | std::thread m_thread; 63 | MutexDataPair m_shared_data; 64 | std::atomic m_should_stop, m_error_occurred; 65 | 66 | public: 67 | X11Input(unsigned int x, unsigned int y, unsigned int width, unsigned int height, bool record_cursor, bool follow_cursor, bool follow_fullscreen); 68 | ~X11Input(); 69 | 70 | // Reads the current size of the stream. 71 | // This function is thread-safe. 72 | void GetCurrentSize(unsigned int* width, unsigned int* height); 73 | 74 | // Returns the total number of captured frames. 75 | // This function is thread-safe. 76 | double GetFPS(); 77 | 78 | // Returns whether an error has occurred in the input thread. 79 | // This function is thread-safe. 80 | inline bool HasErrorOccurred() { return m_error_occurred; } 81 | 82 | private: 83 | void Init(); 84 | void Free(); 85 | 86 | private: 87 | void AllocateImage(unsigned int width, unsigned int height); 88 | void FreeImage(); 89 | void UpdateScreenConfiguration(); 90 | 91 | private: 92 | void InputThread(); 93 | 94 | }; 95 | -------------------------------------------------------------------------------- /src/common/Dialogs.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2017 Maarten Baert 3 | 4 | This file is part of SimpleScreenRecorder. 5 | 6 | SimpleScreenRecorder is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | SimpleScreenRecorder is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with SimpleScreenRecorder. If not, see . 18 | */ 19 | 20 | #include "Dialogs.h" 21 | 22 | enum_button MessageBox(QMessageBox::Icon icon, QWidget* parent, const QString& title, const QString& text, int buttons, enum_button default_button) { 23 | 24 | // create message box 25 | QMessageBox mb(icon, title, text, QMessageBox::NoButton, parent); 26 | 27 | // button data 28 | struct ButtonData { 29 | enum_button button; 30 | QString text; 31 | QMessageBox::ButtonRole role; 32 | QPushButton *ptr; 33 | }; 34 | ButtonData buttondata[] = { 35 | {BUTTON_OK , QDialogButtonBox::tr("&OK") , QMessageBox::AcceptRole, NULL}, 36 | {BUTTON_CANCEL , QDialogButtonBox::tr("&Cancel") , QMessageBox::RejectRole, NULL}, 37 | {BUTTON_YES , QDialogButtonBox::tr("&Yes") , QMessageBox::YesRole , NULL}, 38 | {BUTTON_YES_ALWAYS, QDialogButtonBox::tr("Yes, always"), QMessageBox::YesRole , NULL}, 39 | {BUTTON_NO , QDialogButtonBox::tr("&No") , QMessageBox::NoRole , NULL}, 40 | {BUTTON_NO_NEVER , QDialogButtonBox::tr("No, never") , QMessageBox::NoRole , NULL}, 41 | }; 42 | 43 | // add buttons 44 | for(unsigned int i = 0; i < sizeof(buttondata) / sizeof(buttondata[0]); ++i) { 45 | if(buttons & buttondata[i].button) { 46 | buttondata[i].ptr = mb.addButton(buttondata[i].text, buttondata[i].role); 47 | if(default_button == buttondata[i].button) 48 | mb.setDefaultButton(buttondata[i].ptr); 49 | } 50 | } 51 | 52 | // show dialog 53 | mb.exec(); 54 | 55 | // check which button was pressed 56 | QAbstractButton *clicked = mb.clickedButton(); 57 | if(clicked == NULL) 58 | return BUTTON_NONE; 59 | for(unsigned int i = 0; i < sizeof(buttondata) / sizeof(buttondata[0]); ++i) { 60 | if(clicked == buttondata[i].ptr) { 61 | return buttondata[i].button; 62 | } 63 | } 64 | return BUTTON_NONE; 65 | 66 | } 67 | 68 | QString InputBox(QWidget* parent, const QString& title, const QString& text, const QString& value) { 69 | 70 | QInputDialog dialog(parent); 71 | dialog.setInputMode(QInputDialog::TextInput); 72 | dialog.setOkButtonText(QDialogButtonBox::tr("&OK")); 73 | dialog.setCancelButtonText(QDialogButtonBox::tr("&Cancel")); 74 | 75 | dialog.setWindowTitle(title); 76 | dialog.setLabelText(text); 77 | dialog.setTextValue(value); 78 | 79 | if(!dialog.exec()) 80 | return QString(); 81 | return dialog.textValue(); 82 | 83 | } 84 | -------------------------------------------------------------------------------- /src/common/CPUFeatures.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2017 Maarten Baert 3 | 4 | This file is part of SimpleScreenRecorder. 5 | 6 | SimpleScreenRecorder is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | SimpleScreenRecorder is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with SimpleScreenRecorder. If not, see . 18 | */ 19 | 20 | #include "CPUFeatures.h" 21 | 22 | #include "Logger.h" 23 | 24 | #if SSR_USE_X86_ASM 25 | 26 | #include 27 | 28 | //#define __cpuid(level, eax, ebx, ecx, edx) __asm__ __volatile__ ("cpuid" : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) : "a" (level)) 29 | //#define __cpuid_count(level, count, eax, ebx, ecx, edx) __asm__ __volatile__ ("cpuid" : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) : "a" (level), "c" (count)) 30 | 31 | bool CPUFeatures::s_mmx = false; 32 | bool CPUFeatures::s_sse = false; 33 | bool CPUFeatures::s_sse2 = false; 34 | bool CPUFeatures::s_sse3 = false; 35 | bool CPUFeatures::s_ssse3 = false; 36 | bool CPUFeatures::s_sse41 = false; 37 | bool CPUFeatures::s_sse42 = false; 38 | bool CPUFeatures::s_avx = false; 39 | bool CPUFeatures::s_avx2 = false; 40 | bool CPUFeatures::s_bmi1 = false; 41 | bool CPUFeatures::s_bmi2 = false; 42 | 43 | void CPUFeatures::Detect() { 44 | 45 | QString str = "[CPUFeatures::Detect] " + Logger::tr("CPU features") + ":"; 46 | 47 | // CPUID exists in i586 ('pentium 1') and higher, older processors are not supported. 48 | // The meaning of ecx/edx bits are listed in table 3-20 and 3-21 ('Feature Information Returned in the ECX/EDX Register') 49 | // from the Intel reference manual (page 589), or in AMD's CPUID reference (they are compatible). 50 | unsigned int eax, ebx, ecx, edx; 51 | __cpuid(0, eax, ebx, ecx, edx); 52 | unsigned int cpuid_max = eax; 53 | 54 | if(cpuid_max >= 1) { 55 | __cpuid(1, eax, ebx, ecx, edx); 56 | if(edx & (1 << 23)) { s_mmx = true; str += " mmx"; } 57 | if(edx & (1 << 25)) { s_sse = true; str += " sse"; } 58 | if(edx & (1 << 26)) { s_sse2 = true; str += " sse2"; } 59 | if(ecx & (1 << 0)) { s_sse3 = true; str += " sse3"; } 60 | if(ecx & (1 << 9)) { s_ssse3 = true; str += " ssse3"; } 61 | if(ecx & (1 << 19)) { s_sse41 = true; str += " sse4_1"; } 62 | if(ecx & (1 << 20)) { s_sse42 = true; str += " sse4_2"; } 63 | if(ecx & (1 << 28)) { s_avx = true; str += " avx"; } 64 | } 65 | 66 | if(cpuid_max >= 7) { 67 | __cpuid_count(7, 0, eax, ebx, ecx, edx); 68 | if(ebx & (1 << 5)) { s_avx2 = true; str += " avx2"; } 69 | if(ebx & (1 << 3)) { s_bmi1 = true; str += " bmi1"; } 70 | if(ebx & (1 << 8)) { s_bmi2 = true; str += " bmi2"; } 71 | } 72 | 73 | Logger::LogInfo(str); 74 | } 75 | 76 | #endif // SSR_USE_X86_ASM 77 | -------------------------------------------------------------------------------- /src/common/QueueBuffer.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2017 Maarten Baert 3 | 4 | This file is part of SimpleScreenRecorder. 5 | 6 | SimpleScreenRecorder is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | SimpleScreenRecorder is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with SimpleScreenRecorder. If not, see . 18 | */ 19 | 20 | #pragma once 21 | #include "Global.h" 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | template 29 | class QueueBuffer { 30 | 31 | private: 32 | T *m_buffer; 33 | size_t m_buffer_size, m_read_pos, m_write_pos; 34 | 35 | public: 36 | inline QueueBuffer() { 37 | m_buffer_size = 1024; 38 | m_buffer = (T*) malloc(sizeof(T) * m_buffer_size); 39 | if(m_buffer == NULL) 40 | throw std::bad_alloc(); 41 | m_read_pos = 0; 42 | m_write_pos = 0; 43 | } 44 | inline ~QueueBuffer() { 45 | free(m_buffer); 46 | } 47 | inline T* Reserve(size_t count) { 48 | if(m_write_pos + count > m_buffer_size) { 49 | size_t new_buffer_size = (m_write_pos - m_read_pos + count) * 2; 50 | if(new_buffer_size > m_buffer_size) { 51 | T *new_buffer = (T*) malloc(sizeof(T) * new_buffer_size); 52 | if(new_buffer == NULL) 53 | throw std::bad_alloc(); 54 | memcpy(new_buffer, m_buffer + m_read_pos, sizeof(T) * (m_write_pos - m_read_pos)); 55 | free(m_buffer); 56 | m_buffer = new_buffer; 57 | m_buffer_size = new_buffer_size; 58 | } else { 59 | memmove(m_buffer, m_buffer + m_read_pos, sizeof(T) * (m_write_pos - m_read_pos)); 60 | } 61 | m_write_pos -= m_read_pos; 62 | m_read_pos = 0; 63 | } 64 | return m_buffer + m_write_pos; 65 | } 66 | inline void Push(size_t count) { 67 | assert(m_write_pos + count <= m_buffer_size); 68 | m_write_pos += count; 69 | } 70 | inline void Push(const T* data, size_t count) { 71 | T *target = Reserve(count); 72 | memcpy(target, data, sizeof(T) * count); 73 | Push(count); 74 | } 75 | inline void Pop(size_t count) { 76 | assert(m_read_pos + count <= m_write_pos); 77 | m_read_pos += count; 78 | if(m_read_pos == m_write_pos) { 79 | m_read_pos = 0; 80 | m_write_pos = 0; 81 | } 82 | } 83 | inline void Pop(T* data, size_t count) { 84 | assert(count <= GetSize()); 85 | memcpy(data, GetData(), sizeof(T) * count); 86 | Pop(count); 87 | } 88 | inline void Clear() { 89 | m_read_pos = 0; 90 | m_write_pos = 0; 91 | } 92 | 93 | public: 94 | inline T* GetData() { return m_buffer + m_read_pos; } 95 | inline size_t GetSize() { return m_write_pos - m_read_pos; } 96 | inline bool IsEmpty() { return (m_read_pos == m_write_pos); } 97 | inline T& operator[](size_t i) { return m_buffer[m_read_pos + i]; } 98 | 99 | // noncopyable 100 | QueueBuffer(const QueueBuffer&) = delete; 101 | QueueBuffer& operator=(const QueueBuffer&) = delete; 102 | 103 | }; 104 | -------------------------------------------------------------------------------- /src/AV/SourceSink.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2017 Maarten Baert 3 | 4 | This file is part of SimpleScreenRecorder. 5 | 6 | SimpleScreenRecorder is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | SimpleScreenRecorder is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with SimpleScreenRecorder. If not, see . 18 | */ 19 | 20 | #include "SourceSink.h" 21 | 22 | BaseSource::BaseSource() { 23 | } 24 | BaseSource::~BaseSource() { 25 | SharedLock lock(&m_shared_data); 26 | for(SinkData &s : lock->m_sinks) { 27 | s.sink->m_source = NULL; 28 | } 29 | } 30 | 31 | BaseSink::BaseSink() { 32 | m_source = NULL; 33 | m_priority = 0; 34 | } 35 | BaseSink::~BaseSink() { 36 | // Classes that inherit a sink should disconnect themselves in the destructor before doing anything else, 37 | // otherwise inputs may try to send data to partially destructed sinks. 38 | assert(m_source == NULL); 39 | } 40 | void BaseSink::ConnectBaseSource(BaseSource* source, int priority) { 41 | if(m_source == source && m_priority == priority) 42 | return; 43 | if(m_source != NULL) { 44 | BaseSource::SharedLock lock(&m_source->m_shared_data); 45 | for(auto it = lock->m_sinks.begin(); it != lock->m_sinks.end(); ++it) { 46 | if(it->sink == this) { 47 | lock->m_sinks.erase(it); 48 | break; 49 | } 50 | } 51 | } 52 | m_source = source; 53 | if(m_source != NULL) { 54 | BaseSource::SharedLock lock(&m_source->m_shared_data); 55 | BaseSource::SinkData data(this, priority); 56 | auto it = std::upper_bound(lock->m_sinks.begin(), lock->m_sinks.end(), data); 57 | lock->m_sinks.insert(it, data); 58 | } 59 | } 60 | 61 | int64_t VideoSource::CalculateNextVideoTimestamp() { 62 | SharedLock lock(&m_shared_data); 63 | for(SinkData &s : lock->m_sinks) { 64 | int64_t timestamp = static_cast(s.sink)->GetNextVideoTimestamp(); 65 | if(timestamp != SINK_TIMESTAMP_NONE) 66 | return timestamp; 67 | } 68 | return SINK_TIMESTAMP_NONE; 69 | } 70 | 71 | void VideoSource::PushVideoFrame(unsigned int width, unsigned int height, const uint8_t* data, int stride, AVPixelFormat format, int64_t timestamp) { 72 | SharedLock lock(&m_shared_data); 73 | for(SinkData &s : lock->m_sinks) { 74 | static_cast(s.sink)->ReadVideoFrame(width, height, data, stride, format, timestamp); 75 | } 76 | } 77 | 78 | void VideoSource::PushVideoPing(int64_t timestamp) { 79 | SharedLock lock(&m_shared_data); 80 | for(SinkData &s : lock->m_sinks) { 81 | static_cast(s.sink)->ReadVideoPing(timestamp); 82 | } 83 | } 84 | 85 | void AudioSource::PushAudioSamples(unsigned int channels, unsigned int sample_rate, AVSampleFormat format, unsigned int sample_count, const uint8_t* data, int64_t timestamp) { 86 | SharedLock lock(&m_shared_data); 87 | for(SinkData &s : lock->m_sinks) { 88 | static_cast(s.sink)->ReadAudioSamples(channels, sample_rate, format, sample_count, data, timestamp); 89 | } 90 | } 91 | 92 | void AudioSource::PushAudioHole() { 93 | SharedLock lock(&m_shared_data); 94 | for(SinkData &s : lock->m_sinks) { 95 | static_cast(s.sink)->ReadAudioHole(); 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /src/AV/FastResampler_FirFilter_Fallback.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2017 Maarten Baert 3 | 4 | This file is part of SimpleScreenRecorder. 5 | 6 | SimpleScreenRecorder is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | SimpleScreenRecorder is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with SimpleScreenRecorder. If not, see . 18 | */ 19 | 20 | #include "FastResampler_FirFilter.h" 21 | 22 | void FastResampler_FirFilter2_C1_Fallback(unsigned int channels, unsigned int filter_length, float* coef1, float* coef2, float frac, float* input, float* output) { 23 | Q_UNUSED(channels); 24 | float sum[4] = {0.0f}; 25 | for(unsigned int i = 0; i < filter_length / 4; ++i) { 26 | float filter_value[4] = { 27 | coef1[0] + (coef2[0] - coef1[0]) * frac, 28 | coef1[1] + (coef2[1] - coef1[1]) * frac, 29 | coef1[2] + (coef2[2] - coef1[2]) * frac, 30 | coef1[3] + (coef2[3] - coef1[3]) * frac, 31 | }; 32 | coef1 += 4; coef2 += 4; 33 | sum[0] += input[0] * filter_value[0]; 34 | sum[1] += input[1] * filter_value[1]; 35 | sum[2] += input[2] * filter_value[2]; 36 | sum[3] += input[3] * filter_value[3]; 37 | input += 4; 38 | } 39 | output[0] = sum[0] + sum[1] + sum[2] + sum[3]; 40 | } 41 | 42 | void FastResampler_FirFilter2_C2_Fallback(unsigned int channels, unsigned int filter_length, float* coef1, float* coef2, float frac, float* input, float* output) { 43 | Q_UNUSED(channels); 44 | float sum[4] = {0.0f}; 45 | for(unsigned int i = 0; i < filter_length / 4; ++i) { 46 | float filter_value[4] = { 47 | coef1[0] + (coef2[0] - coef1[0]) * frac, 48 | coef1[1] + (coef2[1] - coef1[1]) * frac, 49 | coef1[2] + (coef2[2] - coef1[2]) * frac, 50 | coef1[3] + (coef2[3] - coef1[3]) * frac, 51 | }; 52 | coef1 += 4; coef2 += 4; 53 | sum[0] += input[0] * filter_value[0]; 54 | sum[1] += input[1] * filter_value[0]; 55 | sum[2] += input[2] * filter_value[1]; 56 | sum[3] += input[3] * filter_value[1]; 57 | sum[0] += input[4] * filter_value[2]; 58 | sum[1] += input[5] * filter_value[2]; 59 | sum[2] += input[6] * filter_value[3]; 60 | sum[3] += input[7] * filter_value[3]; 61 | input += 8; 62 | } 63 | output[0] = sum[0] + sum[2]; 64 | output[1] = sum[1] + sum[3]; 65 | } 66 | 67 | void FastResampler_FirFilter2_Cn_Fallback(unsigned int channels, unsigned int filter_length, float* coef1, float* coef2, float frac, float* input, float* output) { 68 | Q_UNUSED(channels); 69 | for(unsigned int c = 0; c < channels; ++c) { 70 | float sum[4] = {0.0f}; 71 | float *input2 = input + c; 72 | for(unsigned int i = 0; i < filter_length / 4; ++i) { 73 | float filter_value[4] = { 74 | coef1[0] + (coef2[0] - coef1[0]) * frac, 75 | coef1[1] + (coef2[1] - coef1[1]) * frac, 76 | coef1[2] + (coef2[2] - coef1[2]) * frac, 77 | coef1[3] + (coef2[3] - coef1[3]) * frac, 78 | }; 79 | coef1 += 4; coef2 += 4; 80 | sum[0] += *input2 * filter_value[0]; input2 += channels; 81 | sum[1] += *input2 * filter_value[1]; input2 += channels; 82 | sum[2] += *input2 * filter_value[2]; input2 += channels; 83 | sum[3] += *input2 * filter_value[3]; input2 += channels; 84 | } 85 | output[c] = sum[0] + sum[1] + sum[2] + sum[3]; 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/AV/SampleCast.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2017 Maarten Baert 3 | 4 | This file is part of SimpleScreenRecorder. 5 | 6 | SimpleScreenRecorder is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | SimpleScreenRecorder is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with SimpleScreenRecorder. If not, see . 18 | */ 19 | 20 | #pragma once 21 | #include "Global.h" 22 | 23 | template OUT SampleCast(IN x); 24 | template<> inline int16_t SampleCast(int16_t x) { return x; } 25 | template<> inline int16_t SampleCast(float x) { return lrint(fmin(fmax(x * 32768.0f, -32768.0f), 32767.0f)); } 26 | template<> inline float SampleCast(int16_t x) { return (float) x * (1.0f / 32768.0f); } 27 | template<> inline float SampleCast(float x) { return x; } 28 | 29 | template IN SampleMix(IN a, IN b); 30 | template<> inline int16_t SampleMix(int16_t a, int16_t b) { return (a + b) >> 1; } 31 | template<> inline float SampleMix(float a, float b) { return (a + b) * 0.5f; } 32 | 33 | // Simple sample format conversion. 34 | // The in_step and out_step parameters are useful for converting between planar and interleaved audio. 35 | template 36 | inline void SampleCopy(unsigned int sample_count, const IN* in_data, int in_step, OUT* out_data, int out_step) { 37 | for(unsigned int i = 0; i < sample_count; ++i) { 38 | *out_data = SampleCast(*in_data); 39 | in_data += in_step; 40 | out_data += out_step; 41 | } 42 | } 43 | 44 | // Sample format conversion and channel remapping in one step. 45 | // This function only supports interleaved audio. 46 | template 47 | inline void SampleChannelRemap(unsigned int sample_count, const IN* in_data, unsigned int in_channels, OUT* out_data, unsigned int out_channels) { 48 | if(in_channels == out_channels) { // no remapping needed 49 | for(unsigned int i = 0; i < sample_count * in_channels; ++i) { 50 | *(out_data++) = SampleCast(*(in_data++)); 51 | } 52 | } else if(in_channels == 1 && out_channels == 2) { // mono to stereo 53 | for(unsigned int i = 0; i < sample_count; ++i) { 54 | OUT val = SampleCast(*(in_data++)); 55 | *(out_data++) = val; 56 | *(out_data++) = val; 57 | } 58 | } else if(in_channels == 2 && out_channels == 1) { // stereo to mono 59 | for(unsigned int i = 0; i < sample_count; ++i) { 60 | OUT val1 = SampleCast(*(in_data++)); 61 | OUT val2 = SampleCast(*(in_data++)); 62 | *(out_data++) = SampleMix(val1, val2); 63 | } 64 | } else if(in_channels < out_channels) { // fill additional channels with silence 65 | for(unsigned int i = 0; i < sample_count; ++i) { 66 | for(unsigned int j = 0; j < in_channels; ++j) 67 | *(out_data++) = SampleCast(*(in_data++)); 68 | for(unsigned int j = 0; j < out_channels - in_channels; ++j) 69 | *(out_data++) = (OUT) 0; 70 | } 71 | } else { // drop redundant channels 72 | for(unsigned int i = 0; i < sample_count; ++i) { 73 | for(unsigned int j = 0; j < out_channels; ++j) 74 | *(out_data++) = SampleCast(*(in_data++)); 75 | in_data += in_channels - out_channels; 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/SimpleScreenRecorder.pro: -------------------------------------------------------------------------------- 1 | # Don't try to compile this with qmake! This file is only meant for Qt Creator, not for actual compilation. 2 | 3 | QT += core gui 4 | 5 | TARGET = SimpleScreenRecorder 6 | TEMPLATE = app 7 | 8 | DEFINES += SSR_USE_X86_ASM=1 SSR_USE_FFMPEG_VERSIONS=1 SSR_USE_OPENGL_RECORDING=1 SSR_USE_ALSA=1 SSR_USE_PULSEAUDIO=1 SSR_USE_JACK=1 SSR_SYSTEM_DIR=\\"/usr/share/simplescreenrecorder\\" 9 | QMAKE_CXXFLAGS += -std=c++0x -flax-vector-conversions 10 | LIBS += -lavformat -lavcodec -lavutil -lswscale -lX11 -lXext -lXfixes -lasound 11 | 12 | INCLUDEPATH += AV AV/Input AV/Output common GUI 13 | DEPENDPATH += AV AV/Input AV/Output common GUI 14 | 15 | SOURCES += \ 16 | AV/Input/ALSAInput.cpp \ 17 | AV/Input/GLInjectInput.cpp \ 18 | AV/Input/JACKInput.cpp \ 19 | AV/Input/PulseAudioInput.cpp \ 20 | AV/Input/SSRVideoStreamReader.cpp \ 21 | AV/Input/SSRVideoStreamWatcher.cpp \ 22 | AV/Input/X11Input.cpp \ 23 | AV/Output/AudioEncoder.cpp \ 24 | AV/Output/BaseEncoder.cpp \ 25 | AV/Output/Muxer.cpp \ 26 | AV/Output/OutputManager.cpp \ 27 | AV/Output/SyncDiagram.cpp \ 28 | AV/Output/Synchronizer.cpp \ 29 | AV/Output/VideoEncoder.cpp \ 30 | AV/Output/X264Presets.cpp \ 31 | AV/AVWrapper.cpp \ 32 | AV/FastResampler.cpp \ 33 | AV/FastResampler_FirFilter_Fallback.cpp \ 34 | AV/FastResampler_FirFilter_SSE2.cpp \ 35 | AV/FastScaler.cpp \ 36 | AV/FastScaler_Convert_Fallback.cpp \ 37 | AV/FastScaler_Convert_SSSE3.cpp \ 38 | AV/FastScaler_Scale_Fallback.cpp \ 39 | AV/FastScaler_Scale_Generic.cpp \ 40 | AV/FastScaler_Scale_SSSE3.cpp \ 41 | AV/SimpleSynth.cpp \ 42 | AV/SourceSink.cpp \ 43 | common/CPUFeatures.cpp \ 44 | common/Dialogs.cpp \ 45 | common/Logger.cpp \ 46 | GUI/AudioPreviewer.cpp \ 47 | GUI/DialogGLInject.cpp \ 48 | GUI/ElidedLabel.cpp \ 49 | GUI/HiddenScrollArea.cpp \ 50 | GUI/HotkeyListener.cpp \ 51 | GUI/Icons.cpp \ 52 | GUI/MainWindow.cpp \ 53 | GUI/PageDone.cpp \ 54 | GUI/PageInput.cpp \ 55 | GUI/PageOutput.cpp \ 56 | GUI/PageRecord.cpp \ 57 | GUI/PageWelcome.cpp \ 58 | GUI/ProfileBox.cpp \ 59 | GUI/VideoPreviewer.cpp \ 60 | Benchmark.cpp \ 61 | Main.cpp \ 62 | NVidia.cpp 63 | 64 | HEADERS += \ 65 | AV/Input/ALSAInput.h \ 66 | AV/Input/GLInjectInput.h \ 67 | AV/Input/JACKInput.h \ 68 | AV/Input/PulseAudioInput.h \ 69 | AV/Input/SSRVideoStream.h \ 70 | AV/Input/SSRVideoStreamReader.h \ 71 | AV/Input/SSRVideoStreamWatcher.h \ 72 | AV/Input/X11Input.h \ 73 | AV/Output/AudioEncoder.h \ 74 | AV/Output/BaseEncoder.h \ 75 | AV/Output/Muxer.h \ 76 | AV/Output/OutputManager.h \ 77 | AV/Output/OutputSettings.h \ 78 | AV/Output/SyncDiagram.h \ 79 | AV/Output/Synchronizer.h \ 80 | AV/Output/VideoEncoder.h \ 81 | AV/Output/X264Presets.h \ 82 | AV/AVWrapper.h \ 83 | AV/FastResampler.h \ 84 | AV/FastResampler_FirFilter.h \ 85 | AV/FastScaler.h \ 86 | AV/FastScaler_Convert.h \ 87 | AV/FastScaler_Scale.h \ 88 | AV/FastScaler_Scale_Generic.h \ 89 | AV/SampleCast.h \ 90 | AV/SimpleSynth.h \ 91 | AV/SourceSink.h \ 92 | common/CPUFeatures.h \ 93 | common/Dialogs.h \ 94 | common/EnumStrings.h \ 95 | common/LockFreeMessageQueue.h \ 96 | common/Logger.h \ 97 | common/MutexDataPair.h \ 98 | common/QueueBuffer.h \ 99 | common/TempBuffer.h \ 100 | GUI/AudioPreviewer.h \ 101 | GUI/DialogGLInject.h \ 102 | GUI/ElidedLabel.h \ 103 | GUI/HiddenScrollArea.h \ 104 | GUI/HotkeyListener.h \ 105 | GUI/Icons.h \ 106 | GUI/MainWindow.h \ 107 | GUI/PageDone.h \ 108 | GUI/PageInput.h \ 109 | GUI/PageOutput.h \ 110 | GUI/PageRecord.h \ 111 | GUI/PageWelcome.h \ 112 | GUI/ProfileBox.h \ 113 | GUI/VideoPreviewer.h \ 114 | Benchmark.h \ 115 | Global.h \ 116 | Main.h \ 117 | NVidia.h 118 | 119 | RESOURCES += \ 120 | resources.qrc 121 | 122 | -------------------------------------------------------------------------------- /glinject/Global.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2017 Maarten Baert 3 | 4 | Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. 5 | 6 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 7 | */ 8 | 9 | #ifndef GLOBAL_H 10 | #define GLOBAL_H 11 | 12 | #define GL_GLEXT_PROTOTYPES 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | 35 | // generic macro to test version numbers 36 | #define TEST_MAJOR_MINOR(major, minor, required_major, required_minor) (major > required_major || (major == required_major && minor >= required_minor)) 37 | 38 | // test GCC version 39 | #define TEST_GCC_VERSION(major, minor) TEST_MAJOR_MINOR(__GNUC__, __GNUC_MINOR__, major, minor) 40 | 41 | // 'override' was added in GCC 4.7 42 | #if !TEST_GCC_VERSION(4, 7) 43 | #define override 44 | #endif 45 | 46 | // std::atomic_thread_fence exists in GCC 4.6 but it doesn't link properly for some reason 47 | #if !TEST_GCC_VERSION(4, 7) 48 | #define atomic_thread_fence atomic_thread_fence_replacement 49 | namespace std { 50 | inline void atomic_thread_fence_replacement(memory_order) { 51 | __sync_synchronize(); 52 | } 53 | } 54 | #endif 55 | 56 | #define GLINJECT_PRINT(message) { \ 57 | std::cerr << "[SSR-GLInject] " << message << std::endl; \ 58 | } 59 | 60 | class SSRStreamException : public std::exception { 61 | public: 62 | inline virtual const char* what() const throw() override { 63 | return "SSRStreamException"; 64 | } 65 | }; 66 | 67 | // simple function to do 16-byte alignment 68 | inline size_t grow_align16(size_t size) { 69 | return (size_t) (size + 15) & ~((size_t) 15); 70 | } 71 | 72 | // high resolution timer 73 | inline int64_t hrt_time_micro() { 74 | timespec ts; 75 | clock_gettime(CLOCK_MONOTONIC, &ts); 76 | return (uint64_t) ts.tv_sec * (uint64_t) 1000000 + (uint64_t) (ts.tv_nsec / 1000); 77 | } 78 | 79 | // Returns the name of the user. 80 | inline std::string GetUserName() { 81 | std::vector buf(std::max((long) 16384, sysconf(_SC_GETPW_R_SIZE_MAX))); 82 | passwd pwd, *result = NULL; 83 | if(getpwuid_r(geteuid(), &pwd, buf.data(), buf.size(), &result) == 0 && result != NULL) 84 | return std::string(result->pw_name); 85 | return "unknownuser"; 86 | } 87 | 88 | template 89 | T positive_mod(T x, T y) { 90 | T z = x % y; 91 | return (z < 0)? z + y : z; 92 | } 93 | 94 | // Generic number-to-string conversion and vice versa 95 | // Unlike the standard functions, these are locale-independent, and the functions never throw exceptions. 96 | template 97 | inline std::string NumToString(T number) { 98 | std::ostringstream ss; 99 | ss << number; 100 | return ss.str(); 101 | } 102 | template 103 | inline bool StringToNum(const std::string& str, T* number) { 104 | std::istringstream ss(str); 105 | ss >> *number; 106 | return !ss.fail(); 107 | } 108 | 109 | #endif // GLOBAL_H 110 | -------------------------------------------------------------------------------- /src/AV/FastResampler_FirFilter_SSE2.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2017 Maarten Baert 3 | 4 | This file is part of SimpleScreenRecorder. 5 | 6 | SimpleScreenRecorder is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | SimpleScreenRecorder is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with SimpleScreenRecorder. If not, see . 18 | */ 19 | 20 | #include "FastResampler_FirFilter.h" 21 | 22 | #if SSR_USE_X86_ASM 23 | 24 | #include // sse 25 | #include // sse2 26 | 27 | void FastResampler_FirFilter2_C1_SSE2(unsigned int channels, unsigned int filter_length, float* coef1, float* coef2, float frac, float* input, float* output) { 28 | Q_UNUSED(channels); 29 | __m128 sum = _mm_setzero_ps(); 30 | __m128 v_frac = _mm_set1_ps(frac); 31 | for(unsigned int i = 0; i < filter_length / 4; ++i) { 32 | __m128 v_coef1 = _mm_load_ps(coef1), v_coef2 = _mm_load_ps(coef2); 33 | coef1 += 4; coef2 += 4; 34 | __m128 filter_value = _mm_add_ps(v_coef1, _mm_mul_ps(_mm_sub_ps(v_coef2, v_coef1), v_frac)); 35 | __m128 v_input = _mm_loadu_ps(input); 36 | input += 4; 37 | sum = _mm_add_ps(sum, _mm_mul_ps(v_input, filter_value)); 38 | } 39 | __m128 sum2 = _mm_add_ps(sum, _mm_shuffle_ps(sum, sum, 0x0e)); 40 | __m128 sum3 = _mm_add_ss(sum2, _mm_shuffle_ps(sum2, sum2, 0x01)); 41 | _mm_store_ss(output, sum3); 42 | } 43 | 44 | void FastResampler_FirFilter2_C2_SSE2(unsigned int channels, unsigned int filter_length, float* coef1, float* coef2, float frac, float* input, float* output) { 45 | Q_UNUSED(channels); 46 | __m128 sum = _mm_setzero_ps(); 47 | __m128 v_frac = _mm_set1_ps(frac); 48 | for(unsigned int i = 0; i < filter_length / 4; ++i) { 49 | __m128 v_coef1 = _mm_load_ps(coef1), v_coef2 = _mm_load_ps(coef2); 50 | coef1 += 4; coef2 += 4; 51 | __m128 filter_value = _mm_add_ps(v_coef1, _mm_mul_ps(_mm_sub_ps(v_coef2, v_coef1), v_frac)); 52 | __m128 v_input1 = _mm_loadu_ps(input), v_input2 = _mm_loadu_ps(input + 4); 53 | input += 8; 54 | sum = _mm_add_ps(sum, _mm_mul_ps(v_input1, _mm_unpacklo_ps(filter_value, filter_value))); 55 | sum = _mm_add_ps(sum, _mm_mul_ps(v_input2, _mm_unpackhi_ps(filter_value, filter_value))); 56 | } 57 | __m128 sum2 = _mm_add_ps(sum, _mm_shuffle_ps(sum, sum, 0xee)); 58 | _mm_store_sd((double*) output, _mm_castps_pd(sum2)); 59 | } 60 | 61 | void FastResampler_FirFilter2_Cn_SSE2(unsigned int channels, unsigned int filter_length, float* coef1, float* coef2, float frac, float* input, float* output) { 62 | Q_UNUSED(channels); 63 | for(unsigned int c = 0; c < channels; ++c) { 64 | __m128 sum = _mm_setzero_ps(); 65 | __m128 v_frac = _mm_set1_ps(frac); 66 | float *input2 = input + c; 67 | for(unsigned int i = 0; i < filter_length / 4; ++i) { 68 | __m128 v_coef1 = _mm_load_ps(coef1), v_coef2 = _mm_load_ps(coef2); 69 | coef1 += 4; coef2 += 4; 70 | __m128 filter_value = _mm_add_ps(v_coef1, _mm_mul_ps(_mm_sub_ps(v_coef2, v_coef1), v_frac)); 71 | __m128 v_input1 = _mm_load_ss(input2); input2 += channels; 72 | __m128 v_input2 = _mm_load_ss(input2); input2 += channels; 73 | __m128 v_input3 = _mm_load_ss(input2); input2 += channels; 74 | __m128 v_input4 = _mm_load_ss(input2); input2 += channels; 75 | __m128 v_input = _mm_movelh_ps(_mm_unpacklo_ps(v_input1, v_input2), _mm_unpacklo_ps(v_input3, v_input4)); 76 | sum = _mm_add_ps(sum, _mm_mul_ps(v_input, filter_value)); 77 | } 78 | __m128 sum2 = _mm_add_ps(sum, _mm_shuffle_ps(sum, sum, 0x0e)); 79 | __m128 sum3 = _mm_add_ss(sum2, _mm_shuffle_ps(sum2, sum2, 0x01)); 80 | _mm_store_ss(output + c, sum3); 81 | } 82 | } 83 | 84 | #endif 85 | -------------------------------------------------------------------------------- /src/AV/Output/OutputManager.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2017 Maarten Baert 3 | 4 | This file is part of SimpleScreenRecorder. 5 | 6 | SimpleScreenRecorder is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | SimpleScreenRecorder is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with SimpleScreenRecorder. If not, see . 18 | */ 19 | 20 | #pragma once 21 | #include "Global.h" 22 | 23 | #include "Muxer.h" 24 | #include "VideoEncoder.h" 25 | #include "AudioEncoder.h" 26 | #include "Synchronizer.h" 27 | #include "OutputSettings.h" 28 | 29 | class OutputManager { 30 | 31 | private: 32 | struct SharedData { 33 | 34 | // frame queue used while switching between fragments 35 | std::deque > m_video_frame_queue; 36 | std::deque > m_audio_frame_queue; 37 | unsigned int m_fragment_number; 38 | 39 | // muxer and encoders 40 | std::unique_ptr m_muxer; 41 | VideoEncoder *m_video_encoder; 42 | AudioEncoder *m_audio_encoder; 43 | 44 | }; 45 | typedef MutexDataPair::Lock SharedLock; 46 | 47 | private: 48 | static const size_t THROTTLE_THRESHOLD_FRAMES, THROTTLE_THRESHOLD_PACKETS; 49 | 50 | private: 51 | OutputSettings m_output_settings; 52 | OutputFormat m_output_format; 53 | 54 | bool m_fragmented; 55 | int64_t m_fragment_length; 56 | 57 | std::unique_ptr m_synchronizer; 58 | 59 | std::thread m_thread; 60 | MutexDataPair m_shared_data; 61 | std::atomic m_should_stop, m_should_finish, m_is_done, m_error_occurred; 62 | 63 | public: 64 | OutputManager(const OutputSettings& output_settings); 65 | ~OutputManager(); 66 | 67 | // Tells the encoders and muxer to finish. After calling this function, you should wait until 68 | // IsFinished returns true before deleting the output manager. 69 | void Finish(); 70 | 71 | // Returns whether the encoders and muxer have finished. 72 | bool IsFinished(); 73 | 74 | // Adds a video frame to the frame queue. Called by the synchronizer. 75 | // This function is thread-safe. 76 | void AddVideoFrame(std::unique_ptr frame); 77 | 78 | // Adds an audio frame to the frame queue. Called by the synchronizer. 79 | // This function is thread-safe. 80 | void AddAudioFrame(std::unique_ptr frame); 81 | 82 | // Returns an additional delay (in us) between frames, based on the queue size, to avoid memory problems. 83 | // As long as the queues are relatively small, this function will just return 0. 84 | // This function is thread-safe. 85 | int64_t GetVideoFrameDelay(); 86 | 87 | // Returns the total number of frames in the queue. 88 | // This function is thread-safe. 89 | unsigned int GetTotalQueuedFrameCount(); 90 | 91 | // Returns the frame rate of the output stream. 92 | // This function is thread-safe. 93 | double GetActualFrameRate(); 94 | 95 | // Returns the bit rate of the output stream. 96 | // This function is thread-safe. 97 | double GetActualBitRate(); 98 | 99 | // Returns the total number of bytes written to the output file. 100 | // This function is thread-safe. 101 | uint64_t GetTotalBytes(); 102 | 103 | private: 104 | void Init(); 105 | void Free(); 106 | 107 | void StartFragment(); 108 | void StopFragment(); 109 | 110 | void FragmentThread(); 111 | 112 | public: 113 | inline const OutputSettings* GetOutputSettings() { return &m_output_settings; } 114 | inline const OutputFormat* GetOutputFormat() { return &m_output_format; } 115 | inline Synchronizer* GetSynchronizer() { return m_synchronizer.get(); } 116 | 117 | }; 118 | -------------------------------------------------------------------------------- /src/common/LockFreeMessageQueue.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2017 Maarten Baert 3 | 4 | This file is part of SimpleScreenRecorder. 5 | 6 | SimpleScreenRecorder is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | SimpleScreenRecorder is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with SimpleScreenRecorder. If not, see . 18 | */ 19 | 20 | #pragma once 21 | #include "Global.h" 22 | 23 | inline bool IncreaseWritePos(unsigned int r, unsigned int& w, unsigned int inc, unsigned int buffer_size) { 24 | if(w + inc > buffer_size) { 25 | if(r > w || r <= inc) 26 | return false; 27 | w = inc; 28 | } else { 29 | if(r > w && r <= w + inc) 30 | return false; 31 | w += inc; 32 | } 33 | return true; 34 | } 35 | inline bool IncreaseReadPos(unsigned int& r, unsigned int w, unsigned int inc, unsigned int buffer_size) { 36 | if(r + inc > buffer_size) { 37 | if(w >= r || w < inc) 38 | return false; 39 | r = inc; 40 | } else { 41 | if(w >= r && w < r + inc) 42 | return false; 43 | r += inc; 44 | } 45 | return true; 46 | } 47 | 48 | class LockFreeMessageQueue { 49 | 50 | private: 51 | char *m_buffer; 52 | unsigned int m_buffer_size, m_read_pos, m_write_pos, m_read_pos_next, m_write_pos_next; 53 | 54 | public: 55 | inline LockFreeMessageQueue() { 56 | m_buffer = NULL; 57 | m_buffer_size = 0; 58 | m_read_pos = 0; 59 | m_write_pos = 0; 60 | } 61 | inline ~LockFreeMessageQueue() { 62 | free(m_buffer); 63 | } 64 | inline void Reset(unsigned int size) { 65 | free(m_buffer); 66 | m_buffer_size = 0; 67 | m_read_pos = 0; 68 | m_write_pos = 0; 69 | m_buffer = (char*) malloc(size); 70 | if(m_buffer == NULL) 71 | throw std::bad_alloc(); 72 | m_buffer_size = size; 73 | } 74 | 75 | inline char* PrepareWriteMessage(unsigned int size) { 76 | std::atomic_thread_fence(std::memory_order_acquire); 77 | unsigned int r = m_read_pos, w = m_write_pos; 78 | //fprintf(stderr, "PrepareWriteMessage (1) r=%10u w=%10u\n", r, w); 79 | if(!IncreaseWritePos(r, w, sizeof(unsigned int), m_buffer_size)) 80 | return NULL; 81 | //fprintf(stderr, "PrepareWriteMessage (2) r=%10u w=%10u\n", r, w); 82 | *((unsigned int*) (m_buffer + w - sizeof(unsigned int))) = size; 83 | if(!IncreaseWritePos(r, w, size, m_buffer_size)) 84 | return NULL; 85 | //fprintf(stderr, "PrepareWriteMessage (3) r=%10u w=%10u\n", r, w); 86 | m_write_pos_next = w; 87 | return m_buffer + w - size; 88 | } 89 | inline void WriteMessage() { 90 | std::atomic_thread_fence(std::memory_order_release); 91 | m_write_pos = m_write_pos_next; 92 | std::atomic_thread_fence(std::memory_order_release); 93 | } 94 | 95 | inline char* PrepareReadMessage(unsigned int* size) { 96 | std::atomic_thread_fence(std::memory_order_acquire); 97 | unsigned int r = m_read_pos, w = m_write_pos; 98 | //fprintf(stderr, "PrepareReadMessage (1) r=%10u w=%10u\n", r, w); 99 | if(!IncreaseReadPos(r, w, sizeof(unsigned int), m_buffer_size)) 100 | return NULL; 101 | //fprintf(stderr, "PrepareReadMessage (2) r=%10u w=%10u\n", r, w); 102 | std::atomic_thread_fence(std::memory_order_acquire); 103 | *size = *((unsigned int*) (m_buffer + r - sizeof(unsigned int))); 104 | if(!IncreaseReadPos(r, w, *size, m_buffer_size)) 105 | assert(false); 106 | //fprintf(stderr, "PrepareReadMessage (3) r=%10u w=%10u\n", r, w); 107 | m_read_pos_next = r; 108 | return m_buffer + r - *size; 109 | } 110 | inline void ReadMessage() { 111 | std::atomic_thread_fence(std::memory_order_acq_rel); 112 | m_read_pos = m_read_pos_next; 113 | std::atomic_thread_fence(std::memory_order_release); 114 | } 115 | 116 | }; 117 | -------------------------------------------------------------------------------- /src/AV/SourceSink.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2017 Maarten Baert 3 | 4 | This file is part of SimpleScreenRecorder. 5 | 6 | SimpleScreenRecorder is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | SimpleScreenRecorder is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with SimpleScreenRecorder. If not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #include "Global.h" 23 | 24 | #include "AVWrapper.h" 25 | #include "MutexDataPair.h" 26 | 27 | // The video source/sink system keeps track of connections between video inputs and outputs. 28 | // It decides where new frames should be sent. Using these connections is thread-safe, 29 | // however only ONE thread should ever create or destroy connections (this includes destroying sources or sinks). 30 | 31 | #define SINK_TIMESTAMP_NONE ((int64_t) 0x8000000000000000ull) // the sink doesn't want any new frames at the moment 32 | #define SINK_TIMESTAMP_ASAP ((int64_t) 0x8000000000000001ull) // the sink wants a new frame as soon as possible 33 | 34 | class BaseSource; 35 | class BaseSink; 36 | 37 | class BaseSource { 38 | public: 39 | struct SinkData { 40 | BaseSink *sink; 41 | int priority; 42 | inline SinkData() {} 43 | inline SinkData(BaseSink *sink, int priority) : sink(sink), priority(priority) {} 44 | inline bool operator<(const SinkData& other) const { 45 | return (priority > other.priority); // sort in reverse order (high priority first) 46 | } 47 | }; 48 | struct SharedData { 49 | std::vector m_sinks; 50 | }; 51 | typedef MutexDataPair::Lock SharedLock; 52 | public: 53 | MutexDataPair m_shared_data; 54 | public: 55 | BaseSource(); 56 | virtual ~BaseSource(); 57 | }; 58 | 59 | class BaseSink { 60 | public: 61 | // variables are not protected by a lock because they should only be read when connections change 62 | BaseSource *m_source; 63 | int m_priority; 64 | public: 65 | BaseSink(); 66 | virtual ~BaseSink(); 67 | void ConnectBaseSource(BaseSource* source, int priority); 68 | }; 69 | 70 | class VideoSource : private BaseSource { 71 | friend class VideoSink; 72 | protected: 73 | VideoSource() {} 74 | int64_t CalculateNextVideoTimestamp(); 75 | void PushVideoFrame(unsigned int width, unsigned int height, const uint8_t* data, int stride, AVPixelFormat format, int64_t timestamp); 76 | void PushVideoPing(int64_t timestamp); 77 | }; 78 | 79 | class VideoSink : private BaseSink { 80 | friend class VideoSource; 81 | protected: 82 | VideoSink() {} 83 | public: 84 | inline void ConnectVideoSource(VideoSource* source, int priority = 0) { ConnectBaseSource(source, priority); } 85 | public: 86 | virtual int64_t GetNextVideoTimestamp() { return SINK_TIMESTAMP_NONE; } 87 | virtual void ReadVideoFrame(unsigned int width, unsigned int height, const uint8_t* data, int stride, AVPixelFormat format, int64_t timestamp) = 0; 88 | virtual void ReadVideoPing(int64_t timestamp) {} 89 | }; 90 | 91 | class AudioSource : private BaseSource { 92 | friend class AudioSink; 93 | protected: 94 | AudioSource() {} 95 | void PushAudioSamples(unsigned int channels, unsigned int sample_rate, AVSampleFormat format, unsigned int sample_count, const uint8_t* data, int64_t timestamp); 96 | void PushAudioHole(); 97 | }; 98 | 99 | class AudioSink : private BaseSink { 100 | friend class AudioSource; 101 | protected: 102 | AudioSink() {} 103 | public: 104 | inline void ConnectAudioSource(AudioSource* source, int priority = 0) { ConnectBaseSource(source, priority); } 105 | public: 106 | virtual void ReadAudioSamples(unsigned int channels, unsigned int sample_rate, AVSampleFormat format, unsigned int sample_count, const uint8_t* data, int64_t timestamp) = 0; 107 | virtual void ReadAudioHole() {} 108 | }; 109 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.1) 2 | cmake_policy(VERSION 3.1) 3 | 4 | set(CMAKE_CXX_STANDARD 11) 5 | 6 | project(simplescreenrecorder VERSION 0.3.11) 7 | 8 | if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|amd64|i386|i686") 9 | set(PROCESSOR_IS_X86 TRUE) 10 | else() 11 | set(PROCESSOR_IS_X86 FALSE) 12 | endif() 13 | 14 | option(ENABLE_32BIT_GLINJECT "Build the 32-bit version of 'libssr-glinject' on 64-bit systems (in addition to the 64-bit version). Required for OpenGL recording of 32-bit applications on 64-bit systems." FALSE) 15 | option(ENABLE_X86_ASM "Allow x86/x64 assembly or intrinsics." ${PROCESSOR_IS_X86}) 16 | option(ENABLE_FFMPEG_VERSIONS "Use FFmpeg version numbers for feature support tests. Enable when using FFmpeg, disable when using Libav." TRUE) 17 | option(WITH_OPENGL_RECORDING "Build with OpenGL recording support." TRUE) 18 | option(WITH_ALSA "Build with ALSA support." TRUE) 19 | option(WITH_PULSEAUDIO "Build with PulseAudio support." TRUE) 20 | option(WITH_JACK "Build with JACK support." TRUE) 21 | option(WITH_QT5 "Build with Qt5 (instead of Qt4)." FALSE) 22 | option(WITH_SIMPLESCREENRECORDER "Build the 'simplescreenrecorder' executable." TRUE) 23 | option(WITH_GLINJECT "Build the 'libssr-glinject' library. Required for OpenGL recording." TRUE) 24 | option(WITH_WAYLAND "Build with Wayland (wlroots) support." TRUE) 25 | 26 | set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake) 27 | 28 | include(FeatureSummary) 29 | include(GNUInstallDirs) 30 | 31 | # try to guess the correct 32-bit library path on 64-bit systems 32 | if(ENABLE_32BIT_GLINJECT) 33 | 34 | if(NOT DEFINED CMAKE_INSTALL_LIB32DIR) 35 | set(_LIB32DIR_DEFAULT "lib32") 36 | if(EXISTS "/etc/debian_version") 37 | if(EXISTS "/usr/lib/i386-linux-gnu") 38 | set(_LIB32DIR_DEFAULT "lib/i386-linux-gnu") 39 | elseif(EXISTS "/usr/lib/i686-linux-gnu") 40 | set(_LIB32DIR_DEFAULT "lib/i686-linux-gnu") 41 | else() 42 | message(WARNING "Could not find correct multiarch 32-bit library path, falling back to 'lib32'.") 43 | endif() 44 | endif() 45 | set(CMAKE_INSTALL_LIB32DIR "${_LIB32DIR_DEFAULT}" CACHE PATH "object code libraries, 32-bit (${_LIB32DIR_DEFAULT})") 46 | endif() 47 | 48 | mark_as_advanced(CMAKE_INSTALL_LIB32DIR) 49 | 50 | if(NOT IS_ABSOLUTE ${CMAKE_INSTALL_LIB32DIR}) 51 | set(CMAKE_INSTALL_FULL_LIB32DIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIB32DIR}") 52 | else() 53 | set(CMAKE_INSTALL_FULL_LIB32DIR "${CMAKE_INSTALL_LIB32DIR}") 54 | endif() 55 | 56 | endif() 57 | 58 | if(WITH_GLINJECT) 59 | 60 | add_subdirectory(glinject) 61 | 62 | endif() 63 | 64 | if(WITH_WAYLAND) 65 | include(WaylandScanner) 66 | find_package(WaylandProtocols REQUIRED) 67 | wayland_generate_proto(${CMAKE_SOURCE_DIR}/proto/wlr-screencopy-unstable-v1.xml) 68 | wayland_generate_proto(${WaylandProtocols_PKGDATADIR}/unstable/xdg-output/xdg-output-unstable-v1.xml) 69 | wayland_proto_library(wayland-proto wlr-screencopy-unstable-v1 xdg-output-unstable-v1) 70 | endif() 71 | 72 | if(WITH_SIMPLESCREENRECORDER) 73 | 74 | add_subdirectory(src) 75 | add_subdirectory(src/translations) 76 | 77 | if(WITH_OPENGL_RECORDING) 78 | # the 'ssr-glinject' script is installed together with the main SSR executable to avoid problems with multiarch packages 79 | install( 80 | FILES scripts/ssr-glinject 81 | DESTINATION ${CMAKE_INSTALL_FULL_BINDIR} 82 | PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE 83 | ) 84 | endif() 85 | install( 86 | DIRECTORY data/output-profiles 87 | DESTINATION ${CMAKE_INSTALL_FULL_DATADIR}/simplescreenrecorder 88 | ) 89 | install( 90 | DIRECTORY data/man/ 91 | DESTINATION ${CMAKE_INSTALL_FULL_MANDIR}/man1 92 | ) 93 | install( 94 | FILES data/simplescreenrecorder.desktop 95 | DESTINATION ${CMAKE_INSTALL_FULL_DATADIR}/applications 96 | ) 97 | install( 98 | FILES data/simplescreenrecorder.appdata.xml 99 | DESTINATION ${CMAKE_INSTALL_FULL_DATADIR}/appdata 100 | ) 101 | 102 | # icons 103 | set(icons_res 16 22 24 32 48 64 96 128 192 256) 104 | 105 | foreach(res IN LISTS icons_res) 106 | install( 107 | DIRECTORY data/icons/${res}/ 108 | DESTINATION ${CMAKE_INSTALL_FULL_DATADIR}/icons/hicolor/${res}x${res}/apps 109 | ) 110 | endforeach() 111 | 112 | install( 113 | DIRECTORY data/icons/scalable/ 114 | DESTINATION ${CMAKE_INSTALL_FULL_DATADIR}/icons/hicolor/scalable/apps 115 | ) 116 | 117 | endif() 118 | 119 | feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES) 120 | -------------------------------------------------------------------------------- /src/AV/Output/Muxer.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2017 Maarten Baert 3 | 4 | This file is part of SimpleScreenRecorder. 5 | 6 | SimpleScreenRecorder is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | SimpleScreenRecorder is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with SimpleScreenRecorder. If not, see . 18 | */ 19 | 20 | #pragma once 21 | #include "Global.h" 22 | 23 | #include "MutexDataPair.h" 24 | 25 | #define MUXER_MAX_STREAMS 2 26 | 27 | class AVPacketWrapper; 28 | class BaseEncoder; 29 | class VideoEncoder; 30 | class AudioEncoder; 31 | 32 | class Muxer { 33 | 34 | private: 35 | struct StreamData { 36 | std::deque > m_packet_queue; 37 | bool m_is_done; 38 | }; 39 | typedef MutexDataPair::Lock StreamLock; 40 | struct SharedData { 41 | uint64_t m_total_bytes; 42 | double m_stats_actual_bit_rate; 43 | double m_stats_previous_time; 44 | uint64_t m_stats_previous_bytes; 45 | }; 46 | typedef MutexDataPair::Lock SharedLock; 47 | 48 | static constexpr unsigned int INVALID_STREAM = std::numeric_limits::max(); 49 | static constexpr double NOPTS_DOUBLE = -std::numeric_limits::max(); 50 | 51 | private: 52 | QString m_container_name, m_output_file; 53 | 54 | AVFormatContext *m_format_context; 55 | bool m_started; 56 | BaseEncoder *m_encoders[MUXER_MAX_STREAMS]; 57 | 58 | std::thread m_thread; 59 | MutexDataPair m_stream_data[MUXER_MAX_STREAMS]; 60 | MutexDataPair m_shared_data; 61 | std::atomic m_is_done, m_error_occurred; 62 | 63 | public: 64 | Muxer(const QString& container_name, const QString& output_file); 65 | ~Muxer(); 66 | 67 | // Adds a video or audio encoder. 68 | VideoEncoder* AddVideoEncoder(const QString& codec_name, const std::vector >& codec_options, unsigned int bit_rate, 69 | unsigned int width, unsigned int height, unsigned int frame_rate); 70 | AudioEncoder* AddAudioEncoder(const QString& codec_name, const std::vector >& codec_options, unsigned int bit_rate, 71 | unsigned int channels, unsigned int sample_rate); 72 | 73 | // Starts the muxer. You can't create new encoders after calling this function. 74 | void Start(); 75 | 76 | // Tells the muxer to stop. It can take some time before the muxer really stops. 77 | void Finish(); 78 | 79 | // Returns the bit rate of the output stream. 80 | // This function is thread-safe. 81 | double GetActualBitRate(); 82 | 83 | // Returns the total number of bytes written to the output file. 84 | // This function is thread-safe. 85 | uint64_t GetTotalBytes(); 86 | 87 | // Returns whether the muxing is done. If this returns true, the object can be deleted. 88 | // Note: If an error occurred in the mixing thread, this function will return false. 89 | // This function is thread-safe and lock-free. 90 | inline bool IsDone() { return m_is_done; } 91 | 92 | // Returns whether an error has occurred in the input thread. 93 | // This function is thread-safe and lock-free. 94 | inline bool HasErrorOccurred() { return m_error_occurred; } 95 | 96 | public: 97 | inline QString GetOutputFile() { return m_output_file; } 98 | 99 | public: // internal 100 | 101 | // Ends the stream (i.e. tells the muxer that it shouldn't wait for more packets). Called by the encoder. 102 | // This function is thread-safe. 103 | void EndStream(unsigned int stream_index); 104 | 105 | // Adds a packet to the packet queue of a stream. Called by the encoder. 106 | // This function is thread-safe. 107 | void AddPacket(unsigned int stream_index, std::unique_ptr packet); 108 | 109 | // Returns the total number of packets in the queue of a stream. Called by the encoder. 110 | // This function is thread-safe. 111 | unsigned int GetQueuedPacketCount(unsigned int stream_index); 112 | 113 | private: 114 | void Init(); 115 | void Free(); 116 | 117 | AVCodec* FindCodec(const QString& codec_name); 118 | AVStream* AddStream(AVCodec* codec, AVCodecContext** codec_context); 119 | 120 | void MuxerThread(); 121 | 122 | }; 123 | -------------------------------------------------------------------------------- /src/AV/Output/BaseEncoder.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2017 Maarten Baert 3 | 4 | This file is part of SimpleScreenRecorder. 5 | 6 | SimpleScreenRecorder is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | SimpleScreenRecorder is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with SimpleScreenRecorder. If not, see . 18 | */ 19 | 20 | #pragma once 21 | #include "Global.h" 22 | 23 | #include "AVWrapper.h" 24 | #include "MutexDataPair.h" 25 | 26 | int ParseCodecOptionInt(const QString& key, const QString& value, int min, int max, int multiply = 1); 27 | double ParseCodecOptionDouble(const QString& key, const QString& value, double min, double max, double multiply = 1.0); 28 | 29 | class Muxer; 30 | 31 | class BaseEncoder { 32 | 33 | private: 34 | struct SharedData { 35 | std::deque > m_frame_queue; 36 | uint64_t m_total_frames, m_total_packets; 37 | double m_stats_actual_frame_rate; 38 | int64_t m_stats_previous_pts; 39 | uint64_t m_stats_previous_frames; 40 | }; 41 | typedef MutexDataPair::Lock SharedLock; 42 | 43 | private: 44 | Muxer *m_muxer; 45 | AVStream *m_stream; 46 | AVCodecContext *m_codec_context; 47 | bool m_codec_opened; 48 | 49 | std::thread m_thread; 50 | MutexDataPair m_shared_data; 51 | std::atomic m_should_stop, m_should_finish, m_is_done, m_error_occurred; 52 | 53 | protected: 54 | BaseEncoder(Muxer* muxer, AVStream* stream, AVCodecContext* codec_context, AVCodec* codec, AVDictionary** options); 55 | 56 | public: 57 | virtual ~BaseEncoder(); // encoders will be deleted by Muxer, don't delete them yourself! 58 | 59 | protected: 60 | void StartThread(); 61 | void StopThread(); // important: call this in the destructor of the derived class 62 | 63 | public: 64 | // Returns the frame rate of the output stream. 65 | // This function is thread-safe. 66 | double GetActualFrameRate(); 67 | 68 | // Returns the total number of added frames. 69 | // This function is thread-safe. 70 | uint64_t GetTotalFrames(); 71 | 72 | // Returns the current input-to-output latency of the encoder (in frames). 73 | // This function is thread-safe. 74 | unsigned int GetFrameLatency(); 75 | 76 | // Returns the total number of frames in the queue. 77 | // This function is thread-safe. 78 | unsigned int GetQueuedFrameCount(); 79 | 80 | unsigned int GetQueuedPacketCount(); 81 | 82 | public: // internal 83 | 84 | // Adds a frame to the frame queue. Called by the synchronizer. 85 | // This function is thread-safe. 86 | void AddFrame(std::unique_ptr frame); 87 | 88 | // Tells the encoder to stop. It can still take some time before the encoder is actually done. Called by the muxer. 89 | // After calling this function, the muxer will wait until either IsDone or HasErrorOccurred returns true. 90 | // This function is thread-safe. 91 | void Finish(); 92 | 93 | // Same as finish, except that queued frames will be dropped and the encoder won't be flushed. Called by the muxer. 94 | // This function is thread-safe. 95 | void Stop(); 96 | 97 | // Returns whether the encoding is done. If this returns true, the object can be deleted. Called by the muxer. 98 | // Note: If an error occurred during encoding, this function will return false. 99 | // This function is thread-safe and lock-free. 100 | inline bool IsDone() { return m_is_done; } 101 | 102 | // Returns whether an error has occurred in the input thread. Called by the muxer. 103 | // This function is thread-safe and lock-free. 104 | inline bool HasErrorOccurred() { return m_error_occurred; } 105 | 106 | inline Muxer* GetMuxer() { return m_muxer; } 107 | inline AVStream* GetStream() { return m_stream; } 108 | inline AVCodecContext* GetCodecContext() { return m_codec_context; } 109 | 110 | protected: 111 | 112 | // Called by the encoder thread to encode a single frame. Frame can be NULL if the encoder uses delayed packets. 113 | // Returns whether a packet was created. 114 | virtual bool EncodeFrame(AVFrameWrapper* frame) = 0; 115 | 116 | // Called to increment the packet counter. 117 | void IncrementPacketCounter(); 118 | 119 | private: 120 | void Init(AVCodec* codec, AVDictionary** options); 121 | void Free(); 122 | 123 | void EncoderThread(); 124 | 125 | }; 126 | -------------------------------------------------------------------------------- /simple-build-and-install: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Run this if you just want to build and install the program and you don't care about all the details. 3 | # Any additional arguments will be passed on to 'cmake'. 4 | # The following environment variables can be set to TRUE or FALSE to override the auto-detected values: 5 | # - ENABLE_32BIT_GLINJECT 6 | # - ENABLE_X86_ASM 7 | # - ENABLE_FFMPEG_VERSIONS 8 | # - WITH_QT5 9 | # - WITH_GLINJECT 10 | # - WITH_WAYLAND 11 | 12 | set -e 13 | cd "$( dirname "${BASH_SOURCE[0]}" )" 14 | 15 | if [ x"$( whoami )" = x"root" ]; then 16 | echo "Error: don't run this script as root, this will mess up file permissions" 17 | exit 1 18 | fi 19 | 20 | export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/usr/local/lib64/pkgconfig:/usr/local/lib/pkgconfig" 21 | 22 | if [ -z "$ENABLE_32BIT_GLINJECT" ] || [ -z "$ENABLE_X86_ASM" ] || [ -z "$WITH_GLINJECT" ]; then 23 | echo "Detecting architecture ..." 24 | case "$( uname -m )" in 25 | "i386"|"i486"|"i586"|"i686") 26 | : ${ENABLE_32BIT_GLINJECT:="FALSE"} 27 | : ${ENABLE_X86_ASM:="TRUE"} 28 | : ${WITH_GLINJECT:="TRUE"} 29 | ;; 30 | "x86_64") 31 | : ${ENABLE_32BIT_GLINJECT:="TRUE"} 32 | : ${ENABLE_X86_ASM:="TRUE"} 33 | : ${WITH_GLINJECT:="TRUE"} 34 | ;; 35 | *) 36 | : ${ENABLE_32BIT_GLINJECT:="FALSE"} 37 | : ${ENABLE_X86_ASM:="FALSE"} 38 | : ${WITH_GLINJECT:="FALSE"} 39 | ;; 40 | esac 41 | fi 42 | 43 | if [ -z "$ENABLE_FFMPEG_VERSIONS" ]; then 44 | echo "Detecting ffmpeg/libav ..." 45 | if ! pkg-config --exists libavcodec; then 46 | echo " Error: libavcodec development package not found, make sure ffmpeg or libav development packages are installed." 47 | exit 1 48 | fi 49 | LIBAVCODEC_INCLUDE_DIR="$( pkg-config --variable=includedir libavcodec )" 50 | HAS_FFMPEG=$( grep -c "This file is part of FFmpeg." $LIBAVCODEC_INCLUDE_DIR/libavcodec/avcodec.h || true ) 51 | HAS_LIBAV=$( grep -c "This file is part of Libav." $LIBAVCODEC_INCLUDE_DIR/libavcodec/avcodec.h || true ) 52 | if [ $HAS_FFMPEG -gt 0 ]; then 53 | if [ $HAS_LIBAV -gt 0 ]; then 54 | echo " Error: Detected ffmpeg AND libav, this should not happen!" 55 | exit 1 56 | else 57 | echo " Detected ffmpeg." 58 | ENABLE_FFMPEG_VERSIONS="TRUE" 59 | fi 60 | else 61 | if [ $HAS_LIBAV -gt 0 ]; then 62 | echo " Detected libav." 63 | ENABLE_FFMPEG_VERSIONS="FALSE" 64 | else 65 | echo " Error: Detection failed." 66 | exit 1 67 | fi 68 | fi 69 | fi 70 | 71 | if [ -z "$WITH_QT5" ]; then 72 | echo "Detecting Qt version ..." 73 | if pkg-config --exists "Qt5Gui >= 5.7"; then 74 | echo " Detected Qt5 (version $( pkg-config --modversion Qt5Gui ))." 75 | WITH_QT5="TRUE" 76 | elif pkg-config --exists "QtGui >= 4.8"; then 77 | echo " Detected Qt4 (version $( pkg-config --modversion QtGui ))." 78 | WITH_QT5="FALSE" 79 | else 80 | echo " Error: Qt development package not found, make sure that either Qt4 (4.8 or newer) or Qt5 (5.7 or newer) is installed." 81 | exit 1 82 | fi 83 | fi 84 | 85 | if [ -z "$WITH_WAYLAND" ]; then 86 | WITH_WAYLAND=TRUE 87 | fi 88 | 89 | echo "Auto-detected options:" 90 | echo " ENABLE_32BIT_GLINJECT = $ENABLE_32BIT_GLINJECT" 91 | echo " ENABLE_X86_ASM = $ENABLE_X86_ASM" 92 | echo " ENABLE_FFMPEG_VERSIONS = $ENABLE_FFMPEG_VERSIONS" 93 | echo " WITH_QT5 = $WITH_QT5" 94 | echo " WITH_GLINJECT = $WITH_GLINJECT" 95 | echo " WITH_WAYLAND = $WITH_WAYLAND" 96 | 97 | PREFIX="/usr" 98 | 99 | OPTIONS=() 100 | OPTIONS+=("-DENABLE_32BIT_GLINJECT=$ENABLE_32BIT_GLINJECT") 101 | OPTIONS+=("-DENABLE_X86_ASM=$ENABLE_X86_ASM") 102 | OPTIONS+=("-DENABLE_FFMPEG_VERSIONS=$ENABLE_FFMPEG_VERSIONS") 103 | OPTIONS+=("-DWITH_QT5=$WITH_QT5") 104 | OPTIONS+=("-DWITH_GLINJECT=$WITH_GLINJECT") 105 | OPTIONS+=("-DWITH_WAYLAND=$WITH_WAYLAND") 106 | 107 | if [ x"$WITH_QT5" == x"TRUE" ]; then 108 | export QT_SELECT="qt5" 109 | else 110 | export QT_SELECT="qt4" 111 | OPTIONS+=("-DCMAKE_AUTOMOC_MOC_OPTIONS=-D_SYS_SYSMACROS_H_OUTER") 112 | fi 113 | 114 | echo "Entering build-release directory ..." 115 | rm -rf build-release 116 | mkdir build-release 117 | cd build-release 118 | 119 | echo "Running cmake ..." 120 | cmake -DCMAKE_INSTALL_PREFIX="$PREFIX" -DCMAKE_BUILD_TYPE=Release "${OPTIONS[@]}" "$@" .. 121 | 122 | echo "Compiling ..." 123 | make -j "$( nproc )" 124 | 125 | if [ x"$WITH_GLINJECT" == x"TRUE" ]; then 126 | echo "Removing old GLInject libraries ..." 127 | sudo rm -f "/usr/lib/libssr-glinject."* 128 | sudo rm -f "/usr/lib64/libssr-glinject."* 129 | sudo rm -f "/usr/lib/x86_64-linux-gnu/libssr-glinject."* 130 | if [ x"$ENABLE_32BIT_GLINJECT" == x"TRUE" ]; then 131 | sudo rm -f "/usr/lib32/libssr-glinject."* 132 | sudo rm -f "/usr/lib/i386-linux-gnu/libssr-glinject."* 133 | sudo rm -f "/usr/lib/i686-linux-gnu/libssr-glinject."* 134 | fi 135 | fi 136 | 137 | echo "Installing ..." 138 | sudo make install 139 | 140 | echo "Leaving build-release directory ..." 141 | cd .. 142 | 143 | echo "Running post-install script ..." 144 | sudo ./postinstall 145 | 146 | echo "Done." 147 | -------------------------------------------------------------------------------- /src/AV/AVWrapper.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2017 Maarten Baert 3 | 4 | This file is part of SimpleScreenRecorder. 5 | 6 | SimpleScreenRecorder is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | SimpleScreenRecorder is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with SimpleScreenRecorder. If not, see . 18 | */ 19 | 20 | #pragma once 21 | #include "Global.h" 22 | 23 | #if !SSR_USE_AV_CODEC_ID 24 | #define AV_CODEC_ID_NONE CODEC_ID_NONE 25 | #endif 26 | 27 | #if !SSR_USE_AV_PIX_FMT 28 | #define AVPixelFormat PixelFormat 29 | #define AV_PIX_FMT_NONE PIX_FMT_NONE 30 | #define AV_PIX_FMT_PAL8 PIX_FMT_PAL8 31 | #define AV_PIX_FMT_RGB565 PIX_FMT_RGB565 32 | #define AV_PIX_FMT_RGB555 PIX_FMT_RGB555 33 | #define AV_PIX_FMT_BGR24 PIX_FMT_BGR24 34 | #define AV_PIX_FMT_RGB24 PIX_FMT_RGB24 35 | #define AV_PIX_FMT_BGRA PIX_FMT_BGRA 36 | #define AV_PIX_FMT_RGBA PIX_FMT_RGBA 37 | #define AV_PIX_FMT_ABGR PIX_FMT_ABGR 38 | #define AV_PIX_FMT_ARGB PIX_FMT_ARGB 39 | #define AV_PIX_FMT_YUV420P PIX_FMT_YUV420P 40 | #define AV_PIX_FMT_YUV422P PIX_FMT_YUV422P 41 | #define AV_PIX_FMT_YUV444P PIX_FMT_YUV444P 42 | #define AV_PIX_FMT_NV12 PIX_FMT_NV12 43 | #endif 44 | 45 | #if !SSR_USE_AV_CODEC_CAP 46 | #define AV_CODEC_CAP_DELAY CODEC_CAP_DELAY 47 | #define AV_CODEC_CAP_EXPERIMENTAL CODEC_CAP_EXPERIMENTAL 48 | #define AV_CODEC_CAP_VARIABLE_FRAME_SIZE CODEC_CAP_VARIABLE_FRAME_SIZE 49 | #endif 50 | 51 | #if !SSR_USE_AV_CODEC_FLAG 52 | #define AV_CODEC_FLAG_GLOBAL_HEADER CODEC_FLAG_GLOBAL_HEADER 53 | #define AV_CODEC_FLAG_QSCALE CODEC_FLAG_QSCALE 54 | #endif 55 | 56 | // A trivial class that holds (aligned) frame data. This makes it easy to implement reference counting through std::shared_ptr. 57 | class AVFrameData { 58 | private: 59 | uint8_t *m_data; 60 | size_t m_size; 61 | public: 62 | inline AVFrameData(size_t size) { 63 | m_data = (uint8_t*) av_malloc(size); 64 | if(m_data == NULL) 65 | throw std::bad_alloc(); 66 | m_size = size; 67 | } 68 | inline ~AVFrameData() { 69 | av_free(m_data); 70 | } 71 | inline uint8_t* GetData() { 72 | return m_data; 73 | } 74 | inline size_t GetSize() { 75 | return m_size; 76 | } 77 | }; 78 | 79 | // A wrapper around AVFrame to manage memory allocation and reference counting. 80 | // Note: This reference counting mechanism is unrelated to the mechanism added in later versions of ffmpeg/libav. 81 | class AVFrameWrapper { 82 | 83 | private: 84 | AVFrame *m_frame; 85 | std::shared_ptr m_refcounted_data; 86 | 87 | public: 88 | AVFrameWrapper(const std::shared_ptr& refcounted_data); 89 | ~AVFrameWrapper(); 90 | 91 | AVFrameWrapper(const AVFrameWrapper&) = delete; 92 | AVFrameWrapper& operator=(const AVFrameWrapper&) = delete; 93 | 94 | #if SSR_USE_AVCODEC_SEND_RECEIVE 95 | // This function transfers ownership of the data to the AVFrame, and then releases ownership of the AVFrame itself. 96 | // This turns the AVFrame into a stand-alone object which relies on the ffmpeg/libav reference counting mechanism to free the data. 97 | // The returned frame should be freed with av_frame_free. 98 | AVFrame* Release(); 99 | #endif 100 | 101 | public: 102 | inline AVFrame* GetFrame() { return m_frame; } 103 | inline uint8_t* GetRawData() { return m_refcounted_data->GetData(); } 104 | inline std::shared_ptr GetFrameData() { return m_refcounted_data; } 105 | 106 | }; 107 | 108 | // A wrapper around AVPacket to manage memory allocation. There is no copying or reference counting in this case. 109 | class AVPacketWrapper { 110 | 111 | private: 112 | AVPacket *m_packet; 113 | #if !SSR_USE_AV_PACKET_ALLOC 114 | bool m_free_on_destruct; 115 | #endif 116 | 117 | public: 118 | AVPacketWrapper(); 119 | AVPacketWrapper(size_t size); 120 | ~AVPacketWrapper(); 121 | 122 | AVPacketWrapper(const AVPacketWrapper&) = delete; 123 | AVPacketWrapper& operator=(const AVPacketWrapper&) = delete; 124 | 125 | public: 126 | inline AVPacket* GetPacket() { return m_packet; } 127 | inline void SetFreeOnDestruct(bool free_on_destruct) { 128 | #if !SSR_USE_AV_PACKET_ALLOC 129 | m_free_on_destruct = free_on_destruct; 130 | #endif 131 | } 132 | 133 | }; 134 | 135 | bool AVFormatIsInstalled(const QString& format_name); 136 | bool AVCodecIsInstalled(const QString& codec_name); 137 | bool AVCodecSupportsPixelFormat(const AVCodec* codec, AVPixelFormat pixel_fmt); 138 | bool AVCodecSupportsSampleFormat(const AVCodec* codec, AVSampleFormat sample_fmt); 139 | 140 | #if !SSR_USE_AV_CODEC_IS_ENCODER 141 | inline int av_codec_is_encoder(const AVCodec* codec) { 142 | return (codec != NULL && (codec->encode != NULL || codec->encode2 != NULL)); 143 | } 144 | #endif 145 | -------------------------------------------------------------------------------- /src/AV/Input/WlrInput.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2017 Maarten Baert 3 | 4 | This file is part of SimpleScreenRecorder. 5 | 6 | SimpleScreenRecorder is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | SimpleScreenRecorder is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with SimpleScreenRecorder. If not, see . 18 | */ 19 | 20 | #pragma once 21 | #include "Global.h" 22 | 23 | #include "SourceSink.h" 24 | #include "MutexDataPair.h" 25 | 26 | #include 27 | #include "wlr-screencopy-unstable-v1-client-protocol.h" 28 | #include "xdg-output-unstable-v1-client-protocol.h" 29 | 30 | class WlrInput : public VideoSource { 31 | 32 | private: 33 | struct Rect { 34 | unsigned int m_x1, m_y1, m_x2, m_y2; 35 | inline Rect() {} 36 | inline Rect(unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2) : m_x1(x1), m_y1(y1), m_x2(x2), m_y2(y2) {} 37 | }; 38 | struct SharedData { 39 | unsigned int m_current_width, m_current_height; 40 | }; 41 | typedef MutexDataPair::Lock SharedLock; 42 | 43 | struct WlOutput { 44 | wl_output* output; 45 | zxdg_output_v1* zxdg_output; 46 | std::string name, description; 47 | int32_t x, y, width, height; 48 | }; 49 | 50 | struct WlBuffer { 51 | struct wl_buffer *wl_buffer; 52 | void *data; 53 | enum wl_shm_format format; 54 | int width, height, stride; 55 | bool y_invert; 56 | 57 | timespec presented; 58 | uint32_t base_msec; 59 | }; 60 | private: 61 | unsigned int m_x, m_y, m_width, m_height; 62 | bool m_record_cursor, m_follow_cursor, m_follow_fullscreen; 63 | 64 | std::atomic m_frame_counter; 65 | int64_t m_fps_last_timestamp; 66 | uint32_t m_fps_last_counter; 67 | double m_fps_current; 68 | 69 | wl_shm* m_shm; 70 | wl_registry* m_registry; 71 | wl_display* m_display; 72 | zxdg_output_manager_v1* m_xdg_output_manager; 73 | zwlr_screencopy_manager_v1* m_screencopy_manager; 74 | std::vector m_outputs; 75 | WlOutput* m_current_output; 76 | 77 | WlBuffer m_buffer; 78 | bool m_buffer_copy_done; 79 | 80 | Rect m_screen_bbox; 81 | std::vector m_screen_rects; 82 | std::vector m_screen_dead_space; 83 | 84 | std::thread m_thread; 85 | MutexDataPair m_shared_data; 86 | std::atomic m_should_stop, m_error_occurred; 87 | 88 | public: 89 | WlrInput(unsigned int x, unsigned int y, unsigned int width, unsigned int height, bool record_cursor, bool follow_cursor, bool follow_fullscreen); 90 | ~WlrInput(); 91 | 92 | // Reads the current size of the stream. 93 | // This function is thread-safe. 94 | void GetCurrentSize(unsigned int* width, unsigned int* height); 95 | 96 | // Returns the total number of captured frames. 97 | // This function is thread-safe. 98 | double GetFPS(); 99 | 100 | // Returns whether an error has occurred in the input thread. 101 | // This function is thread-safe. 102 | inline bool HasErrorOccurred() { return m_error_occurred; } 103 | 104 | private: 105 | void Init(); 106 | void Free(); 107 | 108 | private: 109 | void InputThread(); 110 | 111 | void CheckProtos(); 112 | void SyncWayland(); 113 | void LoadOutputInfo(); 114 | 115 | AVPixelFormat GetInputFormat(WlBuffer& buf); 116 | static const zxdg_output_v1_listener XdgOutputImpl; 117 | static void HandleXdgOutputLogicalPosition(void* data, zxdg_output_v1* zxdg_output, int32_t x, int32_t y); 118 | static void HandleXdgOutputLogicalSize(void* data, zxdg_output_v1* zxdg_output, int32_t w, int32_t h); 119 | static void HandleXdgOutputDescription(void* data, zxdg_output_v1* zxdg_output_v1, const char* description); 120 | static void HandleXdgOutputName(void* data, zxdg_output_v1* zxdg_output_v1, const char* name); 121 | static void HandleXdgOutputDone(void* data, zxdg_output_v1* zxdg_output_v1); 122 | 123 | static const struct zwlr_screencopy_frame_v1_listener FrameListener; 124 | static void FrameHandleBuffer(void* data, struct zwlr_screencopy_frame_v1 *frame, uint32_t format, uint32_t width, uint32_t height, uint32_t stride); 125 | static void FrameHandleFlags(void* data, struct zwlr_screencopy_frame_v1 *, uint32_t flags); 126 | static void FrameHandleReady(void* data, struct zwlr_screencopy_frame_v1 *, uint32_t tv_sec_hi, uint32_t tv_sec_low, uint32_t tv_nsec); 127 | static void FrameHandleFailed(void* data, struct zwlr_screencopy_frame_v1 *); 128 | 129 | static const struct wl_registry_listener RegistryListener; 130 | static void HandleGlobal(void* data, struct wl_registry *registry, uint32_t name, const char *interface, uint32_t); 131 | static void HandleGlobalRemove(void*, struct wl_registry *, uint32_t); 132 | }; 133 | --------------------------------------------------------------------------------