diff --git a/src/Clip.cpp b/src/Clip.cpp index d8b61b3a..b63fdba7 100644 --- a/src/Clip.cpp +++ b/src/Clip.cpp @@ -111,24 +111,39 @@ void Clip::init_reader_settings() { } } -// Init reader's rotation (if any) void Clip::init_reader_rotation() { - // Dont init rotation if clip has keyframes + // Don't init rotation if clip already has keyframes. if (rotation.GetCount() > 0) return; - // Init rotation + // Get rotation from metadata (if any) + float rotate_angle = 0.0f; if (reader && reader->info.metadata.count("rotate") > 0) { - // Use reader metadata rotation (if any) - // This is typical with cell phone videos filmed in different orientations try { - float rotate_metadata = strtof(reader->info.metadata["rotate"].c_str(), 0); - rotation = Keyframe(rotate_metadata); - } catch (const std::exception& e) {} + rotate_angle = strtof(reader->info.metadata["rotate"].c_str(), nullptr); + } catch (const std::exception& e) { + // Leave rotate_angle at default 0.0f + } } - else - // Default no rotation - rotation = Keyframe(0.0); + rotation = Keyframe(rotate_angle); + + // Compute uniform scale factors for rotated video. + // Assume reader->info.width and reader->info.height are the clip's natural dimensions. + float w = static_cast(reader->info.width); + float h = static_cast(reader->info.height); + float rad = rotate_angle * M_PI / 180.0f; + + // Calculate the dimensions of the bounding box for the rotated clip. + float new_width = fabs(w * cos(rad)) + fabs(h * sin(rad)); + float new_height = fabs(w * sin(rad)) + fabs(h * cos(rad)); + + // To have the rotated clip appear the same size as the unrotated clip, + // compute a uniform scale factor S that brings the bounding box back to (w, h). + float uniform_scale = std::min(w / new_width, h / new_height); + + // Set scale keyframes uniformly. + scale_x = Keyframe(uniform_scale); + scale_y = Keyframe(uniform_scale); } // Default Constructor for a clip