Skip to content
This repository has been archived by the owner on Sep 20, 2024. It is now read-only.

Commit

Permalink
Bug: Fix aspect ratio on all review
Browse files Browse the repository at this point in the history
  • Loading branch information
Cyprien CAILLOT committed Sep 11, 2024
1 parent d9731d0 commit 57130b9
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 62 deletions.
2 changes: 2 additions & 0 deletions openpype/lib/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@
convert_input_paths_for_ffmpeg,
get_ffprobe_data,
get_ffprobe_streams,
get_video_metadata,
get_ffmpeg_codec_args,
get_ffmpeg_format_args,
convert_ffprobe_fps_value,
Expand Down Expand Up @@ -229,6 +230,7 @@
"convert_input_paths_for_ffmpeg",
"get_ffprobe_data",
"get_ffprobe_streams",
"get_video_metadata",
"get_ffmpeg_codec_args",
"get_ffmpeg_format_args",
"convert_ffprobe_fps_value",
Expand Down
52 changes: 51 additions & 1 deletion openpype/lib/transcoding.py
Original file line number Diff line number Diff line change
Expand Up @@ -834,6 +834,55 @@ def get_ffprobe_streams(path_to_file, logger=None):
return get_ffprobe_data(path_to_file, logger)["streams"]


def get_video_metadata(streams, log=None):
input_timecode = ""
input_width = None
input_height = None
input_frame_rate = None
input_pixel_aspect = None
for stream in streams:
if stream.get("codec_type") != "video":
continue
if log:
log.debug("FFprobe Video: {}".format(stream))

if "width" not in stream or "height" not in stream:
continue
width = int(stream["width"])
height = int(stream["height"])
if not width or not height:
continue

# Make sure that width and height are captured even if frame rate
# is not available
input_width = width
input_height = height

input_pixel_aspect = stream.get("sample_aspect_ratio")
if input_pixel_aspect is not None:
try:
input_pixel_aspect = float(
eval(str(input_pixel_aspect).replace(':', '/')))
except Exception:
if log:
log.debug("__Converting pixel aspect to float failed: {}".format(
input_pixel_aspect))

tags = stream.get("tags") or {}
input_timecode = tags.get("timecode") or ""

input_frame_rate = stream.get("r_frame_rate")
if input_frame_rate is not None:
break
return (
input_width,
input_height,
input_timecode,
input_frame_rate,
input_pixel_aspect
)


def get_ffmpeg_format_args(ffprobe_data, source_ffmpeg_cmd=None):
"""Copy format from input metadata for output.
Expand Down Expand Up @@ -1048,9 +1097,10 @@ def convert_ffprobe_fps_value(str_value):
items = str_value.split("/")
if len(items) == 1:
fps = float(items[0])

elif len(items) == 2:
fps = float(items[0]) / float(items[1])
else:
return "Unknown"

# Check if fps is integer or float number
if int(fps) == fps:
Expand Down
28 changes: 18 additions & 10 deletions openpype/plugins/publish/extract_review.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
from openpype.lib.transcoding import (
IMAGE_EXTENSIONS,
get_ffprobe_streams,
get_video_metadata,
should_convert_for_ffmpeg,
get_review_layer_name,
convert_input_paths_for_ffmpeg,
Expand Down Expand Up @@ -1223,7 +1224,7 @@ def get_letterbox_filters(
return output

def rescaling_filters(self, temp_data, output_def, new_repre):
"""Prepare vieo filters based on tags in new representation.
"""Prepare video filters based on tags in new representation.
It is possible to add letterboxes to output video or rescale to
different resolution.
Expand Down Expand Up @@ -1262,18 +1263,25 @@ def rescaling_filters(self, temp_data, output_def, new_repre):
# Try to find first stream with defined 'width' and 'height'
# - this is to avoid order of streams where audio can be as first
# - there may be a better way (checking `codec_type`?)
input_width = None
input_height = None

# Get video metadata
(
input_width,
input_height,
input_timecode,
input_frame_rate,
input_pixel_aspect
) = get_video_metadata(streams, self.log)

output_width = None
output_height = None
for stream in streams:
if "width" in stream and "height" in stream:
input_width = int(stream["width"])
input_height = int(stream["height"])
break

# Get instance data
pixel_aspect = temp_data["pixel_aspect"]
if input_pixel_aspect:
# Use in priority the aspect ratio retrieved from video metadata
pixel_aspect = input_pixel_aspect

if reformat_in_baking:
self.log.debug((
"Using resolution from input. It is already "
Expand All @@ -1283,13 +1291,13 @@ def rescaling_filters(self, temp_data, output_def, new_repre):
output_width = input_width
output_height = input_height

# Raise exception of any stream didn't define input resolution
# Raise an exception if a stream didn't define input resolution
if input_width is None:
raise AssertionError((
"FFprobe couldn't read resolution from input file: \"{}\""
).format(full_input_path_single_file))

# NOTE Setting only one of `width` or `heigth` is not allowed
# NOTE Setting only one of `width` or `height` is not allowed
# - settings value can't have None but has value of 0
output_width = output_def.get("width") or output_width or None
output_height = output_def.get("height") or output_height or None
Expand Down
56 changes: 5 additions & 51 deletions openpype/plugins/publish/extract_review_slate.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
get_ffmpeg_tool_args,
get_ffprobe_data,
get_ffprobe_streams,
get_video_metadata,
get_ffmpeg_codec_args,
get_ffmpeg_format_args,
)
Expand Down Expand Up @@ -88,11 +89,11 @@ def process(self, instance):
input_timecode,
input_frame_rate,
input_pixel_aspect
) = self._get_video_metadata(streams)
) = get_video_metadata(streams, self.log)
if input_pixel_aspect:
pixel_aspect = input_pixel_aspect

# Raise exception of any stream didn't define input resolution
# Raise an exception if a stream didn't define input resolution
if input_width is None:
raise KnownPublishError(
"FFprobe couldn't read resolution from input file: \"{}\""
Expand Down Expand Up @@ -423,60 +424,13 @@ def _get_slates_resolution(self, slate_path):
slate_height = int(slate_stream["height"])
break

# Raise exception of any stream didn't define input resolution
# Raise an exception if a stream didn't define input resolution
if slate_width is None:
raise AssertionError((
"FFprobe couldn't read resolution from input file: \"{}\""
).format(slate_path))

return (slate_width, slate_height)

def _get_video_metadata(self, streams):
input_timecode = ""
input_width = None
input_height = None
input_frame_rate = None
input_pixel_aspect = None
for stream in streams:
if stream.get("codec_type") != "video":
continue
self.log.debug("FFprobe Video: {}".format(stream))

if "width" not in stream or "height" not in stream:
continue
width = int(stream["width"])
height = int(stream["height"])
if not width or not height:
continue

# Make sure that width and height are captured even if frame rate
# is not available
input_width = width
input_height = height

input_pixel_aspect = stream.get("sample_aspect_ratio")
if input_pixel_aspect is not None:
try:
input_pixel_aspect = float(
eval(str(input_pixel_aspect).replace(':', '/')))
except Exception:
self.log.debug(
"__Converting pixel aspect to float failed: {}".format(
input_pixel_aspect))

tags = stream.get("tags") or {}
input_timecode = tags.get("timecode") or ""

input_frame_rate = stream.get("r_frame_rate")
if input_frame_rate is not None:
break
return (
input_width,
input_height,
input_timecode,
input_frame_rate,
input_pixel_aspect
)
return slate_width, slate_height

def _get_audio_metadata(self, streams):
# Get audio metadata
Expand Down

0 comments on commit 57130b9

Please sign in to comment.