Example #1
0
def procInput(source, bitDepth, fs, out):
    out['load'] = 1
    node = Node({'op': 'toTorch', 'bits': bitDepth})
    fs.append(
        NonNullWrap(
            node.bindFunc(toTorch(bitDepth, config.dtype(), config.device()))))
    return fs, [node], out
Example #2
0
def procDN(opt, out, *_):
    DNopt = opt['opt']
    node = Node(dict(op='DN', model=opt['model']), out['load'])
    if 'name' in opt:
        node.name = opt['name']
    return [NonNullWrap(node.bindFunc(lambda im: runDN.dn(im, DNopt)))
            ], [node], out
Example #3
0
def procOutput(opt, out, *_):
    load = out['load']
    node0 = Node(dict(op='toFloat'), load)
    bitDepthOut = out['bitDepth']
    node1 = Node(dict(op='toOutput', bits=bitDepthOut),
                 load,
                 name=opt['name'] if 'name' in opt else None)
    fOutput = node1.bindFunc(toOutput(bitDepthOut))
    fs = [NonNullWrap(node0.bindFunc(toFloat)), NonNullWrap(fOutput)]
    ns = [node0, node1]
    if out['source']:
        fPreview[0] = restrictSize(2048)
        fs1 = [node0.bindFunc(toFloat), fOutput]
        if previewFormat:

            def o(im):
                res = reduce(applyNonNull, fs1, im)
                funcPreview(im)
                return [res]
        else:
            o = lambda im: [reduce(applyNonNull, fs1, im)]
        fs = [o]
        if out['channel']:
            fPreview[4] = BGR2RGB
        else:
            fPreview[4] = identity
            ns.append(
                appendFuncs(BGR2RGB, Node(dict(op='Channel')), fs1, False))
            out['channel'] = 1
        ns.append(
            appendFuncs(toBuffer(bitDepthOut),
                        Node(dict(op='toBuffer', bits=bitDepthOut), load), fs1,
                        False))
    return fs, ns, out
Example #4
0
def procDehaze(opt, out, *_):
  load = out['load']
  dehazeOpt = opt['opt']
  fs, ns = convertChannel(out) if out['channel'] else ([], [])
  node = Node(dict(op='dehaze'), load, name=opt['name'] if 'name' in opt else None)
  ns.append(appendFuncs(lambda im: dehaze.Dehaze(im, dehazeOpt), node, fs))
  return fs, ns, out
Example #5
0
def main():
    from progress import Node
    from worker import begin, context, enhance
    from imageProcess import genProcess
    from video import SR_vid
    from config import config
    stepFile = [{'op': 'file'}]
    imNode = Node({'op': 'image'}, learn=0)

    def lock(duration):
        from gevent.event import Event
        flag = Event()
        node = begin(Node({}, 1, duration, 0))
        node.reset().trace(0)
        while duration > 0 and not context.stopFlag.is_set():
            duration -= 1
            flag.wait(1)
            flag.clear()
            node.trace()
        return duration

    def imageEnhance(size, *args, name=None, trace=True):
        process, nodes = genProcess(stepFile + list(args))
        return begin(imNode, nodes,
                     True if trace else -1).bindFunc(process)(size, name=name)

    return getMM(), {
        'lock': lock,
        'image_enhance': enhance(imageEnhance),
        'video_enhance': enhance(SR_vid),
        'ednoise_enhance': enhance(imageEnhance),
        'image_dehaze': enhance(imageEnhance),
        'systemInfo': enhance(config.system)
    }
Example #6
0
def procSlomo(opt, out, *_):
    load = out['load']
    fs, ns = convertChannel(out) if out['channel'] else ([], [])
    node = Node(dict(op='slomo'),
                load,
                opt['sf'],
                name=opt['name'] if 'name' in opt else None)
    return fs + [runSlomo.doSlomo], ns + [node], out
