2020-08-19 19:50:31 +00:00
|
|
|
from typing import Tuple, Optional
|
|
|
|
|
2020-11-25 07:32:26 +00:00
|
|
|
from Projects import Project
|
2020-09-14 17:45:21 +00:00
|
|
|
from Chunks.chunk import Chunk
|
2020-08-16 04:20:58 +00:00
|
|
|
from Av1an.commandtypes import MPCommands, CommandPair, Command
|
2020-09-14 17:45:21 +00:00
|
|
|
from Encoders.encoder import Encoder
|
2020-08-19 22:10:29 +00:00
|
|
|
from Av1an.utils import list_index_of_regex
|
2020-08-16 04:20:58 +00:00
|
|
|
|
|
|
|
|
|
|
|
class SvtVp9(Encoder):
|
|
|
|
|
|
|
|
def __init__(self):
|
2020-08-19 19:50:31 +00:00
|
|
|
super().__init__(
|
2020-08-16 04:20:58 +00:00
|
|
|
encoder_bin='SvtVp9EncApp',
|
2020-09-15 17:36:23 +00:00
|
|
|
encoder_help='SvtVp9EncApp --help',
|
2020-08-16 04:20:58 +00:00
|
|
|
default_args=None,
|
2020-08-19 19:50:31 +00:00
|
|
|
default_passes=1,
|
2020-11-25 07:46:37 +00:00
|
|
|
default_q_range=(20, 50),
|
2020-08-16 04:20:58 +00:00
|
|
|
output_extension='ivf'
|
|
|
|
)
|
|
|
|
|
|
|
|
@staticmethod
|
2020-11-25 07:32:26 +00:00
|
|
|
def compose_ffmpeg_raw_pipe(a: Project) -> Command:
|
2020-08-16 04:20:58 +00:00
|
|
|
"""
|
|
|
|
Compose a rawvideo ffmpeg pipe for svt-vp9
|
|
|
|
SVT-VP9 requires rawvideo, so we can't use arg.ffmpeg_pipe
|
|
|
|
|
2020-11-25 07:32:26 +00:00
|
|
|
:param a: the Project
|
2020-08-16 04:20:58 +00:00
|
|
|
:return: a command
|
|
|
|
"""
|
2020-08-19 07:06:42 +00:00
|
|
|
return ['ffmpeg', '-y', '-hide_banner', '-loglevel', 'error', '-i', '-', *a.ffmpeg, *a.pix_format, '-bufsize',
|
|
|
|
'50000K', '-f', 'rawvideo', '-']
|
2020-08-16 04:20:58 +00:00
|
|
|
|
2020-11-25 07:32:26 +00:00
|
|
|
def compose_1_pass(self, a: Project, c: Chunk, output: str) -> MPCommands:
|
2020-08-16 04:20:58 +00:00
|
|
|
return [
|
2020-08-19 07:06:42 +00:00
|
|
|
CommandPair(
|
|
|
|
SvtVp9.compose_ffmpeg_raw_pipe(a),
|
2020-08-19 22:10:29 +00:00
|
|
|
['SvtVp9EncApp', '-i', 'stdin', '-n', f'{c.frames}', *a.video_params, '-b', output]
|
2020-08-19 07:06:42 +00:00
|
|
|
)
|
2020-08-16 04:20:58 +00:00
|
|
|
]
|
|
|
|
|
2020-11-25 07:32:26 +00:00
|
|
|
def compose_2_pass(self, a: Project, c: Chunk, output: str) -> MPCommands:
|
2020-08-16 04:20:58 +00:00
|
|
|
raise ValueError("SVT-VP9 doesn't support 2 pass")
|
2020-08-19 22:10:29 +00:00
|
|
|
|
2020-11-25 07:32:26 +00:00
|
|
|
def is_valid(self, project: Project) -> Tuple[bool, Optional[str]]:
|
|
|
|
if project.video_params is None:
|
2020-08-19 19:50:31 +00:00
|
|
|
return False, 'SVT-VP9 requires: -w, -h, and -fps/-fps-num/-fps-denom'
|
2020-11-25 07:32:26 +00:00
|
|
|
return super().is_valid(project)
|
2020-08-19 19:50:31 +00:00
|
|
|
|
2020-08-22 19:24:09 +00:00
|
|
|
def man_q(self, command: Command, q: int) -> Command:
|
2020-08-19 22:10:29 +00:00
|
|
|
"""Return command with new cq value
|
|
|
|
|
|
|
|
:param command: old command
|
|
|
|
:param q: new cq value
|
|
|
|
:return: command with new cq value"""
|
|
|
|
|
|
|
|
adjusted_command = command.copy()
|
|
|
|
|
|
|
|
i = list_index_of_regex(adjusted_command, r"-q")
|
|
|
|
adjusted_command[i + 1] = f'{q}'
|
|
|
|
|
|
|
|
return adjusted_command
|
2020-08-21 13:31:09 +00:00
|
|
|
|
2020-08-22 19:24:09 +00:00
|
|
|
def match_line(self, line: str):
|
2020-08-21 13:31:09 +00:00
|
|
|
"""Extract number of encoded frames from line.
|
|
|
|
|
|
|
|
:param line: one line of text output from the encoder
|
|
|
|
:return: match object from re.search matching the number of encoded frames"""
|
|
|
|
pass # todo: SVT encoders are special in the way they output to console
|