@@ -172,11 +172,15 @@ def test_random_crop_torchvision(
172172
173173 # We want both kinds of RandomCrop objects to get arrive at the same
174174 # locations to crop, so we need to make sure they get the same random
175- # seed.
175+ # seed. It's used in RandomCrop's _make_transform_spec() method, called
176+ # by the VideoDecoder.
176177 torch .manual_seed (seed )
177178 tc_random_crop = torchcodec .transforms .RandomCrop (size = (height , width ))
178179 decoder_random_crop = VideoDecoder (video .path , transforms = [tc_random_crop ])
179180
181+ # Resetting manual seed for when TorchCodec's RandomCrop, created from
182+ # the TorchVision RandomCrop, is used inside of the VideoDecoder. It
183+ # needs to match the call above.
180184 torch .manual_seed (seed )
181185 decoder_random_crop_tv = VideoDecoder (
182186 video .path ,
@@ -202,14 +206,11 @@ def test_random_crop_torchvision(
202206 expected_shape = (video .get_num_color_channels (), height , width )
203207 assert frame_random_crop_tv .shape == expected_shape
204208
209+ # Resetting manual seed to make sure the invocation of the
210+ # TorchVision RandomCrop matches the two calls above.
211+ torch .manual_seed (seed )
205212 frame_full = decoder_full [frame_index ]
206- frame_tv = v2 .functional .crop (
207- frame_full ,
208- top = tc_random_crop ._top ,
209- left = tc_random_crop ._left ,
210- height = tc_random_crop .size [0 ],
211- width = tc_random_crop .size [1 ],
212- )
213+ frame_tv = v2 .RandomCrop (size = (height , width ))(frame_full )
213214 assert_frames_equal (frame_random_crop , frame_tv )
214215
215216 @pytest .mark .parametrize (
@@ -266,6 +267,56 @@ def test_crop_fails(self, error_message, params):
266267 transforms = [v2 .RandomCrop (** params )],
267268 )
268269
270+ @pytest .mark .parametrize ("seed" , [0 , 314 ])
271+ def test_random_crop_reusable_objects (self , seed ):
272+ torch .manual_seed (seed )
273+ random_crop = torchcodec .transforms .RandomCrop (size = (99 , 99 ))
274+
275+ # Create a spec which causes us to calculate the random crop location.
276+ first_spec = random_crop ._make_transform_spec ((888 , 888 ))
277+
278+ # Create a spec again, which should calculate a different random crop
279+ # location. Despite having the same image size, the specs should be
280+ # different because the crop should be at a different location
281+ second_spec = random_crop ._make_transform_spec ((888 , 888 ))
282+ assert first_spec != second_spec
283+
284+ # Create a spec again, but with a different image size. The specs should
285+ # obviously be different, but the original image size should not be in
286+ # the spec at all.
287+ third_spec = random_crop ._make_transform_spec ((777 , 777 ))
288+ assert third_spec != first_spec
289+ assert "888" not in third_spec
290+
291+ @pytest .mark .parametrize (
292+ "resize, random_crop" ,
293+ [
294+ (torchcodec .transforms .Resize , torchcodec .transforms .RandomCrop ),
295+ (v2 .Resize , v2 .RandomCrop ),
296+ ],
297+ )
298+ def test_transform_pipeline (self , resize , random_crop ):
299+ decoder = VideoDecoder (
300+ TEST_SRC_2_720P .path ,
301+ transforms = [
302+ # resized to bigger than original
303+ resize (size = (2160 , 3840 )),
304+ # crop to smaller than the resize, but still bigger than original
305+ random_crop (size = (1080 , 1920 )),
306+ ],
307+ )
308+
309+ num_frames = len (decoder )
310+ for frame_index in [
311+ 0 ,
312+ int (num_frames * 0.25 ),
313+ int (num_frames * 0.5 ),
314+ int (num_frames * 0.75 ),
315+ num_frames - 1 ,
316+ ]:
317+ frame = decoder [frame_index ]
318+ assert frame .shape == (TEST_SRC_2_720P .get_num_color_channels (), 1080 , 1920 )
319+
269320 def test_transform_fails (self ):
270321 with pytest .raises (
271322 ValueError ,
@@ -528,14 +579,14 @@ def test_crop_transform_fails(self):
528579
529580 with pytest .raises (
530581 RuntimeError ,
531- match = "x position out of bounds" ,
582+ match = "x start position, 9999, out of bounds" ,
532583 ):
533584 decoder = create_from_file (str (NASA_VIDEO .path ))
534585 add_video_stream (decoder , transform_specs = "crop, 100, 100, 9999, 100" )
535586
536587 with pytest .raises (
537588 RuntimeError ,
538- match = "y position out of bounds " ,
589+ match = r"Crop output height \(999\) is greater than input height \(270\) " ,
539590 ):
540591 decoder = create_from_file (str (NASA_VIDEO .path ))
541592 add_video_stream (decoder , transform_specs = "crop, 999, 100, 100, 100" )
0 commit comments