Example #7
0
def genProcess(steps, root=True, outType=None):
  funcs=[]
  nodes=[]
  last = identity
  rf = lambda im: reduce(apply, funcs, im)
  if root:
    for i, opt in enumerate(steps):
      opt['name'] = i + (0 if steps[0]['op'] == 'file' else 2)
    for opt in filter((lambda opt: opt['op'] == 'SR'), steps):
      toInt(opt, ['scale', 'ensemble'])
      opt['opt'] = runSR.getOpt(opt)
    for opt in filter((lambda opt: opt['op'] == 'resize'), steps):
      toInt(opt, ['width', 'height'])
      if 'scaleW' in opt:
        opt['scaleW'] = float(opt['scaleW'])
      if 'scaleH' in opt:
        opt['scaleH'] = float(opt['scaleH'])
    for opt in filter((lambda opt: opt['op'] == 'DN'), steps):
      opt['opt'] = runDN.getOpt(opt)
    for opt in filter((lambda opt: opt['op'] == 'dehaze'), steps):
      opt['opt'] = dehaze.getOpt(opt)
    slomos = [*filter((lambda opt: opt['op'] == 'slomo'), steps)]
    for opt in slomos:
      toInt(opt, ['sf'])
      opt['opt'] = runSlomo.getOpt(opt)
    if len(slomos):
      slomos[-1]['opt'].notLast = 0
    if steps[-1]['op'] != 'output':
      steps.append(dict(op='output'))
    config.getFreeMem(True)
    process = lambda im, name=None: last(rf(im), name, context)
  else:
    process = rf
  for i, opt in enumerate(steps):
    op = opt['op']
    fs, ns, outType = procs[op](opt, outType, nodes)
    funcs.extend(fs)
    nodes.extend(ns)
    if op == 'slomo':
      if i + 1 < len(steps):
        f, nodesAfter = genProcess(steps[i + 1:], False, outType)
      else:
        f = identity
        nodesAfter = []
      slomoOpt = opt['opt']
      slomo = funcs[-1](f, nodes[-1], slomoOpt)
      funcs[-1] = windowWrap(slomo, slomoOpt, 2)
      nodeAfter = Node({}, total=opt['sf'], learn=0)
      for node in nodesAfter:
        nodeAfter.append(node)
      nodes.append(nodeAfter)
      break
  if root and steps[0]['op'] == 'file':
    n = Node({'op': 'write'}, outType['load'])
    nodes.append(n)
    last = n.bindFunc(writeFile)
  else:
    context.imageMode = 'RGB'
  return process, nodes
Example #8
0
 def lock(duration):
     from gevent.event import Event
     flag = Event()
     node = begin(Node({}, 1, duration, 0))
     node.reset().trace(0)
     while duration > 0 and not context.stopFlag.is_set():
         duration -= 1
         flag.wait(1)
         flag.clear()
         node.trace()
     return duration
Example #9
0
def procSR(opt, out, *_):
  load = out['load']
  scale = opt['scale']
  mode = opt['model']
  SRopt = opt['opt']
  if not scale > 1:
    raise TypeError('Invalid scale setting for SR.')
  out['load'] = load * scale * scale
  fs, ns = convertChannel(out) if out['channel'] and mode == 'gan' else ([], [])
  ns.append(appendFuncs(lambda im: runSR.sr(im, SRopt), Node(dict(op='SR', model=mode), load), fs))
  if 'name' in opt:
    ns[-1].name = opt['name']
  return fs, ns, out
Example #10
0
def genProcess(steps, root=True, outType=None):
    funcs = []
    nodes = []
    last = identity
    rf = lambda im: reduce(apply, funcs, im)
    if root:
        stepOffset = 0 if steps[0]['op'] == 'file' else 2
        for i, opt in enumerate(steps):
            opt['name'] = i + stepOffset
            if opt['op'] == 'resize':
                if 'scaleW' in opt:
                    opt['scaleW'] = float(opt['scaleW'])
                if 'scaleH' in opt:
                    opt['scaleH'] = float(opt['scaleH'])
            if opt['op'] in stepOpts:
                stepOpt = stepOpts[opt['op']]
                toInt(opt, stepOpt.get('toInt', []))
                if 'getOpt' in stepOpt:
                    opt['opt'] = stepOpt['getOpt'].getOpt(opt)
        if steps[-1]['op'] != 'output':
            steps.append(dict(op='output'))
        config.getFreeMem(True)
        process = lambda im, name=None: last(rf(im), name, context)
    else:
        process = rf
    for i, opt in enumerate(steps):
        op = opt['op']
        fs, ns, outType = procs[op](opt, outType, nodes)
        funcs.extend(fs)
        nodes.extend(ns)
        if op in videoOps:
            if i + 1 < len(steps):
                f, nodesAfter = genProcess(steps[i + 1:], False, outType)
            else:
                f = identity
                nodesAfter = []
            videoOpt = opt['opt']
            func = funcs[-1](f, nodes[-1], videoOpt)
            funcs[-1] = windowWrap(func, videoOpt,
                                   videoOps[op]) if videoOps[op] > 1 else func
            nodeAfter = Node({}, total=opt.get('sf', 1), learn=0)
            for node in nodesAfter:
                nodeAfter.append(node)
            nodes.append(nodeAfter)
            break
    if root and steps[0]['op'] == 'file':
        n = Node({'op': 'write'}, outType['load'])
        nodes.append(n)
        last = n.bindFunc(writeFile)
    else:
        context.imageMode = 'RGB'
    return process, nodes
