Skip to content

Commit

Permalink
Deinterlacing and better filter logic
Browse files Browse the repository at this point in the history
  • Loading branch information
multiflexi committed Sep 25, 2021
1 parent 3601cc1 commit 9983785
Showing 1 changed file with 43 additions and 17 deletions.
60 changes: 43 additions & 17 deletions files/helpers.py
Expand Up @@ -3,7 +3,6 @@

import hashlib
import json
import math
import os
import random
import shutil
Expand Down Expand Up @@ -245,6 +244,7 @@ def media_file_info(input_file):
- `video_bitrate`: Bitrate of the video stream in kBit/s
- `video_width`: Width in pixels
- `video_height`: Height in pixels
- `interlaced` : True if the video is interlaced
- `video_codec`: Video codec
- `audio_duration`: Duration of the audio in `s.msec`
- `audio_sample_rate`: Audio sample rate in Hz
Expand Down Expand Up @@ -369,16 +369,20 @@ def media_file_info(input_file):
stdout = run_command(cmd).get("out")
stream_size = sum([int(line) for line in stdout.split("\n") if line != ""])
video_bitrate = round((stream_size * 8 / 1024.0) / video_duration, 2)
if "r_frame_rate" in video_info.keys():

if "r_frame_rate" in video_info.keys():
video_frame_rate = video_info["r_frame_rate"].partition("/")
video_frame_rate_n = video_frame_rate[0]
video_frame_rate_d = video_frame_rate[2]
video_frame_rate_n = video_frame_rate[0]
video_frame_rate_d = video_frame_rate[2]

interlaced = False
if video_info.get("field_order") in ("tt", "tb", "bt", "bb"):
interlaced = True

ret = {
"filename": input_file,
"file_size": file_size,
"video_duration": video_duration,
"video_duration": video_duration,
"video_frame_rate_n": video_frame_rate_n,
"video_frame_rate_d": video_frame_rate_d,
"video_bitrate": video_bitrate,
Expand All @@ -387,13 +391,13 @@ def media_file_info(input_file):
"video_codec": video_info["codec_name"],
"has_video": has_video,
"has_audio": has_audio,
"color_range": video_info["color_range"],
"color_space": video_info["color_space"],
"color_range": video_info.get("color_range"),
"color_space": video_info.get("color_space"),
"color_transfer": video_info.get("color_space"),
"color_primaries": video_info.get("color_primaries"),
"field_order": video_info["field_order"],
"display_aspect_ratio": video_info["display_aspect_ratio"],
"sample_aspect_ratio": video_info["sample_aspect_ratio"],
"interlaced": interlaced,
"display_aspect_ratio": video_info.get("display_aspect_ratio"),
"sample_aspect_ratio": video_info.get("sample_aspect_ratio"),
}

if has_audio:
Expand Down Expand Up @@ -491,6 +495,7 @@ def get_base_ffmpeg_command(
encoder,
audio_encoder,
target_fps,
interlaced,
target_height,
target_rate,
target_rate_audio,
Expand All @@ -509,6 +514,7 @@ def get_base_ffmpeg_command(
encoder {str} -- video encoder
audio_encoder {str} -- audio encoder
target_fps {fractions.Fraction} -- target FPS
interlaced {bool} -- true if interlaced
target_height {int} -- height
target_rate {int} -- target bitrate in kbps
target_rate_audio {int} -- audio target bitrate
Expand All @@ -519,11 +525,32 @@ def get_base_ffmpeg_command(

# avoid very high frame rates
while target_fps > 60:
target_fps = target_fps/2
target_fps = target_fps / 2

if target_fps < 1:
target_fps = 1

filters = []

if interlaced:
filters.append("yadif")

target_width = round(target_height * 16 / 9)
scale_filter_opts = [
f"if(lt(iw\\,ih)\\,{target_height}\\,{target_width})",
f"if(lt(iw\\,ih)\\,{target_width}\\,{target_height})",
"force_original_aspect_ratio=decrease",
"force_divisible_by=2",
"flags=lanczos",
]
scale_filter_str = "scale=" + ":".join(scale_filter_opts)
filters.append(scale_filter_str)

fps_str = f"fps=fps={target_fps}"
filters.append(fps_str)

filters_str = ",".join(filters)

base_cmd = [
settings.FFMPEG_COMMAND,
"-y",
Expand All @@ -532,9 +559,7 @@ def get_base_ffmpeg_command(
"-c:v",
encoder,
"-filter:v",
"scale=-2:" + str(target_height) + ",fps=fps=" + str(target_fps),
# always convert to 4:2:0 -- FIXME: this could be also 4:2:2
# but compatibility will suffer
filters_str,
"-pix_fmt",
"yuv420p",
]
Expand Down Expand Up @@ -707,7 +732,6 @@ def produce_ffmpeg_commands(media_file, media_info, resolution, codec, output_fi
# target_fps = 25
# else:


if media_info.get("video_duration") > CRF_ENCODING_NUM_SECONDS:
enc_type = "crf"
else:
Expand All @@ -718,6 +742,7 @@ def produce_ffmpeg_commands(media_file, media_info, resolution, codec, output_fi
elif enc_type == "crf":
passes = [2]

interlaced = media_info.get("interlaced")

cmds = []
for pass_number in passes:
Expand All @@ -730,6 +755,7 @@ def produce_ffmpeg_commands(media_file, media_info, resolution, codec, output_fi
encoder=encoder,
audio_encoder=AUDIO_ENCODERS[codec],
target_fps=target_fps,
interlaced=interlaced,
target_height=resolution,
target_rate=target_rate,
target_rate_audio=AUDIO_BITRATES[codec],
Expand Down Expand Up @@ -757,4 +783,4 @@ def clean_query(query):
for char in chars:
query = query.replace(char, "")

return query.lower()
return query.lower()

0 comments on commit 9983785

Please sign in to comment.