bool ReadClipFromVideoLazzy()

in caffe2_customized_ops/video/customized_video_io.cc [154:238]


bool ReadClipFromVideoLazzy(
    std::string filename,
    const int start_frm,
    const int length,
    const int height,
    const int width,
    const int sampling_rate,
    float*& buffer) {
  cv::VideoCapture cap;
  cv::Mat img, img_origin;
  buffer = nullptr;
  int offset = 0;
  int channel_size = 0;
  int image_size = 0;
  int data_size = 0;
  int end_frm = 0;

  cap.open(filename);
  if (!cap.isOpened()) {
    LOG(ERROR) << "Cannot open " << filename;
    return false;
  }

  int num_of_frames = cap.get(CV_CAP_PROP_FRAME_COUNT);
  if (num_of_frames < length * sampling_rate) {
    LOG(INFO) << filename << " does not have enough frames; having "
              << num_of_frames;
    return false;
  }

  CAFFE_ENFORCE_GE(start_frm, 0, "start frame must be greater or equal to 0");

  if (start_frm) {
    cap.set(CV_CAP_PROP_POS_FRAMES, start_frm);
  }
  end_frm = start_frm + length * sampling_rate;
  CAFFE_ENFORCE_LE(
      end_frm,
      num_of_frames,
      "end frame must be less or equal to num of frames");

  for (int i = start_frm; i < end_frm; i += sampling_rate) {
    if (sampling_rate > 1) {
      cap.set(CV_CAP_PROP_POS_FRAMES, i);
    }
    if (height > 0 && width > 0) {
      cap.read(img_origin);
      if (!img_origin.data) {
        LOG(INFO) << filename << " has no data at frame " << i;
        if (buffer != nullptr) {
          delete[] buffer;
        }
        return false;
      }
      cv::resize(img_origin, img, cv::Size(width, height));
    } else {
      cap.read(img);
      if (!img.data) {
        LOG(ERROR) << "Could not open or find file " << filename;
        if (buffer != nullptr) {
          delete[] buffer;
        }
        return false;
      }
    }

    // If this is the fisrt frame, allocate memory for the buffer
    if (i == start_frm) {
      image_size = img.rows * img.cols;
      channel_size = image_size * length;
      data_size = channel_size * 3;
      buffer = new float[data_size];
    }

    for (int c = 0; c < 3; c++) {
      ImageChannelToBuffer(&img, buffer + c * channel_size + offset, c);
    }

    offset += image_size;
  }

  CAFFE_ENFORCE(offset == channel_size, "wrong offset size");
  cap.release();
  return true;
}