Example #11
0
def doESTRNN(func, node, opt):
  nodes = [Node({'ESTRNN': key}) for key in ('forward', 'pooling', 'fusion', 'recons')]
  inp = StreamState(offload=False)
  forward = StreamState(offload=False)
  forward.feat_hidden = None
  StreamState.pipe(nodes[0].bindFunc(calcForward), [inp], [forward], args=[opt, forward])
  hs = StreamState(RefTime, reserve=1)
  inpW = StreamState()
  StreamState.pipe(identity, [forward], [hs, inpW])
  w = StreamState(RefTime, reserve=1)
  StreamState.pipe(nodes[1].bindFunc(pooling), [inpW], [w])
  fusion = StreamState(offload=False)
  opt.fusionStream = StreamState.pipe(nodes[2].bindFunc(opt.fusion), [hs, w], [fusion])
  recons = StreamState(store=False)
  opt.out = StreamState.pipe(nodes[3].bindFunc(doCrop), [fusion], [recons], args=[opt.recons])
  return makeStreamFunc(func, node, opt, nodes, 'ESTRNN', [hs, w], initFunc, inp.push)
Example #12
0
def genProcess(steps, root=True, outType=None):
  funcs=[]
  nodes=[]
  last = identity
  rf = lambda im: reduce(apply, funcs, im)
  if root:
    for opt in filter((lambda opt: opt['op'] == 'SR'), steps):
      opt['scale'] = int(opt['scale'])
      opt['opt'] = runSR.getOpt(opt['scale'], opt['model'], config.ensembleSR)
    for opt in filter((lambda opt: opt['op'] == 'resize'), steps):
      opt['scale'] = int(opt['scale'])
    for opt in filter((lambda opt: opt['op'] == 'DN'), steps):
      opt['opt'] = runDN.getOpt(opt['model'])
    for opt in filter((lambda opt: opt['op'] == 'dehaze'), steps):
      opt['opt'] = dehaze.getOpt()
    slomos = [*filter((lambda opt: opt['op'] == 'slomo'), steps)]
    for opt in slomos:
      opt['sf'] = int(opt['sf'])
      opt['opt'] = runSlomo.getOpt(opt)
    if len(slomos):
      slomos[-1]['opt'].notLast = 0
    steps.append(dict(op='output'))
    config.getFreeMem(True)
    process = lambda im, name=None: last(rf(im), name)
  else:
    process = rf
  for i, opt in enumerate(steps):
    op = opt['op']
    fs, ns, outType = procs[op](opt, outType, nodes)
    funcs.extend(fs)
    nodes.extend(ns)
    if op == 'slomo':
      if i + 1 < len(steps):
        f, nodesAfter = genProcess(steps[i + 1:], False, outType)
      else:
        f = identity
        nodesAfter = []
      slomoOpt = opt['opt']
      slomo = funcs[-1](f, nodes[-1])
      funcs[-1] = windowWrap(lambda data: slomo(data, slomoOpt), 2, runSlomo.getBatchSize(opt))
      nodeAfter = Node({}, total=opt['sf'], learn=0)
      for node in nodesAfter:
        nodeAfter.append(node)
      nodes.append(nodeAfter)
      break
  if root and steps[0]['op'] == 'file':
    n = Node({'op': 'write'}, outType['load'])
    nodes.append(n)
    last = n.bindFunc(writeFile)
  return process, nodes
