void parse_video_resolution()

in vireo/internal/demux/mp4.cpp [140:204]


  void parse_video_resolution(lsmash_track_parameters_t& track_param) {
    const SampleType type = SampleType::Video;

    // width / height
    lsmash_video_summary_t* video_summary = (lsmash_video_summary_t*)tracks(type).summary.get();
    video.width = video_summary->width;
    video.height = video_summary->height;
    THROW_IF(!security::valid_dimensions(video.width, video.height), Unsafe);

    // orientation + pixel aspect ratio
    auto get_transform_info = [](array<int32_t, 9> matrix) -> transform_info {
      THROW_IF(matrix[2] != 0x0, Unsupported);
      THROW_IF(matrix[5] != 0x0, Unsupported);
      THROW_IF(matrix[8] != 0x40000000, Unsupported);
      transform_info info;
      auto atan2_in_degree = [](int32_t y, int32_t x) -> int32_t {
        return (int32_t)(atan2((double)y, (double)x) * 180 / M_PI);
      };

      int32_t degree = atan2_in_degree(matrix[1], matrix[0]);
      if (degree % 90 == 0) {
        const int32_t multiplier = 0x10000;
        int32_t degree_check = numeric_limits<int32_t>::min();  // initialize to an invalid degree
        if (matrix[1] == 0x0 && matrix[3] == 0x0) {
          // Landscape / LandscapeReverse
          THROW_IF((matrix[0] == 0) || (matrix[0] % multiplier), Invalid);
          THROW_IF((matrix[4] == 0) || (matrix[4] % multiplier), Invalid);
          info.par.x = abs(matrix[0]) / multiplier;
          info.par.y = abs(matrix[4]) / multiplier;
          degree_check = atan2_in_degree(0, matrix[4]);  // matrix[0] & matrix[4] must have same signs
        } else if (matrix[0] == 0x0 && matrix[4] == 0x0) {
          // Portrait / PortraitReverse
          THROW_IF((matrix[1] == 0) || (matrix[1] % multiplier), Invalid);
          THROW_IF((matrix[3] == 0) || (matrix[3] % multiplier), Invalid);
          info.par.x = abs(matrix[1]) / multiplier;
          info.par.y = abs(matrix[3]) / multiplier;
          degree_check = atan2_in_degree(-matrix[3], 0);  // matrix[1] & matrix[3] must have opposite signs
        }
        THROW_IF(degree != degree_check, Invalid);
        while (degree < 0) {
          degree += 360;
        }
        info.orientation = (settings::Video::Orientation)round(degree / 90);
      }
      return info;
    };

    transform_info info = get_transform_info({
      track_param.matrix[0], track_param.matrix[1], track_param.matrix[2],
      track_param.matrix[3], track_param.matrix[4], track_param.matrix[5],
      track_param.matrix[6], track_param.matrix[7], track_param.matrix[8],
    });
    pixel_aspect_ratio par = info.par;
    if (video.sps_pps.get()) {
      pixel_aspect_ratio par_from_sps;
      if (parse_pixel_aspect_ratio(video.sps_pps->sps, par_from_sps)) {
        par = par_from_sps;
      }
    }
    video.par_width = (uint16_t)par.x;
    video.par_height = (uint16_t)par.y;

    THROW_IF(info.orientation == settings::Video::Orientation::UnknownOrientation, Unsupported);
    video.orientation = info.orientation;
  }