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;
}