Example #13
0
def main():
    from progress import Node
    from worker import begin, context, enhance
    from procedure import genProcess
    from video import SR_vid
    from config import config
    stepFile = [{'op': 'file'}]
    imNode = Node({'op': 'image'}, learn=0)

    def lock(duration):
        from gevent.event import Event
        flag = Event()
        node = begin(Node({}, 1, duration, 0))
        node.reset().trace(0)
        while duration > 0 and not context.stopFlag.is_set():
            duration -= 1
            flag.wait(1)
            flag.clear()
            node.trace()
        return duration

    def imageEnhance(size, *args):
        outputOpt = args[-1]
        name = outputOpt['file'] if 'file' in outputOpt else None
        if not ('op' in outputOpt and outputOpt['op'] == 'output'):
            outputOpt = {}
        bench = outputOpt.get('diagnose', {}).get('bench', False)
        trace = outputOpt.get('trace', False) or bench
        process, nodes = genProcess(stepFile + list(args))
        return begin(imNode, nodes, trace, bench).bindFunc(process)(size,
                                                                    name=name)

    mm = getMM(sharedMemSize, False)

    return mm, {
        'lockInterface': lock,
        'image_enhance': enhance(imageEnhance, verbose=False),
        'batch': enhance(imageEnhance, verbose=False),
        'video_enhance': enhance(SR_vid),
        'systemInfo': enhance(config.system)
    }
Example #14
0
def doVSR(func, node, opt):
    nodes = [
        Node({'IconVSR': key})
        for key in ('KeyframeFeature', 'Flow', 'Backward', 'Flow', 'Forward',
                    'upsample')
    ]
    inp = StreamState(offload=False)
    inp1 = StreamState()
    inp2 = StreamState()
    backwardInp = StreamState()
    flowInp = StreamState(2, offload=False)
    flowForwardInp = StreamState(offload=False).setPadding(1)
    flowBackwardInp = StreamState(offload=False)
    isKeyFrame = KeyFrameState(RefTime)
    keyframeFeatureInp = StreamState(RefTime,
                                     tensor=False,
                                     reserve=1,
                                     offload=False)
    StreamState.pipe(identity, [inp], [inp1, inp2, flowInp, backwardInp])
    StreamState.pipe(identity, [flowInp], [flowForwardInp, flowBackwardInp])
    keyframeFeature = StreamState(tensor=False, offload=False)
    StreamState.pipe(nodes[0].bindFunc(getKeyframeFeature),
                     [keyframeFeatureInp, isKeyFrame], [keyframeFeature],
                     args=[opt],
                     size=7)
    keyframeFeature1 = StreamState(tensor=False)
    keyframeFeature2 = StreamState(tensor=False)
    StreamState.pipe(identity, [keyframeFeature],
                     [keyframeFeature1, keyframeFeature2])
    flowBackward = StreamState(tensor=False)
    opt.flowBackward = StreamState.pipe(nodes[1].bindFunc(calcFlowBackward),
                                        [flowBackwardInp], [flowBackward],
                                        args=[opt],
                                        size=1)
    backward = StreamState(3, tensor=False)
    StreamState.pipe(nodes[2].bindFunc(calcBackward),
                     [backwardInp, flowBackward, keyframeFeature1], [backward],
                     args=[opt],
                     size=20)
    flowForward = StreamState(tensor=False, offload=False)
    flowForward.first = 1  # signal alignment for frame 0, 1
    opt.flowForward = StreamState.pipe(nodes[3].bindFunc(calcFlowForward),
                                       [flowForwardInp], [flowForward],
                                       args=[opt, flowForward],
                                       size=1)
    forward = StreamState(offload=False)
    forward.feat_prop = None
    StreamState.pipe(nodes[4].bindFunc(calcForward),
                     [inp1, flowForward, keyframeFeature2, backward],
                     [forward],
                     args=[opt, forward])
    upsample = StreamState(store=False)
    opt.out = StreamState.pipe(nodes[5].bindFunc(doUpsample), [inp2, forward],
                               [upsample],
                               args=[opt],
                               size=1)

    def pushFunc(x):
        if opt.i + opt.startPadding >= RefTime >> 1:
            inp.push(x)
        keyframeFeatureInp.push(x)

    return makeStreamFunc(func, node, opt, nodes, 'VSR', [keyframeFeatureInp],
                          initFunc, pushFunc)
