Adds setting quality accoeding to pattern default
This commit is contained in:
4
.gitignore
vendored
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)
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user