@@ -661,6 +661,67 @@ TEST_CASE( "GetMaxFrame and GetMaxTime", "[libopenshot][timeline]" )
661
661
CHECK (t.GetMaxTime () == Approx (20.0 ).margin (0.001 ));
662
662
}
663
663
664
+ TEST_CASE ( " GetMinFrame and GetMinTime" , " [libopenshot][timeline]" )
665
+ {
666
+ // Create a timeline
667
+ Timeline t (640 , 480 , Fraction (30 , 1 ), 44100 , 2 , LAYOUT_STEREO);
668
+
669
+ std::stringstream path1;
670
+ path1 << TEST_MEDIA_PATH << " interlaced.png" ;
671
+ Clip clip1 (path1.str ());
672
+ clip1.Id (" C1" );
673
+ clip1.Layer (1 );
674
+ clip1.Position (50 ); // Start at 50 seconds
675
+ clip1.End (45 ); // Ends at 95 seconds
676
+ t.AddClip (&clip1);
677
+
678
+ CHECK (t.GetMinTime () == Approx (50.0 ).margin (0.001 ));
679
+ CHECK (t.GetMinFrame () == 50 * 30 );
680
+
681
+ Clip clip2 (path1.str ());
682
+ clip2.Id (" C2" );
683
+ clip2.Layer (2 );
684
+ clip2.Position (0 ); // Start at 0 seconds
685
+ clip2.End (55 ); // Ends at 55 seconds
686
+ t.AddClip (&clip2);
687
+
688
+ CHECK (t.GetMinTime () == Approx (0.0 ).margin (0.001 ));
689
+ CHECK (t.GetMinFrame () == 0 );
690
+
691
+ clip1.Position (80 ); // Move clip1 to start at 80 seconds
692
+ clip2.Position (100 ); // Move clip2 to start at 100 seconds
693
+ CHECK (t.GetMinTime () == Approx (80.0 ).margin (0.001 ));
694
+ CHECK (t.GetMinFrame () == 80 * 30 );
695
+
696
+ clip2.Position (20 ); // Adjust clip2 to start at 20 seconds
697
+ CHECK (t.GetMinTime () == Approx (20.0 ).margin (0.001 ));
698
+ CHECK (t.GetMinFrame () == 20 * 30 );
699
+
700
+ clip2.End (35 ); // Adjust clip2 to end at 35 seconds
701
+ CHECK (t.GetMinTime () == Approx (20.0 ).margin (0.001 ));
702
+ CHECK (t.GetMinFrame () == 20 * 30 );
703
+
704
+ t.RemoveClip (&clip1);
705
+ CHECK (t.GetMinTime () == Approx (20.0 ).margin (0.001 ));
706
+ CHECK (t.GetMinFrame () == 20 * 30 );
707
+
708
+ // Update Clip's basic properties with JSON Diff
709
+ std::stringstream json_change1;
710
+ json_change1 << " [{\" type\" :\" update\" ,\" key\" :[\" clips\" ,{\" id\" :\" C2\" }],\" value\" :{\" id\" :\" C2\" ,\" layer\" :4000000,\" position\" :5.0,\" start\" :0,\" end\" :10},\" partial\" :false}]" ;
711
+ t.ApplyJsonDiff (json_change1.str ());
712
+
713
+ CHECK (t.GetMinTime () == Approx (5.0 ).margin (0.001 ));
714
+ CHECK (t.GetMinFrame () == 5 * 30 );
715
+
716
+ // Insert NEW Clip with JSON Diff
717
+ std::stringstream json_change2;
718
+ json_change2 << " [{\" type\" :\" insert\" ,\" key\" :[\" clips\" ],\" value\" :{\" id\" :\" C3\" ,\" layer\" :4000000,\" position\" :10.0,\" start\" :0,\" end\" :10,\" reader\" :{\" acodec\" :\"\" ,\" audio_bit_rate\" :0,\" audio_stream_index\" :-1,\" audio_timebase\" :{\" den\" :1,\" num\" :1},\" channel_layout\" :4,\" channels\" :0,\" display_ratio\" :{\" den\" :1,\" num\" :1},\" duration\" :3600.0,\" file_size\" :\" 160000\" ,\" fps\" :{\" den\" :1,\" num\" :30},\" has_audio\" :false,\" has_single_image\" :true,\" has_video\" :true,\" height\" :200,\" interlaced_frame\" :false,\" metadata\" :{},\" path\" :\" " << path1.str () << " \" ,\" pixel_format\" :-1,\" pixel_ratio\" :{\" den\" :1,\" num\" :1},\" sample_rate\" :0,\" top_field_first\" :true,\" type\" :\" QtImageReader\" ,\" vcodec\" :\"\" ,\" video_bit_rate\" :0,\" video_length\" :\" 108000\" ,\" video_stream_index\" :-1,\" video_timebase\" :{\" den\" :30,\" num\" :1},\" width\" :200}},\" partial\" :false}]" ;
719
+ t.ApplyJsonDiff (json_change2.str ());
720
+
721
+ CHECK (t.GetMinTime () == Approx (5.0 ).margin (0.001 ));
722
+ CHECK (t.GetMinFrame () == 5 * 30 );
723
+ }
724
+
664
725
TEST_CASE ( " Multi-threaded Timeline GetFrame" , " [libopenshot][timeline]" )
665
726
{
666
727
Timeline *t = new Timeline (1280 , 720 , Fraction (24 , 1 ), 48000 , 2 , LAYOUT_STEREO);
0 commit comments