Example #15
0
def prepare(video, by, steps):
    optEncode = steps[-1]
    encodec = optEncode.get('codec', config.defaultEncodec)  # pylint: disable=E1101
    optDecode = steps[0]
    decodec = optDecode.get('codec', config.defaultDecodec)  # pylint: disable=E1101
    optRange = steps[1]
    start = int(optRange.get('start', 0))
    outDir = config.outDir  # pylint: disable=E1101
    procSteps = stepVideo + list(steps[2:-1])
    diagnose = optEncode.get('diagnose', {})
    bench = diagnose.get('bench', False)
    clear = diagnose.get('clear', False)
    process, nodes = genProcess(procSteps)
    traceDetail = config.progressDetail or bench  # pylint: disable=E1101
    root = begin(Node({'op': 'video'}, 1, 2, 0), nodes, traceDetail, bench,
                 clear)
    context.root = root
    slomos = [*filter((lambda opt: opt['op'] == 'slomo'), procSteps)]
    if start < 0:
        start = 0
    if start and len(
            slomos
    ):  # should generate intermediate frames between start-1 and start
        start -= 1
        for opt in slomos:
            opt['opt'].firstTime = 0
    stop = int(optRange.get('stop', -1))
    if stop <= start:
        stop = -1
    root.total = -1 if stop < 0 else stop - start
    outputPath = fixExt(
        splitext(optEncode.get('file', '') or outDir + '/' + config.getPath()))
    dataPath = suffix(outputPath, '-a')
    commandIn = [
        ffmpegPath, '-hide_banner', '-f', 'lavfi', '-i', video, '-vn', '-c',
        'copy', '-y', dataPath, '-map', '0:v', '-f', 'rawvideo', '-pix_fmt',
        pix_fmt
    ]
    if by != 'cmd':
        commandIn = clipList(commandIn, 2, 4)
    if len(decodec):
        commandIn.extend(decodec.split(' '))
    commandIn.append('-')
    metadata = [
        '-metadata', 'service_provider="MoePhoto {}"'.format(config.version)
    ]  # pylint: disable=E1101
    commandVideo = [
        ffmpegPath, '-hide_banner', '-y', '-f', 'rawvideo', '-pix_fmt',
        pix_fmt, '-s', '', '-r', '', '-i', '-', '-i', dataPath, '-map', '0:v',
        '-map', '1?', '-map', '-1:v', '-c:1', 'copy', *metadata, '-c:v:0'
    ] + encodec.split(' ') + ['']
    commandOut = None
    if by:
        commandVideo[-1] = suffix(outputPath, '-v')
        commandOut = [
            ffmpegPath, '-hide_banner', '-y', '-i', commandVideo[-1], '-i',
            dataPath, '-map', '0:v', '-map', '1?', '-c:0', 'copy', '-c:1',
            'copy', *metadata, outputPath
        ]
    else:
        commandVideo[14] = video
    frameRate = optEncode.get('frameRate', 0)
    width = optDecode.get('width', 0)
    height = optDecode.get('height', 0)
    sizes = filter((lambda opt: opt['op'] == 'SR' or opt['op'] == 'resize'),
                   procSteps)
    return outputPath, process, start, stop, root, commandIn, commandVideo, commandOut, slomos, sizes, width, height, frameRate
Example #16
0
def convertChannel(out):
    out['channel'] = 0
    fs = []
    return fs, [appendFuncs(BGR2RGBTorch, Node(dict(op='Channel')), fs)]
Example #17
0
def procResize(opt, out, nodes):
    node = Node(dict(op='resize', mode=opt['method']),
                1,
                name=opt['name'] if 'name' in opt else None)
    return [node.bindFunc(NonNullWrap(resize(opt, out, len(nodes),
                                             nodes)))], [node], out
Example #18
0
from progress import Node
from imageProcess import toFloat, toOutput, toOutput8, toTorch, toNumPy, toBuffer, toInt, readFile, writeFile, BGR2RGB, BGR2RGBTorch, resize, restrictSize, windowWrap, apply, identity, previewFormat, previewPath, ensemble
import runDN
import runSR
import runSlomo
import dehaze
import videoSR
import ESTRNN
from worker import context

