Beispiel #1
0
def create_select_chunk(args: Args, index: int, src_path: Path,
                        frame_start: int, frame_end: int) -> Chunk:
    """
    Creates a chunk using ffmpeg's select filter

    :param args: the Args
    :param src_path: the path of the entire unchunked source file
    :param index: the index of the chunk
    :param frame_start: frame that this chunk should start on (0-based, inclusive)
    :param frame_end: frame that this chunk should end on (0-based, exclusive)
    :return: a Chunk
    """
    assert frame_end > frame_start, "Can't make a chunk with <= 0 frames!"

    frames = frame_end - frame_start
    frame_end -= 1  # the frame end boundary is actually a frame that should be included in the next chunk

    ffmpeg_gen_cmd = [
        'ffmpeg', '-y', '-hide_banner', '-loglevel', 'error', '-i',
        src_path.as_posix(), '-vf',
        f'select=between(n\\,{frame_start}\\,{frame_end}),setpts=PTS-STARTPTS',
        *args.pix_format, '-bufsize', '50000K', '-f', 'yuv4mpegpipe', '-'
    ]
    extension = ENCODERS[args.encoder].output_extension
    size = frames  # use the number of frames to prioritize which chunks encode first, since we don't have file size

    chunk = Chunk(args.temp, index, ffmpeg_gen_cmd, extension, size, frames)

    return chunk
Beispiel #2
0
def plot_vmaf(source: Path, encoded: Path, args, model, vmaf_res):
    """
    Making VMAF plot after encode is done
    """

    print('Calculating Vmaf...\r', end='')

    fl_path = encoded.with_name(f'{encoded.stem}_vmaflog').with_suffix(".json")

    # call_vmaf takes a chunk, so make a chunk of the entire source
    ffmpeg_gen_cmd = [
        'ffmpeg', '-y', '-hide_banner', '-loglevel', 'error', '-i',
        source.as_posix(), *args.pix_format, '-f', 'yuv4mpegpipe', '-'
    ]
    input_chunk = Chunk(args.temp, 0, ffmpeg_gen_cmd, '', 0, 0)

    scores = call_vmaf(input_chunk,
                       encoded,
                       0,
                       model,
                       vmaf_res,
                       fl_path=fl_path)

    if not scores.exists():
        print(
            f'Vmaf calculation failed for chunks:\n {source.name} {encoded.stem}'
        )
        sys.exit()

    file_path = encoded.with_name(f'{encoded.stem}_plot').with_suffix('.png')
    plot_vmaf_score_file(scores, file_path)
Beispiel #3
0
def create_vsffms2_chunk(args: Args, index: int, load_script: Path,
                         frame_start: int, frame_end: int) -> Chunk:
    """
    Creates a chunk using vspipe and ffms2

    :param args: the Args
    :param load_script: the path to the .vpy script for vspipe
    :param index: the index of the chunk
    :param frame_start: frame that this chunk should start on (0-based, inclusive)
    :param frame_end: frame that this chunk should end on (0-based, exclusive)
    :return: a Chunk
    """
    assert frame_end > frame_start, "Can't make a chunk with <= 0 frames!"

    frames = frame_end - frame_start
    frame_end -= 1  # the frame end boundary is actually a frame that should be included in the next chunk

    ffmpeg_gen_cmd = [
        'vspipe',
        load_script.as_posix(), '-y', '-', '-s',
        str(frame_start), '-e',
        str(frame_end)
    ]
    extension = ENCODERS[args.encoder].output_extension
    size = frames  # use the number of frames to prioritize which chunks encode first, since we don't have file size

    chunk = Chunk(args.temp, index, ffmpeg_gen_cmd, extension, size, frames)

    return chunk
Beispiel #4
0
def target_vmaf_routine(args: Args, chunk: Chunk):
    """
    Applies target vmaf to this chunk. Determines what the cq value should be and sets the
    vmaf_target_cq for this chunk

    :param args: the Args
    :param chunk: the Chunk
    :return: None
    """
    chunk.vmaf_target_cq = target_vmaf(chunk, args)
Beispiel #5
0
def per_frame_target_quality_routine(args: Project, chunk: Chunk):
    """
    Applies per_shot_target_quality to this chunk. Determines what the cq value should be and sets the
    per_shot_target_quality_cq for this chunk

    :param args: the Project
    :param chunk: the Chunk
    :return: None
    """
    chunk.per_frame_target_quality_cq = per_frame_target_quality(chunk, args)
Beispiel #6
0
def read_chunk_queue(temp: Path) -> List[Chunk]:
    """
    Reads the chunk queue from the chunks.json file

    :param temp: the temp directory
    :return: the chunk queue
    """
    with open(temp / 'chunks.json', 'r') as file:
        chunk_dicts = json.load(file)
    return [Chunk.create_from_dict(cd, temp) for cd in chunk_dicts]
Beispiel #7
0
def create_chunk_from_segment(args: Args, index: int, file: Path) -> Chunk:
    """
    Creates a Chunk object from a segment file generated by ffmpeg

    :param args: the Args
    :param index: the index of the chunk
    :param file: the segmented file
    :return: A Chunk
    """
    ffmpeg_gen_cmd = [
        'ffmpeg', '-y', '-hide_banner', '-loglevel', 'error', '-i',
        file.as_posix(), *args.pix_format, '-bufsize', '50000K', '-f',
        'yuv4mpegpipe', '-'
    ]
    file_size = file.stat().st_size
    frames = frame_probe(file)
    extension = ENCODERS[args.encoder].output_extension

    chunk = Chunk(args.temp, index, ffmpeg_gen_cmd, extension, file_size,
                  frames)

    return chunk