//  [python]
def random_crop_resize(frames: tf.Tensor,
                       output_height: int,
                       output_width: int,
                       num_frames: int,
                       num_channels: int,
                       aspect_ratio: Tuple[float, float],
                       area_range: Tuple[float, float],
                       state: MutableMapping[str, tf.Tensor]) -> tf.Tensor:
  """First crops clip with jittering and then resizes.

  Args:
    frames: A Tensor of dimension [timesteps, input_h, input_w, channels].
    output_height: Resized image height.
    output_width: Resized image width.
    num_frames: Number of input frames per clip.
    num_channels: Number of channels of the clip.
    aspect_ratio: Float tuple with the aspect range for cropping.
    area_range: Float tuple with the area range for cropping.
    state: A mutable dictionary passed to the stateful functions and might be
      modified in order to keep metadata.
  Returns:
    A Tensor of shape [timesteps, output_height, output_width, channels] of type
      frames.dtype.
  """
  shape = tf.shape(frames)
  image_size = tf.cast(shape[1:3], tf.float32)
  seq_len, _, _, channels = shape[0], shape[1], shape[2], shape[3]
  bbox = tf.constant([0.0, 0.0, 1.0, 1.0], dtype=tf.float32, shape=[1, 1, 4])
  factor = output_width / output_height
  aspect_ratio = (aspect_ratio[0] * factor, aspect_ratio[1] * factor)
  sample_distorted_bbox = tf.image.sample_distorted_bounding_box(
      shape[1:],
      bounding_boxes=bbox,
      min_object_covered=0.1,
      aspect_ratio_range=aspect_ratio,
      area_range=area_range,
      max_attempts=100,
      use_image_if_no_bounding_boxes=True)
  bbox_begin, bbox_size, _ = sample_distorted_bbox
  offset_y, offset_x, _ = tf.unstack(bbox_begin)
  target_height, target_width, _ = tf.unstack(bbox_size)
  size = tf.convert_to_tensor((
      seq_len, target_height, target_width, channels))
  offset = tf.convert_to_tensor((0, offset_y, offset_x, 0))
  frames = tf.slice(frames, offset, size)
  frames = tf.cast(
      tf.image.resize(frames, (output_height, output_width)),
      frames.dtype)
  frames.set_shape((num_frames, output_height, output_width, num_channels))
  image_scale = (
      tf.convert_to_tensor((output_height, output_width), tf.float32) /
      tf.cast(bbox_size[:2], tf.float32))

  # Note: image_info encodes the information of the image and the applied
  # preprocessing. It is in the format of
  # [[original_height, original_width], [desired_height, desired_width],
  #  [y_scale, x_scale], [y_offset, x_offset]],
  # where [desired_height, desired_width] is the actual scaled image size,
  # and [y_scale, x_scale] is the scaling factor, which is the ratio of scaled
  # dimension / original dimension. [y_offset, x_offset] is the upper-left
  # coordinates to perform image cropping.
  offset = tf.convert_to_tensor((offset_y, offset_x), tf.float32)
  offset *= image_scale
  image_info = tf.stack([
      image_size,
      tf.convert_to_tensor((output_height, output_width), tf.float32),
      image_scale,
      offset])
  if 'image_info' not in state:
    state['image_info'] = image_info
  else:
    update_image_info(state, image_info)
  return frames