videoOps = dict(slomo=runSlomo.WindowSize,
                VSR=videoSR.WindowSize,
                demob=ESTRNN.WindowSize)
applyNonNull = lambda v, f: NonNullWrap(f)(v)
NonNullWrap = lambda f: lambda x: f(x) if not x is None else None
newNode = lambda opt, op, load=1, total=1: Node(
    op, load, total, name=opt.get('name', None))


def appendFuncs(f, node, funcs, wrap=True):
    g = node.bindFunc(f)
    funcs.append(NonNullWrap(g) if wrap else g)
    return node


fPreview = [
    0, toFloat, toOutput8, (lambda im: im.astype(np.uint8)), 0,
    lambda im: writeFile(im, context.shared, context, previewFormat),
    lambda *_: context.root.trace(
        0, preview=previewPath, fileSize=context.shared.tell())
]
funcPreview = lambda im: reduce(applyNonNull, fPreview, im)
Example #19
0
def prepare(video, steps):
  optEncode = steps[-1]
  encodec = optEncode['codec'] if 'codec' in optEncode else config.defaultEncodec  # pylint: disable=E1101
  optDecode = steps[0]
  decodec = optDecode['codec'] if 'codec' in optDecode else config.defaultDecodec  # pylint: disable=E1101
  optRange = steps[1]
  start = int(optRange['start']) if 'start' in optRange else 0
  outDir = config.outDir  # pylint: disable=E1101
  procSteps = stepVideo + list(steps[2:-1])
  process, nodes = genProcess(procSteps)
  root = begin(Node({'op': 'video', 'encodec': encodec}, 1, 2, 0), nodes, False)
  context.root = root
  width, height, frameRate, totalFrames = getVideoInfo(video)
  slomos = [*filter((lambda opt: opt['op'] == 'slomo'), procSteps)]
  if 'frameRate' in optEncode:
    frameRate = optEncode['frameRate']
  else:
    for opt in slomos:
      frameRate *= opt['sf']
  if 'width' in optDecode:
    width = optDecode['width']
  if 'height' in optDecode:
    height = optDecode['height']
  outWidth, outHeight = (width, height)
  for opt in filter((lambda opt: opt['op'] == 'SR' or opt['op'] == 'resize'), procSteps):
    if opt['op'] == 'SR':
      outWidth *= opt['scale']
      outHeight *= opt['scale']
    else: # resize
      outWidth = round(outWidth * opt['scaleW']) if 'scaleW' in opt else opt['width']
      outHeight = round(outHeight * opt['scaleH']) if 'scaleH' in opt else opt['height']
  if start < 0:
    start = 0
  if start and len(slomos): # should generate intermediate frames between start-1 and start
    start -= 1
    for opt in slomos:
      opt['opt'].firstTime = 0
  stop = None
  if 'stop' in optRange:
    stop = int(optRange['stop'])
    if stop <= start:
      stop = None
  root.total = (stop if stop else totalFrames) - start
  if not stop:
    stop = 0xffffffff
  root.multipleLoad(width * height * 3)
  initialETA(root)
  root.reset().trace(0)
  videoName = config.getPath()
  outputPath = outDir + '/' + videoName
  commandIn = [
    ffmpegPath,
    '-i', video,
    '-an',
    '-sn',
    '-f', 'rawvideo',
    '-s', '{}x{}'.format(width, height),
    '-pix_fmt', pix_fmt]
  if len(decodec):
    commandIn.extend(decodec.split(' '))
  commandIn.append('-')
  commandOut = [
    ffmpegPath,
    '-y',
    '-f', 'rawvideo',
    '-pix_fmt', pix_fmt,
    '-s', '{}x{}'.format(outWidth, outHeight),
    '-r', str(frameRate),
    '-i', '-',
    '-i', video,
    '-map', '0:v',
    '-map', '1?',
    '-map', '-1:v',
    '-c:1', 'copy',
    '-c:v:0']
  if start > 0:
    commandOut = commandOut[:12] + commandOut[22:]
  if len(encodec):
    commandOut.extend(encodec.split(' '))
  commandOut.append(outputPath)
  return commandIn, commandOut, outputPath, width, height, start, stop, root, process
