From 686e386f4112d00dbd118f0983b53390cdd94cdd Mon Sep 17 00:00:00 2001 From: Jan Stabenow Date: Mon, 21 Nov 2022 10:52:04 +0100 Subject: [PATCH] Add Bob Weaver Deinterlacing Filter (datarhei/restreamer#465) --- CHANGELOG.md | 6 +- src/misc/filters/index.js | 2 + src/misc/filters/video/Bwdif.js | 172 ++++++++++++++++++++++++++++++++ 3 files changed, 179 insertions(+), 1 deletion(-) create mode 100644 src/misc/filters/video/Bwdif.js diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f27d90..38163be 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,12 @@ # Restreamer-UI +## v1.5.1 > v1.6.0 + +- Add Bob Weaver Deinterlacing Filter ([#465](https://github.com/datarhei/restreamer/issues/465)) + ## v1.5.0 > v1.5.1 -- Fix FFmpeg version check for RTSP sources (datarhei/restreamer#455) +- Fix FFmpeg version check for RTSP sources ([#455](https://github.com/datarhei/restreamer/issues/455)) - Fix requires Core >= v16.11.0 and FFmpeg >= 5.1.0 ## v1.4.0 > v1.5.0 diff --git a/src/misc/filters/index.js b/src/misc/filters/index.js index 382f0d0..f223d11 100644 --- a/src/misc/filters/index.js +++ b/src/misc/filters/index.js @@ -9,6 +9,7 @@ import * as Scale from './video/Scale'; import * as Transpose from './video/Transpose'; import * as HFlip from './video/HFlip'; import * as VFlip from './video/VFlip'; +import * as Bwdif from './video/Bwdif'; // Register filters type: audio/video class Registry { @@ -56,6 +57,7 @@ videoRegistry.Register(Scale); videoRegistry.Register(Transpose); videoRegistry.Register(HFlip); videoRegistry.Register(VFlip); +videoRegistry.Register(Bwdif); // Export registrys for ../SelectFilters.js export { audioRegistry as Audio, videoRegistry as Video }; diff --git a/src/misc/filters/video/Bwdif.js b/src/misc/filters/video/Bwdif.js new file mode 100644 index 0000000..26ec93e --- /dev/null +++ b/src/misc/filters/video/Bwdif.js @@ -0,0 +1,172 @@ +import React from 'react'; + +import { Trans } from '@lingui/macro'; +import Grid from '@mui/material/Grid'; +import MenuItem from '@mui/material/MenuItem'; + +import Checkbox from '../../Checkbox'; +import Select from '../../Select'; + +// Deinterlace the input video ("bwdif" stands for "Bob Weaver Deinterlacing Filter"). +// http://ffmpeg.org/ffmpeg-all.html#bwdif + +function init(initialState) { + const state = { + enabled: false, + mode: '1', + parity: '-1', + deint: '0', + ...initialState, + }; + + return state; +} + +function createGraph(settings) { + settings = init(settings); + + const mapping = []; + + if (settings.enabled) { + mapping.push(`bwdif=mode=${settings.mode}:parity=${settings.parity}:deint=${settings.deint}`); + } + + return mapping.join(','); +} + +function Mode(props) { + return ( + + ); +} + +Mode.defaultProps = { + value: '', + onChange: function (event) {}, +}; + +function Parity(props) { + return ( + + ); +} + +Parity.defaultProps = { + value: '', + onChange: function (event) {}, +}; + +function Deint(props) { + return ( + + ); +} + +Deint.defaultProps = { + value: '', + onChange: function (event) {}, +}; + +function Filter(props) { + const settings = init(props.settings); + + const handleChange = (newSettings) => { + let automatic = false; + if (!newSettings) { + newSettings = settings; + automatic = true; + } + + props.onChange(newSettings, createGraph(newSettings), automatic); + }; + + const update = (what) => (event) => { + const newSettings = { + ...settings, + }; + if (['enabled'].includes(what)) { + newSettings[what] = !settings.enabled; + } else { + newSettings[what] = event.target.value; + } + + handleChange(newSettings); + }; + + React.useEffect(() => { + handleChange(null); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + return ( + + + Deinterlace (bwdif)} checked={settings.enabled} onChange={update('enabled')} /> + + {settings.enabled && ( + + + Deinterlace mode} value={settings.mode} onChange={update('mode')}> + + + Deinterlace parity} value={settings.parity} onChange={update('parity')}> + + + Deinterlace deint} value={settings.deint} onChange={update('deint')}> + + + )} + + ); +} + +Filter.defaultProps = { + settings: {}, + onChange: function (settings, mapping) {}, +}; + +const filter = 'bwdif'; +const name = 'Deinterlacing Filter'; +const type = 'video'; +const hwaccel = false; + +function summarize(settings) { + if (settings.mode !== 'none') { + return `${name}`; + } +} + +function defaults() { + const settings = init({}); + + return { + settings: settings, + graph: createGraph(settings), + }; +} + +export { name, filter, type, hwaccel, summarize, defaults, createGraph, Filter as component };