mirror of
https://github.com/motioneye-project/motioneyeos.git
synced 2025-07-29 06:06:32 +00:00
Merge pull request #998 from jasaw/enable-rpi-hw-accel
Enable hwaccel h264 encoding on raspberry pi
This commit is contained in:
commit
03edcf3ba7
1
board/raspberrypi/overlay/opt/vc/lib
Symbolic link
1
board/raspberrypi/overlay/opt/vc/lib
Symbolic link
@ -0,0 +1 @@
|
||||
../../usr/lib
|
1
board/raspberrypi2/overlay/opt/vc/lib
Symbolic link
1
board/raspberrypi2/overlay/opt/vc/lib
Symbolic link
@ -0,0 +1 @@
|
||||
../../usr/lib
|
1
board/raspberrypi3/overlay/opt/vc/lib
Symbolic link
1
board/raspberrypi3/overlay/opt/vc/lib
Symbolic link
@ -0,0 +1 @@
|
||||
../../usr/lib
|
@ -27,6 +27,7 @@ BR2_PACKAGE_FFMPEG=y
|
||||
BR2_PACKAGE_FFMPEG_GPL=y
|
||||
BR2_PACKAGE_FFMPEG_NONFREE=y
|
||||
BR2_PACKAGE_FFMPEG_SWSCALE=y
|
||||
BR2_PACKAGE_FFMPEG_RPI_HW_CODECS=y
|
||||
BR2_PACKAGE_LIBWEBCAM=y
|
||||
BR2_PACKAGE_MOTION=y
|
||||
BR2_PACKAGE_STREAMEYE=y
|
||||
|
@ -27,6 +27,7 @@ BR2_PACKAGE_FFMPEG=y
|
||||
BR2_PACKAGE_FFMPEG_GPL=y
|
||||
BR2_PACKAGE_FFMPEG_NONFREE=y
|
||||
BR2_PACKAGE_FFMPEG_SWSCALE=y
|
||||
BR2_PACKAGE_FFMPEG_RPI_HW_CODECS=y
|
||||
BR2_PACKAGE_LIBWEBCAM=y
|
||||
BR2_PACKAGE_MOTION=y
|
||||
BR2_PACKAGE_STREAMEYE=y
|
||||
|
@ -28,6 +28,7 @@ BR2_PACKAGE_FFMPEG=y
|
||||
BR2_PACKAGE_FFMPEG_GPL=y
|
||||
BR2_PACKAGE_FFMPEG_NONFREE=y
|
||||
BR2_PACKAGE_FFMPEG_SWSCALE=y
|
||||
BR2_PACKAGE_FFMPEG_RPI_HW_CODECS=y
|
||||
BR2_PACKAGE_LIBWEBCAM=y
|
||||
BR2_PACKAGE_MOTION=y
|
||||
BR2_PACKAGE_STREAMEYE=y
|
||||
|
@ -167,6 +167,12 @@ config BR2_PACKAGE_FFMPEG_OUTDEVS
|
||||
bool "Enable output devices"
|
||||
default y
|
||||
|
||||
config BR2_PACKAGE_FFMPEG_RPI_HW_CODECS
|
||||
bool "Enable rpi hardware accelerated codecs"
|
||||
depends on BR2_PACKAGE_RPI_USERLAND
|
||||
help
|
||||
Enable HW accelerated codecs on Raspberry pi.
|
||||
|
||||
config BR2_PACKAGE_FFMPEG_EXTRACONF
|
||||
string "Additional parameters for ./configure"
|
||||
default ""
|
||||
|
15
package/ffmpeg/disable-rpi-omx-input-zerocopy.patch
Normal file
15
package/ffmpeg/disable-rpi-omx-input-zerocopy.patch
Normal file
@ -0,0 +1,15 @@
|
||||
diff --git a/libavcodec/omx.c b/libavcodec/omx.c
|
||||
index 19b4f33836..4641dc79e2 100644
|
||||
--- a/libavcodec/omx.c
|
||||
+++ b/libavcodec/omx.c
|
||||
@@ -644,10 +644,6 @@ static av_cold int omx_encode_init(AVCodecContext *avctx)
|
||||
OMX_BUFFERHEADERTYPE *buffer;
|
||||
OMX_ERRORTYPE err;
|
||||
|
||||
-#if CONFIG_OMX_RPI
|
||||
- s->input_zerocopy = 1;
|
||||
-#endif
|
||||
-
|
||||
s->omx_context = omx_init(avctx, s->libname, s->libprefix);
|
||||
if (!s->omx_context)
|
||||
return AVERROR_ENCODER_NOT_FOUND;
|
@ -1,2 +1,3 @@
|
||||
# Locally calculated
|
||||
sha256 54ce502aca10b7e6059f19220ea2f68fa0c9c4c4d255ae13e615f08f0c94dcc5 ffmpeg-3.2.3.tar.xz
|
||||
sha256 1998de1ab32616cbf2ff86efc3f1f26e76805ec5dc51e24c041c79edd8262785 ffmpeg-3.3.2.tar.xz
|
||||
|
@ -4,7 +4,7 @@
|
||||
#
|
||||
################################################################################
|
||||
|
||||
FFMPEG_VERSION = 3.2.3
|
||||
FFMPEG_VERSION = 3.3.2
|
||||
FFMPEG_SOURCE = ffmpeg-$(FFMPEG_VERSION).tar.xz
|
||||
FFMPEG_SITE = http://ffmpeg.org/releases
|
||||
FFMPEG_INSTALL_STAGING = YES
|
||||
@ -26,7 +26,6 @@ FFMPEG_CONF_OPTS = \
|
||||
--enable-avdevice \
|
||||
--enable-avcodec \
|
||||
--enable-avformat \
|
||||
--disable-x11grab \
|
||||
--enable-network \
|
||||
--disable-gray \
|
||||
--enable-swscale-alpha \
|
||||
@ -39,7 +38,6 @@ FFMPEG_CONF_OPTS = \
|
||||
--disable-dxva2 \
|
||||
--enable-runtime-cpudetect \
|
||||
--disable-hardcoded-tables \
|
||||
--disable-memalign-hack \
|
||||
--disable-mipsdsp \
|
||||
--disable-mipsdspr2 \
|
||||
--disable-msa \
|
||||
@ -473,6 +471,11 @@ else ifneq ($(call qstrip,$(BR2_GCC_TARGET_ARCH)),)
|
||||
FFMPEG_CONF_OPTS += --cpu=$(BR2_GCC_TARGET_ARCH)
|
||||
endif
|
||||
|
||||
ifeq ($(BR2_PACKAGE_FFMPEG_RPI_HW_CODECS),y)
|
||||
FFMPEG_DEPENDENCIES += rpi-userland
|
||||
FFMPEG_CONF_OPTS += --enable-omx --enable-omx-rpi --enable-mmal --extra-cflags=-I../../staging/usr/include/IL/
|
||||
endif
|
||||
|
||||
|
||||
FFMPEG_CONF_OPTS += $(call qstrip,$(BR2_PACKAGE_FFMPEG_EXTRACONF))
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
#
|
||||
################################################################################
|
||||
|
||||
MOTION_VERSION = 37b3595
|
||||
MOTION_VERSION = ab9e800d5984f2907f00bebabc794d1dba9682ad
|
||||
MOTION_SITE = $(call github,motion-project,motion,$(MOTION_VERSION))
|
||||
MOTION_AUTORECONF = YES
|
||||
MOTION_CONF_OPTS = --without-pgsql --without-sdl --without-sqlite3 --without-mysql --with-ffmpeg=$(STAGING_DIR)/usr/lib \
|
||||
|
145
package/motion/preferred-encoder.patch
Normal file
145
package/motion/preferred-encoder.patch
Normal file
@ -0,0 +1,145 @@
|
||||
diff --git a/ffmpeg.c b/ffmpeg.c
|
||||
index 87b4f75..3e7787c 100644
|
||||
--- a/ffmpeg.c
|
||||
+++ b/ffmpeg.c
|
||||
@@ -236,10 +236,21 @@ static void ffmpeg_free_context(struct ffmpeg *ffmpeg){
|
||||
|
||||
static int ffmpeg_get_oformat(struct ffmpeg *ffmpeg){
|
||||
|
||||
+ size_t codec_name_len = strcspn(ffmpeg->codec_name, ":");
|
||||
+ char *codec_name = alloca(codec_name_len + 1);
|
||||
+
|
||||
+ if (codec_name == NULL) {
|
||||
+ MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, "Failed to allocate memory for codec name");
|
||||
+ ffmpeg_free_context(ffmpeg);
|
||||
+ return -1;
|
||||
+ }
|
||||
+ memcpy(codec_name, ffmpeg->codec_name, codec_name_len);
|
||||
+ codec_name[codec_name_len] = 0;
|
||||
+
|
||||
/* Only the newer codec and containers can handle the really fast FPS */
|
||||
- if (((strcmp(ffmpeg->codec_name, "msmpeg4") == 0) ||
|
||||
- (strcmp(ffmpeg->codec_name, "mpeg4") == 0) ||
|
||||
- (strcmp(ffmpeg->codec_name, "swf") == 0) ) && (ffmpeg->fps >50)){
|
||||
+ if (((strcmp(codec_name, "msmpeg4") == 0) ||
|
||||
+ (strcmp(codec_name, "mpeg4") == 0) ||
|
||||
+ (strcmp(codec_name, "swf") == 0) ) && (ffmpeg->fps >50)){
|
||||
MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, "The frame rate specified is too high for the ffmpeg movie type specified. Choose a different ffmpeg container or lower framerate.");
|
||||
ffmpeg_free_context(ffmpeg);
|
||||
return -1;
|
||||
@@ -250,59 +261,59 @@ static int ffmpeg_get_oformat(struct ffmpeg *ffmpeg){
|
||||
if (ffmpeg->oc->oformat) ffmpeg->oc->oformat->video_codec = MY_CODEC_ID_MPEG2VIDEO;
|
||||
strncat(ffmpeg->filename, ".mpg", 4);
|
||||
if (!ffmpeg->oc->oformat) {
|
||||
- MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, "ffmpeg_video_codec option value %s is not supported", ffmpeg->codec_name);
|
||||
+ MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, "ffmpeg_video_codec option value %s is not supported", codec_name);
|
||||
ffmpeg_free_context(ffmpeg);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
- if (strcmp(ffmpeg->codec_name, "mpeg4") == 0) {
|
||||
+ if (strcmp(codec_name, "mpeg4") == 0) {
|
||||
ffmpeg->oc->oformat = av_guess_format("avi", NULL, NULL);
|
||||
strncat(ffmpeg->filename, ".avi", 4);
|
||||
}
|
||||
|
||||
- if (strcmp(ffmpeg->codec_name, "msmpeg4") == 0) {
|
||||
+ if (strcmp(codec_name, "msmpeg4") == 0) {
|
||||
ffmpeg->oc->oformat = av_guess_format("avi", NULL, NULL);
|
||||
strncat(ffmpeg->filename, ".avi", 4);
|
||||
if (ffmpeg->oc->oformat) ffmpeg->oc->oformat->video_codec = MY_CODEC_ID_MSMPEG4V2;
|
||||
}
|
||||
|
||||
- if (strcmp(ffmpeg->codec_name, "swf") == 0) {
|
||||
+ if (strcmp(codec_name, "swf") == 0) {
|
||||
ffmpeg->oc->oformat = av_guess_format("swf", NULL, NULL);
|
||||
strncat(ffmpeg->filename, ".swf", 4);
|
||||
}
|
||||
|
||||
- if (strcmp(ffmpeg->codec_name, "flv") == 0) {
|
||||
+ if (strcmp(codec_name, "flv") == 0) {
|
||||
ffmpeg->oc->oformat = av_guess_format("flv", NULL, NULL);
|
||||
strncat(ffmpeg->filename, ".flv", 4);
|
||||
if (ffmpeg->oc->oformat) ffmpeg->oc->oformat->video_codec = MY_CODEC_ID_FLV1;
|
||||
}
|
||||
|
||||
- if (strcmp(ffmpeg->codec_name, "ffv1") == 0) {
|
||||
+ if (strcmp(codec_name, "ffv1") == 0) {
|
||||
ffmpeg->oc->oformat = av_guess_format("avi", NULL, NULL);
|
||||
strncat(ffmpeg->filename, ".avi", 4);
|
||||
if (ffmpeg->oc->oformat) ffmpeg->oc->oformat->video_codec = MY_CODEC_ID_FFV1;
|
||||
}
|
||||
|
||||
- if (strcmp(ffmpeg->codec_name, "mov") == 0) {
|
||||
+ if (strcmp(codec_name, "mov") == 0) {
|
||||
ffmpeg->oc->oformat = av_guess_format("mov", NULL, NULL);
|
||||
strncat(ffmpeg->filename, ".mov", 4);
|
||||
}
|
||||
|
||||
- if (strcmp(ffmpeg->codec_name, "mp4") == 0) {
|
||||
+ if (strcmp(codec_name, "mp4") == 0) {
|
||||
ffmpeg->oc->oformat = av_guess_format("mp4", NULL, NULL);
|
||||
strncat(ffmpeg->filename, ".mp4", 4);
|
||||
if (ffmpeg->oc->oformat) ffmpeg->oc->oformat->video_codec = MY_CODEC_ID_H264;
|
||||
}
|
||||
|
||||
- if (strcmp(ffmpeg->codec_name, "mkv") == 0) {
|
||||
+ if (strcmp(codec_name, "mkv") == 0) {
|
||||
ffmpeg->oc->oformat = av_guess_format("matroska", NULL, NULL);
|
||||
strncat(ffmpeg->filename, ".mkv", 4);
|
||||
if (ffmpeg->oc->oformat) ffmpeg->oc->oformat->video_codec = MY_CODEC_ID_H264;
|
||||
}
|
||||
|
||||
- if (strcmp(ffmpeg->codec_name, "hevc") == 0) {
|
||||
+ if (strcmp(codec_name, "hevc") == 0) {
|
||||
ffmpeg->oc->oformat = av_guess_format("mp4", NULL, NULL);
|
||||
strncat(ffmpeg->filename, ".mp4", 4);
|
||||
if (ffmpeg->oc->oformat) ffmpeg->oc->oformat->video_codec = MY_CODEC_ID_HEVC;
|
||||
@@ -310,7 +321,7 @@ static int ffmpeg_get_oformat(struct ffmpeg *ffmpeg){
|
||||
|
||||
//Check for valid results
|
||||
if (!ffmpeg->oc->oformat) {
|
||||
- MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, "codec option value %s is not supported", ffmpeg->codec_name);
|
||||
+ MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, "codec option value %s is not supported", codec_name);
|
||||
ffmpeg_free_context(ffmpeg);
|
||||
return -1;
|
||||
}
|
||||
@@ -484,13 +495,23 @@ static int ffmpeg_set_codec(struct ffmpeg *ffmpeg){
|
||||
int retcd;
|
||||
char errstr[128];
|
||||
int chkrate;
|
||||
+ size_t codec_name_len = strcspn(ffmpeg->codec_name, ":");
|
||||
|
||||
- ffmpeg->codec = avcodec_find_encoder(ffmpeg->oc->oformat->video_codec);
|
||||
+ ffmpeg->codec = NULL;
|
||||
+ if (ffmpeg->codec_name[codec_name_len]) {
|
||||
+ ffmpeg->codec = avcodec_find_encoder_by_name(&ffmpeg->codec_name[codec_name_len+1]);
|
||||
+ if (!ffmpeg->codec)
|
||||
+ MOTION_LOG(WRN, TYPE_ENCODER, NO_ERRNO, "Preferred codec %s not found", &ffmpeg->codec_name[codec_name_len+1]);
|
||||
+ }
|
||||
+ if (!ffmpeg->codec)
|
||||
+ ffmpeg->codec = avcodec_find_encoder(ffmpeg->oc->oformat->video_codec);
|
||||
if (!ffmpeg->codec) {
|
||||
MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, "Codec %s not found", ffmpeg->codec_name);
|
||||
ffmpeg_free_context(ffmpeg);
|
||||
return -1;
|
||||
}
|
||||
+ if (ffmpeg->codec_name[codec_name_len])
|
||||
+ MOTION_LOG(NTC, TYPE_ENCODER, NO_ERRNO, "Using codec %s", ffmpeg->codec->name);
|
||||
|
||||
#if (LIBAVFORMAT_VERSION_MAJOR >= 58) || ((LIBAVFORMAT_VERSION_MAJOR == 57) && (LIBAVFORMAT_VERSION_MINOR >= 41))
|
||||
//If we provide the codec to this, it results in a memory leak. ffmpeg ticket: 5714
|
||||
diff --git a/ffmpeg.h b/ffmpeg.h
|
||||
index 78a2785..95383a7 100644
|
||||
--- a/ffmpeg.h
|
||||
+++ b/ffmpeg.h
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <stdarg.h>
|
||||
#include <sys/time.h>
|
||||
#include <stdint.h>
|
||||
+#include <alloca.h>
|
||||
#include "config.h"
|
||||
|
||||
enum TIMELAPSE_TYPE {
|
17
package/motion/temp-fix-for-extpipe-subdir-creation.patch
Normal file
17
package/motion/temp-fix-for-extpipe-subdir-creation.patch
Normal file
@ -0,0 +1,17 @@
|
||||
diff --git a/event.c b/event.c
|
||||
index f67214e..44d8096 100644
|
||||
--- a/event.c
|
||||
+++ b/event.c
|
||||
@@ -572,6 +572,12 @@ static void event_create_extpipe(struct context *cnt,
|
||||
}
|
||||
}
|
||||
|
||||
+ /* Temporary solution for https://github.com/Motion-Project/motion/issues/360#issuecomment-320849158
|
||||
+ Always create any path specified as file name */
|
||||
+ if (create_path(cnt->extpipefilename) == -1)
|
||||
+ return ;
|
||||
+ /* end of fix */
|
||||
+
|
||||
mystrftime(cnt, stamp, sizeof(stamp), cnt->conf.extpipe, currenttime_tv, cnt->extpipefilename, 0);
|
||||
|
||||
MOTION_LOG(NTC, TYPE_EVENTS, NO_ERRNO, "pipe: %s", stamp);
|
42
package/motion/tune-h264-encode-quality.patch
Normal file
42
package/motion/tune-h264-encode-quality.patch
Normal file
@ -0,0 +1,42 @@
|
||||
diff --git a/ffmpeg.c b/ffmpeg.c
|
||||
index a4d3757..368c855 100644
|
||||
--- a/ffmpeg.c
|
||||
+++ b/ffmpeg.c
|
||||
@@ -451,7 +451,7 @@ static int ffmpeg_set_pts(struct ffmpeg *ffmpeg, const struct timeval *tv1){
|
||||
|
||||
static int ffmpeg_set_quality(struct ffmpeg *ffmpeg){
|
||||
|
||||
- char crf[4];
|
||||
+ int bit_rate;
|
||||
|
||||
ffmpeg->opts = 0;
|
||||
if (ffmpeg->vbr > 100) ffmpeg->vbr = 100;
|
||||
@@ -459,13 +459,24 @@ static int ffmpeg_set_quality(struct ffmpeg *ffmpeg){
|
||||
ffmpeg->ctx_codec->codec_id == MY_CODEC_ID_HEVC){
|
||||
if (ffmpeg->vbr > 0) {
|
||||
ffmpeg->vbr = (int)(( (100-ffmpeg->vbr) * 51)/100);
|
||||
+ //bit_rate = ffmpeg->width * ffmpeg->height * ffmpeg->fps * quality_factor
|
||||
+ bit_rate = (ffmpeg->width * ffmpeg->height * ffmpeg->fps * ffmpeg->vbr) >> 8;
|
||||
} else {
|
||||
+ bit_rate = ffmpeg->bps;
|
||||
ffmpeg->vbr = 28;
|
||||
}
|
||||
- snprintf(crf, 4, "%d",ffmpeg->vbr);
|
||||
- av_dict_set(&ffmpeg->opts, "preset", "ultrafast", 0);
|
||||
- av_dict_set(&ffmpeg->opts, "tune", "zerolatency", 0);
|
||||
- av_dict_set(&ffmpeg->opts, "crf", crf, 0);
|
||||
+ av_dict_set(&ffmpeg->opts, "preset", "ultrafast", 0);
|
||||
+ av_dict_set(&ffmpeg->opts, "tune", "zerolatency", 0);
|
||||
+ av_dict_set_int(&ffmpeg->opts, "crf", ffmpeg->vbr, 0);
|
||||
+ if ((strcmp(ffmpeg->codec->name, "h264_omx") == 0) || (strcmp(ffmpeg->codec->name, "mpeg4_omx") == 0)) {
|
||||
+ // Clip bit rate to min and max
|
||||
+ if (bit_rate < 40000)
|
||||
+ bit_rate = 40000;
|
||||
+ else if (bit_rate > 3000000)
|
||||
+ bit_rate = 3000000;
|
||||
+ ffmpeg->ctx_codec->profile = FF_PROFILE_H264_HIGH;
|
||||
+ ffmpeg->ctx_codec->bit_rate = bit_rate;
|
||||
+ }
|
||||
} else {
|
||||
/* The selection of 8000 in the else is a subjective number based upon viewing output files */
|
||||
if (ffmpeg->vbr > 0){
|
183
package/motioneye/add-hwaccel-video-encoding-option.patch
Normal file
183
package/motioneye/add-hwaccel-video-encoding-option.patch
Normal file
@ -0,0 +1,183 @@
|
||||
commit 508d177f9f62a33f1062443243d8c1b9c6172edf
|
||||
Author: Joo Aun Saw <jasaw@dius.com.au>
|
||||
Date: Wed Aug 23 16:12:47 2017 +1000
|
||||
|
||||
Add option to enable hardware accelerated video encoding
|
||||
|
||||
diff --git a/motioneye/config.py b/motioneye/config.py
|
||||
index 48e8cf5..b810588 100644
|
||||
--- a/motioneye/config.py
|
||||
+++ b/motioneye/config.py
|
||||
@@ -57,6 +57,7 @@ _EXPONENTIAL_QUALITY_CODECS = ['mpeg4', 'msmpeg4', 'swf', 'flv', 'mov', 'mkv']
|
||||
_EXPONENTIAL_QUALITY_FACTOR = 100000 # voodoo
|
||||
_EXPONENTIAL_DEF_QUALITY = 511 # about 75%
|
||||
_MAX_FFMPEG_VARIABLE_BITRATE = 32767
|
||||
+_HW_ACCEL_CODECS = ['mp4', 'mkv']
|
||||
|
||||
_KNOWN_MOTION_OPTIONS = set([
|
||||
'auto_brightness',
|
||||
@@ -737,6 +738,7 @@ def motion_camera_ui_to_dict(ui, old_config=None):
|
||||
'movie_filename': ui['movie_file_name'],
|
||||
'max_movie_time': ui['max_movie_length'],
|
||||
'@preserve_movies': int(ui['preserve_movies']),
|
||||
+ '@movie_hwaccel': ui['movie_hwaccel'],
|
||||
|
||||
# motion detection
|
||||
'@motion_detection': ui['motion_detection'],
|
||||
@@ -930,6 +932,9 @@ def motion_camera_ui_to_dict(ui, old_config=None):
|
||||
|
||||
else:
|
||||
vbr = max(1, q)
|
||||
+ if motionctl.has_hwaccel_movie_encoding_support() and ui['movie_hwaccel']:
|
||||
+ if data['ffmpeg_video_codec'] in _HW_ACCEL_CODECS:
|
||||
+ data['ffmpeg_video_codec'] = data['ffmpeg_video_codec']+':h264_omx'
|
||||
|
||||
data['ffmpeg_variable_bitrate'] = int(vbr)
|
||||
|
||||
@@ -1120,6 +1125,7 @@ def motion_camera_dict_to_ui(data):
|
||||
'movie_file_name': data['movie_filename'],
|
||||
'max_movie_length': data['max_movie_time'],
|
||||
'preserve_movies': data['@preserve_movies'],
|
||||
+ 'movie_hwaccel': data['@movie_hwaccel'],
|
||||
|
||||
# motion detection
|
||||
'motion_detection': data['@motion_detection'],
|
||||
@@ -1313,6 +1319,7 @@ def motion_camera_dict_to_ui(data):
|
||||
ui['recording_mode'] = 'motion-triggered'
|
||||
|
||||
ui['movie_format'] = data['ffmpeg_video_codec']
|
||||
+ ui['movie_format'] = [x.strip() for x in ui['movie_format'].split(':')][0]
|
||||
|
||||
bitrate = data['ffmpeg_variable_bitrate']
|
||||
if motionctl.needs_ffvb_quirks():
|
||||
@@ -1897,6 +1904,7 @@ def _set_default_motion_camera(camera_id, data):
|
||||
data.setdefault('ffmpeg_variable_bitrate', _EXPONENTIAL_DEF_QUALITY)
|
||||
|
||||
data.setdefault('@preserve_movies', 0)
|
||||
+ data.setdefault('@movie_hwaccel', 0)
|
||||
|
||||
data.setdefault('@working_schedule', '')
|
||||
data.setdefault('@working_schedule_type', 'outside')
|
||||
diff --git a/motioneye/handlers.py b/motioneye/handlers.py
|
||||
index 051621c..4044d73 100644
|
||||
--- a/motioneye/handlers.py
|
||||
+++ b/motioneye/handlers.py
|
||||
@@ -221,6 +221,7 @@ class MainHandler(BaseHandler):
|
||||
admin_username=config.get_main().get('@admin_username'),
|
||||
has_streaming_auth=motionctl.has_streaming_auth(),
|
||||
has_new_movie_format_support=motionctl.has_new_movie_format_support(),
|
||||
+ has_hwaccel_movie_encoding_support=motionctl.has_hwaccel_movie_encoding_support(),
|
||||
has_motion=bool(motionctl.find_motion()[0]),
|
||||
mask_width=utils.MASK_WIDTH)
|
||||
|
||||
diff --git a/motioneye/motionctl.py b/motioneye/motionctl.py
|
||||
index 832ed38..da61c23 100644
|
||||
--- a/motioneye/motionctl.py
|
||||
+++ b/motioneye/motionctl.py
|
||||
@@ -38,6 +38,7 @@ _LAST_OLD_CONFIG_VERSIONS = (490, '3.2.12')
|
||||
_started = False
|
||||
_motion_binary_cache = None
|
||||
_motion_detected = {}
|
||||
+_hwaccel_codec_cache = None
|
||||
|
||||
|
||||
def find_motion():
|
||||
@@ -75,6 +76,38 @@ def find_motion():
|
||||
return _motion_binary_cache
|
||||
|
||||
|
||||
+def hwaccel_codec_supported():
|
||||
+ global _hwaccel_codec_cache
|
||||
+ if _hwaccel_codec_cache:
|
||||
+ return _hwaccel_codec_cache
|
||||
+
|
||||
+ if settings.FFMPEG_BINARY:
|
||||
+ if os.path.exists(settings.FFMPEG_BINARY):
|
||||
+ binary = settings.FFMPEG_BINARY
|
||||
+ else:
|
||||
+ return False
|
||||
+
|
||||
+ else: # autodetect ffmpeg binary path
|
||||
+ try:
|
||||
+ binary = subprocess.check_output(['which', 'ffmpeg'], stderr=utils.DEV_NULL).strip()
|
||||
+ except subprocess.CalledProcessError: # not found
|
||||
+ return False
|
||||
+
|
||||
+ try:
|
||||
+ help = subprocess.check_output(binary + ' -codecs -hide_banner', shell=True)
|
||||
+
|
||||
+ except subprocess.CalledProcessError: # not found
|
||||
+ return False
|
||||
+
|
||||
+ result = re.findall('h264_omx', help, re.IGNORECASE)
|
||||
+ if result:
|
||||
+ logging.debug('Hardware accelerated codec found: %s' % result)
|
||||
+ _hwaccel_codec_cache = True
|
||||
+ else:
|
||||
+ _hwaccel_codec_cache = False
|
||||
+ return _hwaccel_codec_cache
|
||||
+
|
||||
+
|
||||
def start(deferred=False):
|
||||
import config
|
||||
import mjpgclient
|
||||
@@ -354,6 +387,10 @@ def has_new_movie_format_support():
|
||||
return version.lower().count('git') or update.compare_versions(version, '3.4') >= 0
|
||||
|
||||
|
||||
+def has_hwaccel_movie_encoding_support():
|
||||
+ return hwaccel_codec_supported()
|
||||
+
|
||||
+
|
||||
def get_rtsp_support():
|
||||
binary, version = find_motion()
|
||||
if not binary:
|
||||
diff --git a/motioneye/settings.py b/motioneye/settings.py
|
||||
index cfd8488..8ba1363 100644
|
||||
--- a/motioneye/settings.py
|
||||
+++ b/motioneye/settings.py
|
||||
@@ -124,3 +124,6 @@ ADD_REMOVE_CAMERAS = True
|
||||
|
||||
# enable HTTPS certificate validation
|
||||
VALIDATE_CERTS = True
|
||||
+
|
||||
+# path to the ffmpeg binary (automatically detected by default)
|
||||
+FFMPEG_BINARY = None
|
||||
diff --git a/motioneye/static/js/main.js b/motioneye/static/js/main.js
|
||||
index ac43386..1a25d76 100644
|
||||
--- a/motioneye/static/js/main.js
|
||||
+++ b/motioneye/static/js/main.js
|
||||
@@ -1869,6 +1869,7 @@ function cameraUi2Dict() {
|
||||
'movie_file_name': $('#movieFileNameEntry').val(),
|
||||
'movie_quality': $('#movieQualitySlider').val(),
|
||||
'movie_format': $('#movieFormatSelect').val(),
|
||||
+ 'movie_hwaccel': $('#hwaccelEncoding')[0].checked,
|
||||
'recording_mode': $('#recordingModeSelect').val(),
|
||||
'max_movie_length': $('#maxMovieLengthEntry').val(),
|
||||
'preserve_movies': $('#preserveMoviesSelect').val() >= 0 ? $('#preserveMoviesSelect').val() : $('#moviesLifetimeEntry').val(),
|
||||
@@ -2219,6 +2220,7 @@ function dict2CameraUi(dict) {
|
||||
$('#movieFileNameEntry').val(dict['movie_file_name']); markHideIfNull('movie_file_name', 'movieFileNameEntry');
|
||||
$('#movieQualitySlider').val(dict['movie_quality']); markHideIfNull('movie_quality', 'movieQualitySlider');
|
||||
$('#movieFormatSelect').val(dict['movie_format']); markHideIfNull('movie_format', 'movieFormatSelect');
|
||||
+ $('#hwaccelEncoding')[0].checked = dict['movie_hwaccel']; markHideIfNull('movie_hwaccel', 'hwaccelEncoding');
|
||||
$('#recordingModeSelect').val(dict['recording_mode']); markHideIfNull('recording_mode', 'recordingModeSelect');
|
||||
$('#maxMovieLengthEntry').val(dict['max_movie_length']); markHideIfNull('max_movie_length', 'maxMovieLengthEntry');
|
||||
$('#preserveMoviesSelect').val(dict['preserve_movies']);
|
||||
diff --git a/motioneye/templates/main.html b/motioneye/templates/main.html
|
||||
index e2b38d8..3fc6183 100644
|
||||
--- a/motioneye/templates/main.html
|
||||
+++ b/motioneye/templates/main.html
|
||||
@@ -762,6 +762,13 @@
|
||||
<td class="settings-item-value"><input type="text" class="range styled movies camera-config" id="movieQualitySlider"></td>
|
||||
<td><span class="help-mark" title="sets the MPEG video quality (higher values produce a better video quality but require more storage space)">?</span></td>
|
||||
</tr>
|
||||
+ {% if has_hwaccel_movie_encoding_support %}
|
||||
+ <tr class="settings-item advanced-setting">
|
||||
+ <td class="settings-item-label"><span class="settings-item-label">Hardware Acceleration</span></td>
|
||||
+ <td class="settings-item-value"><input type="checkbox" class="styled movies camera-config" id="hwaccelEncoding"></td>
|
||||
+ <td><span class="help-mark" title="uses hardware acceleration when encoding movie">?</span></td>
|
||||
+ </tr>
|
||||
+ {% endif %}
|
||||
<tr class="settings-item advanced-setting">
|
||||
<td class="settings-item-label"><span class="settings-item-label">Recording Mode</span></td>
|
||||
<td class="settings-item-value">
|
Loading…
x
Reference in New Issue
Block a user