Example #20
0
def prepare(video, by, steps):
    optEncode = steps[-1]
    encodec = optEncode.get('codec', config.defaultEncodec)  # pylint: disable=E1101
    optDecode = steps[0]
    decodec = optDecode.get('codec', config.defaultDecodec)  # pylint: disable=E1101
    optRange = steps[1]
    start = int(optRange.get('start', 0))
    outDir = config.outDir  # pylint: disable=E1101
    procSteps = stepVideo + list(steps[2:-1])
    diagnose = optEncode.get('diagnose', {})
    bench = diagnose.get('bench', False)
    clear = diagnose.get('clear', False)
    process, nodes = genProcess(procSteps)
    traceDetail = config.progressDetail or bench  # pylint: disable=E1101
    root = begin(Node({'op': 'video'}, 1, 2, 0), nodes, traceDetail, bench,
                 clear)
    context.root = root
    slomos = [step for step in procSteps if step['op'] == 'slomo']
    refs, ahead = 0, 0
    if start < 0:
        start = 0
    for i in range(
            len(procSteps) - 1, -1, -1
    ):  # gather some reference frames before start point for video models
        step = procSteps[i]
        if step['op'] == 'slomo':
            step['opt'].outStart = -refs % step['sf'] if refs else 1
            step['opt'].outEnd = -(-ahead % step['sf'])
            refs = max(ceil(refs / step['sf']), lookback[step['op']])
            ahead = max(ceil(ahead / step['sf']), lookahead[step['op']])
        elif step['op'] in padOp:
            step['opt'].start = 0
            step['opt'].end = 0
            refs += lookback[step['op']]
            ahead += lookahead[step['op']]
    if start < refs:  # no enough reference frames
        arefs = start
        for step in procSteps:
            if arefs >= refs:
                break
            if step['op'] == 'slomo':
                refs = refs * step['sf'] - step['opt'].outStart
                step['opt'].outStart = 0
                arefs = arefs * step['sf']
            elif step['op'] in padOp:
                step['opt'].start = min(refs - arefs, lookback[step['op']])
                refs -= step['opt'].start
        start = 0
    else:
        start -= refs
    stop = int(optRange.get('stop', -1))
    if stop <= start:
        stop = -1
    root.total = -1 if stop < 0 else stop - start
    outputPath = fixExt(
        splitext(optEncode.get('file', '') or outDir + '/' + config.getPath()))
    dataPath = suffix(outputPath, '-a')
    commandIn = [
        ffmpegPath, '-hide_banner', '-f', 'lavfi', '-i', video, '-vn', '-c',
        'copy', '-y', dataPath, '-map', '0:v', '-f', 'rawvideo', '-pix_fmt',
        pix_fmt
    ]
    if by != 'cmd':
        commandIn = clipList(commandIn, 2, 4)
    if len(decodec):
        commandIn.extend(decodec.split(' '))
    commandIn.append('-')
    metadata = [
        '-metadata', 'service_provider="MoePhoto {}"'.format(config.version)
    ]  # pylint: disable=E1101
    commandVideo = [
        ffmpegPath, '-hide_banner', '-y', '-f', 'rawvideo', '-pix_fmt',
        pix_fmt, '-s', '', '-r', '', '-thread_queue_size', '64', '-i', '-',
        '-i', dataPath, '-map', '0:v', '-map', '1?', '-map', '-1:v', '-c:1',
        'copy', *metadata, '-c:v:0'
    ] + encodec.split(' ') + ['']
    commandOut = None
    if by:
        commandVideo[-1] = suffix(outputPath, '-v')
        commandOut = [
            ffmpegPath, '-hide_banner', '-y', '-i', commandVideo[-1], '-i',
            dataPath, '-map', '0:v', '-map', '1?', '-c:0', 'copy', '-c:1',
            'copy', *metadata, outputPath
        ]
    else:
        commandVideo[16] = video
    frameRate = optEncode.get('frameRate', 0)
    width = optDecode.get('width', 0)
    height = optDecode.get('height', 0)
    sizes = [step for step in procSteps if step['op'] in resizeOp]
    return outputPath, process, start, stop, ahead, root, commandIn, commandVideo, commandOut, slomos, sizes, width, height, frameRate