* Framerate fix

Keep original framerate up to 60fps, halve any framerate above 60fps. Because of "video_frame_rate": Fraction(video_info["r_frame_rate"]), it does not work, when float used, the video is encoded but framerate suffers from rounding error.

* Framerate fix

Keep original framerate up to 60fps, halve any framerate above 60fps. Because of "video_frame_rate": Fraction(video_info["r_frame_rate"]), it does not work, when float used, the video is encoded but framerate suffers from rounding error.

* Introduction of minimum bitrate modifier

A minimum bitrate modifier introduced as per https://developers.google.com/media/vp9/settings/vod

* Introduction of minimum bitrate modifier

A minimum bitrate modifier introduced as per https://developers.google.com/media/vp9/settings/vod

* Deinterlacing and better filter logic
This commit is contained in:
multiflexi 2021-10-01 16:48:52 +02:00 committed by GitHub
parent 4480fa7de1
commit 28031f07e5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -244,6 +244,7 @@ def media_file_info(input_file):
- `video_bitrate`: Bitrate of the video stream in kBit/s - `video_bitrate`: Bitrate of the video stream in kBit/s
- `video_width`: Width in pixels - `video_width`: Width in pixels
- `video_height`: Height in pixels - `video_height`: Height in pixels
- `interlaced` : True if the video is interlaced
- `video_codec`: Video codec - `video_codec`: Video codec
- `audio_duration`: Duration of the audio in `s.msec` - `audio_duration`: Duration of the audio in `s.msec`
- `audio_sample_rate`: Audio sample rate in Hz - `audio_sample_rate`: Audio sample rate in Hz
@ -374,6 +375,10 @@ def media_file_info(input_file):
video_frame_rate_n = video_frame_rate[0] video_frame_rate_n = video_frame_rate[0]
video_frame_rate_d = video_frame_rate[2] video_frame_rate_d = video_frame_rate[2]
interlaced = False
if video_info.get("field_order") in ("tt", "tb", "bt", "bb"):
interlaced = True
ret = { ret = {
"filename": input_file, "filename": input_file,
"file_size": file_size, "file_size": file_size,
@ -390,7 +395,7 @@ def media_file_info(input_file):
"color_space": video_info.get("color_space"), "color_space": video_info.get("color_space"),
"color_transfer": video_info.get("color_space"), "color_transfer": video_info.get("color_space"),
"color_primaries": video_info.get("color_primaries"), "color_primaries": video_info.get("color_primaries"),
"field_order": video_info.get("field_order"), "interlaced": interlaced,
"display_aspect_ratio": video_info.get("display_aspect_ratio"), "display_aspect_ratio": video_info.get("display_aspect_ratio"),
"sample_aspect_ratio": video_info.get("sample_aspect_ratio"), "sample_aspect_ratio": video_info.get("sample_aspect_ratio"),
} }
@ -490,6 +495,7 @@ def get_base_ffmpeg_command(
encoder, encoder,
audio_encoder, audio_encoder,
target_fps, target_fps,
interlaced,
target_height, target_height,
target_rate, target_rate,
target_rate_audio, target_rate_audio,
@ -508,6 +514,7 @@ def get_base_ffmpeg_command(
encoder {str} -- video encoder encoder {str} -- video encoder
audio_encoder {str} -- audio encoder audio_encoder {str} -- audio encoder
target_fps {fractions.Fraction} -- target FPS target_fps {fractions.Fraction} -- target FPS
interlaced {bool} -- true if interlaced
target_height {int} -- height target_height {int} -- height
target_rate {int} -- target bitrate in kbps target_rate {int} -- target bitrate in kbps
target_rate_audio {int} -- audio target bitrate target_rate_audio {int} -- audio target bitrate
@ -523,6 +530,27 @@ def get_base_ffmpeg_command(
if target_fps < 1: if target_fps < 1:
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 = [ base_cmd = [
settings.FFMPEG_COMMAND, settings.FFMPEG_COMMAND,
"-y", "-y",
@ -531,9 +559,7 @@ def get_base_ffmpeg_command(
"-c:v", "-c:v",
encoder, encoder,
"-filter:v", "-filter:v",
"scale=-2:" + str(target_height) + ",fps=fps=" + str(target_fps), filters_str,
# always convert to 4:2:0 -- FIXME: this could be also 4:2:2
# but compatibility will suffer
"-pix_fmt", "-pix_fmt",
"yuv420p", "yuv420p",
] ]
@ -716,6 +742,8 @@ def produce_ffmpeg_commands(media_file, media_info, resolution, codec, output_fi
elif enc_type == "crf": elif enc_type == "crf":
passes = [2] passes = [2]
interlaced = media_info.get("interlaced")
cmds = [] cmds = []
for pass_number in passes: for pass_number in passes:
cmds.append( cmds.append(
@ -727,6 +755,7 @@ def produce_ffmpeg_commands(media_file, media_info, resolution, codec, output_fi
encoder=encoder, encoder=encoder,
audio_encoder=AUDIO_ENCODERS[codec], audio_encoder=AUDIO_ENCODERS[codec],
target_fps=target_fps, target_fps=target_fps,
interlaced=interlaced,
target_height=resolution, target_height=resolution,
target_rate=target_rate, target_rate=target_rate,
target_rate_audio=AUDIO_BITRATES[codec], target_rate_audio=AUDIO_BITRATES[codec],