Fix rotation detection for HDR videos (#50854)

Fixes https://github.com/rails/rails/issues/50853

The video analyzer was relying on the positional reference of the Display
Matrix side_data to fetch the rotation value. However, the side_data is
not guaranteed to be in the same position. For instance, HDR videos shot
on iOS have "DOVI configuration record" side_data in the first position,
followed by the "Display Matrix" side data containing the rotation value.

This fix removes the positional reference and explicitely searches for
the "Display Matrix" side_data to retrieve the rotation angle.
This commit is contained in:
Anup Narkhede 2024-01-23 19:28:11 +00:00 committed by GitHub
parent ee88f4133f
commit 776626ff98
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 15 additions and 2 deletions

View File

@ -55,11 +55,15 @@ module ActiveStorage
def angle
if tags["rotate"]
Integer(tags["rotate"])
elsif side_data && side_data[0] && side_data[0]["rotation"]
Integer(side_data[0]["rotation"])
elsif display_matrix && display_matrix["rotation"]
Integer(display_matrix["rotation"])
end
end
def display_matrix
side_data.detect { |data| data["side_data_type"] == "Display Matrix" }
end
def display_aspect_ratio
if descriptor = video_stream["display_aspect_ratio"]
if terms = descriptor.split(":", 2)

View File

@ -29,6 +29,15 @@ class ActiveStorage::Analyzer::VideoAnalyzerTest < ActiveSupport::TestCase
assert_includes [90, -90], metadata[:angle]
end
test "analyzing a rotated HDR video" do
blob = create_file_blob(filename: "rotated_hdr_video.mov", content_type: "video/quicktime")
metadata = extract_metadata_from(blob)
assert_equal 1080.0, metadata[:width]
assert_equal 1920.0, metadata[:height]
assert_equal(-90, metadata[:angle])
end
test "analyzing a video with rectangular samples" do
blob = create_file_blob(filename: "video_with_rectangular_samples.mp4", content_type: "video/mp4")
metadata = extract_metadata_from(blob)

Binary file not shown.