Adds setting quality accoeding to pattern default

dev
Javanaut 1 month ago
parent c354ba09ba
commit 15bfbdbe88

4
.gitignore vendored

@ -8,5 +8,7 @@ tools/ansible/inventory/cappuccino.yml
tools/ansible/inventory/group_vars/all.yml
ffx_test_report.log
bin/conversiontest.py
*.egg-info/
build/
dist/
*.egg-info/

@ -30,6 +30,15 @@ class AudioLayout(Enum):
except:
return AudioLayout.LAYOUT_UNDEFINED
# @staticmethod
# def fromIndex(index : int):
# try:
# target_index = int(index)
# except (TypeError, ValueError):
# return AudioLayout.LAYOUT_UNDEFINED
# return next((a for a in AudioLayout if a.value['index'] == target_index),
# AudioLayout.LAYOUT_UNDEFINED)
@staticmethod
def fromIndex(index : int):
try:

@ -32,6 +32,7 @@ from ffx.filter.preset_filter import PresetFilter
from ffx.filter.crop_filter import CropFilter
from ffx.filter.nlmeans_filter import NlmeansFilter
from ffx.filter.deinterlace_filter import DeinterlaceFilter
from ffx.constants import VERSION
@ -335,6 +336,8 @@ def checkUniqueDispositions(context, mediaDescriptor: MediaDescriptor):
@click.option("--output-directory", type=str, default='')
@click.option("--deinterlace", is_flag=False, flag_value="default", default="none")
@click.option("--denoise", is_flag=False, flag_value="default", default="none")
@click.option("--denoise-use-hw", is_flag=True, default=False)
@click.option('--denoise-strength', type=str, default='', help='Denoising strength, more blurring vs more details.')
@ -391,6 +394,8 @@ def convert(ctx,
output_directory,
deinterlace,
denoise,
denoise_use_hw,
denoise_strength,
@ -517,14 +522,6 @@ def convert(ctx,
ctx.obj['logger'].debug(f"\nVideo encoder: {video_encoder}")
qualityTokens = quality.split(',')
q_list = [q for q in qualityTokens if q.isnumeric()]
ctx.obj['logger'].debug(f"Qualities: {q_list}")
presetTokens = preset.split(',')
p_list = [p for p in presetTokens if p.isnumeric()]
ctx.obj['logger'].debug(f"Presets: {p_list}")
context['bitrates'] = {}
context['bitrates']['stereo'] = str(stereo_bitrate) if str(stereo_bitrate).endswith('k') else f"{stereo_bitrate}k"
@ -548,9 +545,12 @@ def convert(ctx,
tc = TmdbController() if context['use_tmdb'] else None
qualityKwargs = {QualityFilter.QUALITY_KEY: str(QualityFilter.DEFAULT_H264_QUALITY if (context['video_encoder'] == VideoEncoder.H264 and not quality) else quality)}
qualityKwargs = {QualityFilter.QUALITY_KEY: str(quality)}
qf = QualityFilter(**qualityKwargs)
if context['video_encoder'] == VideoEncoder.AV1 and preset:
presetKwargs = {PresetFilter.PRESET_KEY: preset}
PresetFilter(**presetKwargs)
@ -575,6 +575,9 @@ def convert(ctx,
if denoise != 'none' or denoiseKwargs:
NlmeansFilter(**denoiseKwargs)
if deinterlace != 'none':
DeinterlaceFilter()
chainYield = list(qf.getChainYield())
ctx.obj['logger'].info(f"\nRunning {len(existingSourcePaths) * len(chainYield)} jobs")
@ -791,15 +794,18 @@ def convert(ctx,
ctx.obj['logger'].info(f"Creating file {targetFilename}")
if rename_only:
shutil.copyfile(sourcePath, targetPath)
else:
fc.runJob(sourcePath,
targetPath,
targetFormat,
context['video_encoder'],
chainIteration,
cropArguments)
cropArguments,
currentPattern)
endTime = time.perf_counter()
ctx.obj['logger'].info(f"\nDONE\nTime elapsed {endTime - startTime}")

@ -15,6 +15,8 @@ from ffx.filter.quality_filter import QualityFilter
from ffx.filter.preset_filter import PresetFilter
from ffx.filter.crop_filter import CropFilter
from ffx.model.pattern import Pattern
class FfxController():
@ -179,19 +181,35 @@ class FfxController():
sourcePath,
targetPath,
targetFormat: str = '',
videoEncoder: VideoEncoder = VideoEncoder.VP9,
chainIteration: list = [],
cropArguments: dict = {}):
cropArguments: dict = {},
currentPattern: Pattern = None):
# quality: int = DEFAULT_QUALITY,
# preset: int = DEFAULT_AV1_PRESET):
videoEncoder: VideoEncoder = self.__context.get('video_encoder', VideoEncoder.VP9)
qualityFilters = [fy for fy in chainIteration if fy['identifier'] == 'quality']
presetFilters = [fy for fy in chainIteration if fy['identifier'] == 'preset']
cropFilters = [fy for fy in chainIteration if fy['identifier'] == 'crop']
denoiseFilters = [fy for fy in chainIteration if fy['identifier'] == 'nlmeans']
deinterlaceFilters = [fy for fy in chainIteration if fy['identifier'] == 'bwdif']
if qualityFilters and (quality := qualityFilters[0]['parameters']['quality']):
self.__logger.info(f"Setting quality {quality} from filter")
elif (quality := currentPattern.quality):
self.__logger.info(f"Setting quality {quality} from pattern default")
else:
quality = (QualityFilter.DEFAULT_H264_QUALITY
if (videoEncoder == VideoEncoder.H264)
else QualityFilter.DEFAULT_VP9_QUALITY)
self.__logger.info(f"Setting quality {quality} from default")
quality = (qualityFilters[0]['parameters']['quality'] if qualityFilters else QualityFilter.DEFAULT_VP9_QUALITY)
preset = presetFilters[0]['parameters']['preset'] if presetFilters else PresetFilter.DEFAULT_PRESET
@ -208,6 +226,9 @@ class FfxController():
filterParamTokens.append(cropParams)
filterParamTokens.extend(denoiseFilters[0]['tokens'] if denoiseFilters else [])
filterParamTokens.extend(deinterlaceFilters[0]['tokens'] if deinterlaceFilters else [])
deinterlaceFilters
filterTokens = ['-vf', ', '.join(filterParamTokens)] if filterParamTokens else []

@ -1,7 +1,9 @@
import itertools
import click
from .filter import Filter
from ffx.video_encoder import VideoEncoder
class QualityFilter(Filter):
@ -14,6 +16,9 @@ class QualityFilter(Filter):
def __init__(self, **kwargs):
context = click.get_current_context().obj
self.__qualitiesList = []
qualities = kwargs.get(QualityFilter.QUALITY_KEY, '')
if qualities:
@ -27,7 +32,9 @@ class QualityFilter(Filter):
raise ValueError('QualityFilter: Quality value has to be between 0 and 63')
self.__qualitiesList.append(qualityValue)
else:
self.__qualitiesList = [QualityFilter.DEFAULT_VP9_QUALITY]
self.__qualitiesList = [None]
super().__init__(self)
@ -52,4 +59,4 @@ class QualityFilter(Filter):
def getYield(self):
for q in self.__qualitiesList:
yield self.getPayload(q)
yield self.getPayload(q)

@ -31,9 +31,11 @@ class Pattern(Base):
tracks = relationship('Track', back_populates='pattern', cascade="all, delete", lazy='joined')
media_tags = relationship('MediaTag', back_populates='pattern', cascade="all, delete", lazy='joined')
quality = Column(Integer, default=0)
def getId(self):
return int(self.id)

@ -49,6 +49,7 @@ class PatternController():
pattern.show_id = int(patternObj['show_id'])
pattern.pattern = str(patternObj['pattern'])
pattern.quality = str(patternObj['quality'])
s.commit()
return True

@ -40,7 +40,7 @@ class PatternDetailsScreen(Screen):
Grid {
grid-size: 7 13;
grid-rows: 2 2 2 2 2 8 2 2 8 2 2 2 2;
grid-rows: 2 2 2 2 2 2 8 2 2 8 2 2 2 2;
grid-columns: 25 25 25 25 25 25 25;
height: 100%;
width: 100%;
@ -255,6 +255,9 @@ class PatternDetailsScreen(Screen):
self.query_one("#pattern_input", Input).value = str(self.__pattern.getPattern())
if self.__pattern and self.__pattern.quality:
self.query_one("#quality_input", Input).value = str(self.__pattern.quality)
self.updateTags()
self.updateTracks()
@ -301,6 +304,12 @@ class PatternDetailsScreen(Screen):
# 3
yield Static(" ", classes="seven")
# 4
yield Static("Quality")
yield Input(type="integer", id="quality_input")
yield Static(' ', classes="five")
# 4
yield Static(" ", classes="seven")
@ -367,6 +376,11 @@ class PatternDetailsScreen(Screen):
def getPatternFromInput(self):
return str(self.query_one("#pattern_input", Input).value)
def getQualityFromInput(self):
try:
return int(self.query_one("#quality_input", Input).value)
except ValueError:
return 0
def getSelectedTrackDescriptor(self):
@ -428,6 +442,7 @@ class PatternDetailsScreen(Screen):
patternDescriptor = {}
patternDescriptor['show_id'] = self.__showDescriptor.getId()
patternDescriptor['pattern'] = self.getPatternFromInput()
patternDescriptor['quality'] = self.getQualityFromInput()
if self.__pattern is not None:

@ -15,14 +15,8 @@ def executeProcess(commandSequence: List[str], directory: str = None, context: d
niceSequence = []
niceness = (int(context['resource_limits']['niceness'])
if not context is None
and 'resource_limits' in context.keys()
and 'niceness' in context['resource_limits'].keys() else 99)
cpu_percent = (int(context['resource_limits']['cpu_percent'])
if not context is None
and 'resource_limits' in context.keys()
and 'cpu_percent' in context['resource_limits'].keys() else 0)
niceness = int((context or {}).get('resource_limits', {}).get('niceness', 99))
cpu_percent = int((context or {}).get('resource_limits', {}).get('cpu_percent', 0))
if niceness >= -20 and niceness <= 19:
niceSequence += ['nice', '-n', str(niceness)]

@ -522,14 +522,6 @@ def convert(ctx,
ctx.obj['logger'].debug(f"\nVideo encoder: {video_encoder}")
qualityTokens = quality.split(',')
q_list = [q for q in qualityTokens if q.isnumeric()]
ctx.obj['logger'].debug(f"Qualities: {q_list}")
presetTokens = preset.split(',')
p_list = [p for p in presetTokens if p.isnumeric()]
ctx.obj['logger'].debug(f"Presets: {p_list}")
context['bitrates'] = {}
context['bitrates']['stereo'] = str(stereo_bitrate) if str(stereo_bitrate).endswith('k') else f"{stereo_bitrate}k"
@ -553,9 +545,12 @@ def convert(ctx,
tc = TmdbController() if context['use_tmdb'] else None
qualityKwargs = {QualityFilter.QUALITY_KEY: str(QualityFilter.DEFAULT_H264_QUALITY if (context['video_encoder'] == VideoEncoder.H264 and not quality) else quality)}
qualityKwargs = {QualityFilter.QUALITY_KEY: str(quality)}
qf = QualityFilter(**qualityKwargs)
if context['video_encoder'] == VideoEncoder.AV1 and preset:
presetKwargs = {PresetFilter.PRESET_KEY: preset}
PresetFilter(**presetKwargs)
@ -799,15 +794,18 @@ def convert(ctx,
ctx.obj['logger'].info(f"Creating file {targetFilename}")
if rename_only:
shutil.copyfile(sourcePath, targetPath)
else:
fc.runJob(sourcePath,
targetPath,
targetFormat,
context['video_encoder'],
chainIteration,
cropArguments)
cropArguments,
currentPattern)
endTime = time.perf_counter()
ctx.obj['logger'].info(f"\nDONE\nTime elapsed {endTime - startTime}")

@ -1,4 +1,5 @@
import os, click
from logging import Logger
from ffx.media_descriptor_change_set import MediaDescriptorChangeSet
@ -15,6 +16,8 @@ from ffx.filter.quality_filter import QualityFilter
from ffx.filter.preset_filter import PresetFilter
from ffx.filter.crop_filter import CropFilter
from ffx.model.pattern import Pattern
class FfxController():
@ -46,7 +49,7 @@ class FfxController():
targetMediaDescriptor,
sourceMediaDescriptor)
self.__logger = context['logger']
self.__logger: Logger = context['logger']
def generateAV1Tokens(self, quality, preset, subIndex : int = 0):
@ -179,12 +182,16 @@ class FfxController():
sourcePath,
targetPath,
targetFormat: str = '',
videoEncoder: VideoEncoder = VideoEncoder.VP9,
chainIteration: list = [],
cropArguments: dict = {}):
cropArguments: dict = {},
currentPattern: Pattern = None):
# quality: int = DEFAULT_QUALITY,
# preset: int = DEFAULT_AV1_PRESET):
videoEncoder: VideoEncoder = self.__context.get('video_encoder', VideoEncoder.VP9)
qualityFilters = [fy for fy in chainIteration if fy['identifier'] == 'quality']
presetFilters = [fy for fy in chainIteration if fy['identifier'] == 'preset']
@ -192,7 +199,18 @@ class FfxController():
denoiseFilters = [fy for fy in chainIteration if fy['identifier'] == 'nlmeans']
deinterlaceFilters = [fy for fy in chainIteration if fy['identifier'] == 'bwdif']
quality = (qualityFilters[0]['parameters']['quality'] if qualityFilters else QualityFilter.DEFAULT_VP9_QUALITY)
if qualityFilters and (quality := qualityFilters[0]['parameters']['quality']):
self.__logger.debug(f"Setting quality {quality} from filter")
elif (quality := currentPattern.quality):
self.__logger.debug(f"Setting quality {quality} from pattern default")
else:
quality = (QualityFilter.DEFAULT_H264_QUALITY
if (videoEncoder == VideoEncoder.H264)
else QualityFilter.DEFAULT_VP9_QUALITY)
self.__logger.debug(f"Setting quality {quality} from default")
preset = presetFilters[0]['parameters']['preset'] if presetFilters else PresetFilter.DEFAULT_PRESET

@ -1,7 +1,9 @@
import itertools
import click
from .filter import Filter
from ffx.video_encoder import VideoEncoder
class QualityFilter(Filter):
@ -14,6 +16,9 @@ class QualityFilter(Filter):
def __init__(self, **kwargs):
context = click.get_current_context().obj
self.__qualitiesList = []
qualities = kwargs.get(QualityFilter.QUALITY_KEY, '')
if qualities:
@ -27,7 +32,9 @@ class QualityFilter(Filter):
raise ValueError('QualityFilter: Quality value has to be between 0 and 63')
self.__qualitiesList.append(qualityValue)
else:
self.__qualitiesList = [QualityFilter.DEFAULT_VP9_QUALITY]
self.__qualitiesList = [None]
super().__init__(self)
@ -52,4 +59,4 @@ class QualityFilter(Filter):
def getYield(self):
for q in self.__qualitiesList:
yield self.getPayload(q)
yield self.getPayload(q)

Loading…
Cancel
Save