63 #define DEFAULT_HEATMAP_W 32 
   64 #define DEFAULT_HEATMAP_H 16 
   66 #define M_PI_F ((float)M_PI) 
   67 #define M_PI_2_F ((float)M_PI_2) 
   68 #define M_PI_4_F ((float)M_PI_4) 
   69 #define M_SQRT2_F ((float)M_SQRT2) 
   71 #define DEFAULT_EXPANSION_COEF 1.01f 
   73 #define BARREL_THETA_RANGE (DEFAULT_EXPANSION_COEF *  2.0f * M_PI_F) 
   74 #define BARREL_PHI_RANGE   (DEFAULT_EXPANSION_COEF *  M_PI_2_F) 
   77 #define FIXED_POINT_PRECISION 16 
   80 #define SSIM360_HIST_SIZE 131072 
   84     1.0, 0.9, 0.8, 0.7, 0.6,
 
   85     0.5, 0.4, 0.3, 0.2, 0.1, 0, -1
 
  195         uint8_t *
main, 
int main_stride,
 
  196         uint8_t *
ref, 
int ref_stride,
 
  201 #define OFFSET(x) offsetof(SSIM360Context, x) 
  202 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM 
  205     { 
"stats_file", 
"Set file where to store per-frame difference information",
 
  207     { 
"f",          
"Set file where to store per-frame difference information",
 
  211       "Specifies if non-luma channels must be computed",
 
  213       0, 1, .flags = 
FLAGS },
 
  215     { 
"frame_skip_ratio",
 
  216       "Specifies the number of frames to be skipped from evaluation, for every evaluated frame",
 
  218       0, 1000000, .flags = 
FLAGS },
 
  220     { 
"ref_projection", 
"projection of the reference video",
 
  231     { 
"main_projection", 
"projection of the main video",
 
  235     { 
"ref_stereo", 
"stereo format of the reference video",
 
  243     { 
"main_stereo", 
"stereo format of main video",
 
  248       "Expansion (padding) coefficient for each cube face of the reference video",
 
  252       "Expansion (padding) coeffiecient for each cube face of the main video",
 
  256       "Specifies if the tape based SSIM 360 algorithm must be used independent of the input video types",
 
  258       0, 1, .flags = 
FLAGS },
 
  261       "Heatmap data for view-based evaluation. For heatmap file format, please refer to EntSphericalVideoHeatmapData.",
 
  264     { 
"default_heatmap_width",
 
  265       "Default heatmap dimension. Will be used when dimension is not specified in heatmap data.",
 
  268     { 
"default_heatmap_height",
 
  269       "Default heatmap dimension. Will be used when dimension is not specified in heatmap data.",
 
  342                     const uint8_t *ref8,  ptrdiff_t ref_stride,
 
  343                     int64_t (*sums)[4], 
int width)
 
  345     const uint16_t *main16 = (
const uint16_t *)main8;
 
  346     const uint16_t *ref16  = (
const uint16_t *)ref8;
 
  351     for (
int z = 0; z < 
width; z++) {
 
  352         uint64_t 
s1 = 0, 
s2 = 0, 
ss = 0, s12 = 0;
 
  354         for (
int y = 0; y < 4; y++) {
 
  355             for (
int x = 0; x < 4; x++) {
 
  356                 unsigned a = main16[x + y * main_stride];
 
  357                 unsigned b = ref16[x + y * ref_stride];
 
  378                    const uint8_t *
ref,  ptrdiff_t ref_stride,
 
  379                    int (*sums)[4], 
int width)
 
  381     for (
int z = 0; z < 
width; z++) {
 
  382         uint32_t 
s1 = 0, 
s2 = 0, 
ss = 0, s12 = 0;
 
  384         for (
int y = 0; y < 4; y++) {
 
  385             for (
int x = 0; x < 4; x++) {
 
  386                 int a = 
main[x + y * main_stride];
 
  387                 int b = 
ref[x + y * ref_stride];
 
  408     int64_t ssim_c1 = (int64_t)(.01 * .01 * 
max * 
max * 64      + .5);
 
  409     int64_t ssim_c2 = (int64_t)(.03 * .03 * 
max * 
max * 64 * 63 + .5);
 
  415     int64_t 
vars = fss * 64 - fs1 * fs1 - fs2 * fs2;
 
  416     int64_t covar = fs12 * 64 - fs1 * fs2;
 
  418     return (
float)(2 * fs1 * fs2 + ssim_c1) * (
float)(2 * covar + ssim_c2)
 
  419          / ((
float)(fs1 * fs1 + fs2 * fs2 + ssim_c1) * (
float)(
vars + ssim_c2));
 
  424     static const int ssim_c1 = (
int)(.01*.01*255*255*64 + .5);
 
  425     static const int ssim_c2 = (
int)(.03*.03*255*255*64*63 + .5);
 
  431     int vars = fss * 64 - fs1 * fs1 - fs2 * fs2;
 
  432     int covar = fs12 * 64 - fs1 * fs2;
 
  434     return (
float)(2 * fs1 * fs2 + ssim_c1) * (
float)(2 * covar + ssim_c2)
 
  435          / ((
float)(fs1 * fs1 + fs2 * fs2 + ssim_c1) * (
float)(
vars + ssim_c2));
 
  441                    double *density_map, 
int map_width, 
double *total_weight)
 
  443     double ssim360 = 0.0, 
weight;
 
  446         weight = density_map ? density_map[(
int) ((0.5 + 
i) / 
width * map_width)] : 1.0;
 
  448             sum0[
i][0] + sum0[
i + 1][0] + sum1[
i][0] + sum1[
i + 1][0],
 
  449             sum0[
i][1] + sum0[
i + 1][1] + sum1[
i][1] + sum1[
i + 1][1],
 
  450             sum0[
i][2] + sum0[
i + 1][2] + sum1[
i][2] + sum1[
i + 1][2],
 
  451             sum0[
i][3] + sum0[
i + 1][3] + sum1[
i][3] + sum1[
i + 1][3],
 
  460                   double *density_map, 
int map_width, 
double *total_weight)
 
  462     double ssim360 = 0.0, 
weight;
 
  465         weight = density_map ? density_map[(
int) ((0.5 + 
i) / 
width * map_width)] : 1.0;
 
  467             sum0[
i][0] + sum0[
i + 1][0] + sum1[
i][0] + sum1[
i + 1][0],
 
  468             sum0[
i][1] + sum0[
i + 1][1] + sum1[
i][1] + sum1[
i + 1][1],
 
  469             sum0[
i][2] + sum0[
i + 1][2] + sum1[
i][2] + sum1[
i + 1][2],
 
  470             sum0[
i][3] + sum0[
i + 1][3] + sum1[
i][3] + sum1[
i + 1][3]);
 
  478                     uint8_t *
ref, 
int ref_stride,
 
  483     double ssim360 = 0.0;
 
  484     int64_t (*sum0)[4] = 
temp;
 
  485     int64_t (*sum1)[4] = sum0 + (
width >> 2) + 3;
 
  486     double total_weight = 0.0;
 
  491     for (
int y = 1; y < 
height; y++) {
 
  492         for (; z <= y; z++) {
 
  493             FFSWAP(
void*, sum0, sum1);
 
  495                                 &
ref[4 * z * ref_stride], ref_stride,
 
  499             (
const int64_t (*)[4])sum0, (
const int64_t (*)[4])sum1,
 
  502             density.
w, &total_weight);
 
  505     return (
double) (ssim360 / total_weight);
 
  510                    uint8_t *
ref, 
int ref_stride,
 
  515     double ssim360 = 0.0;
 
  517     int (*sum1)[4] = sum0 + (
width >> 2) + 3;
 
  518     double total_weight = 0.0;
 
  523     for (
int y = 1; y < 
height; y++) {
 
  524         for (; z <= y; z++) {
 
  525             FFSWAP(
void*, sum0, sum1);
 
  527                 &
main[4 * z * main_stride], main_stride,
 
  528                 &
ref[4 * z * ref_stride], ref_stride,
 
  532             (
const int (*)[4])sum0, (
const int (*)[4])sum1, 
width - 1,
 
  534             density.
w, &total_weight);
 
  537     return (
double) (ssim360 / total_weight);
 
  548     static const int inv_byte_mask = UINT_MAX << 8;
 
  550     int tl, tr, bl, br, v;
 
  552     if (max_value & inv_byte_mask) {
 
  553         uint16_t *data16 = (uint16_t *)
data;
 
  577                    int offset_y, 
int max_value, 
int (*sums)[4])
 
  582     for (
int z = 0; z < 2; z++) {
 
  583         int s1 = 0, 
s2 = 0, 
ss = 0, s12 = 0;
 
  586         for (
int y = offset_y; y < offset_y + 4; y++) {
 
  587             int y_stride = y << 3;
 
  588             for (
int x = offset_x; x < offset_x + 4; x++) {
 
  589                 int map_index = x + y_stride;
 
  612     int floor_theta_by_2pi, floor_theta_by_pi;
 
  615     floor_theta_by_2pi = (
int)(theta / (2.0
f * 
M_PI_F)) - (theta < 0.0
f);
 
  616     theta -= 2.0f * 
M_PI_F * floor_theta_by_2pi;
 
  619     floor_theta_by_pi = theta / 
M_PI_F;
 
  620     theta -= 2.0f * 
M_PI_F * floor_theta_by_pi;
 
  626     float pitch, yaw, norm_pitch, norm_yaw;
 
  632     pitch = asinf(norm_tape_pos*2);
 
  633     yaw   = 
M_PI_2_F * pitch / angular_resoluation;
 
  637     norm_pitch = 1.0f - (pitch / 
M_PI_F + 0.5f);
 
  638     norm_yaw   = yaw / 2.0f / 
M_PI_F + 0.5f;
 
  649              int tape_length, 
int max_value, 
void *
temp,
 
  650              double *ssim360_hist, 
double *ssim360_hist_net,
 
  653     int horizontal_block_count = 2;
 
  654     int vertical_block_count = tape_length >> 2;
 
  658     double ssim360 = 0.0;
 
  659     double sum_weight = 0.0;
 
  662     int (*sum1)[4] = sum0 + horizontal_block_count + 3;
 
  664     for (y = 1; y < vertical_block_count; y++) {
 
  665         int fs1, fs2, fss, fs12, hist_index;
 
  666         float norm_tape_pos, 
weight;
 
  667         double sample_ssim360;
 
  669         for (; z <= y; z++) {
 
  670             FFSWAP(
void*, sum0, sum1);
 
  675         fs1  = sum0[0][0] + sum0[1][0] + sum1[0][0] + sum1[1][0];
 
  676         fs2  = sum0[0][1] + sum0[1][1] + sum1[0][1] + sum1[1][1];
 
  677         fss  = sum0[0][2] + sum0[1][2] + sum1[0][2] + sum1[1][2];
 
  678         fs12 = sum0[0][3] + sum0[1][3] + sum1[0][3] + sum1[1][3];
 
  680         if (max_value > 255) {
 
  682             double ssim_c1_d = .01*.01*64*max_value*max_value;
 
  683             double ssim_c2_d = .03*.03*64*63*max_value*max_value;
 
  685             double vars = 64. * fss - 1. * fs1 * fs1 - 1. * fs2 * fs2;
 
  686             double covar = 64. * fs12 - 1.*fs1 * fs2;
 
  687             sample_ssim360 = (2. * fs1 * fs2 + ssim_c1_d) * (2. * covar + ssim_c2_d)
 
  688                         / ((1. * fs1 * fs1 + 1. * fs2 * fs2 + ssim_c1_d) * (1. * 
vars + ssim_c2_d));
 
  690             static const int ssim_c1 = (
int)(.01*.01*255*255*64 + .5);
 
  691             static const int ssim_c2 = (
int)(.03*.03*255*255*64*63 + .5);
 
  693             int vars = fss * 64 - fs1 * fs1 - fs2 * fs2;
 
  694             int covar = fs12 * 64 - fs1 * fs2;
 
  695             sample_ssim360 = (
double)(2 * fs1 * fs2 + ssim_c1) * (
double)(2 * covar + ssim_c2)
 
  702         norm_tape_pos = (y - 0.5f) / (vertical_block_count - 1.0
f) - 0.5f;
 
  705         ssim360_hist[hist_index] += 
weight;
 
  706         *ssim360_hist_net += 
weight;
 
  708         ssim360 += (sample_ssim360 * 
weight);
 
  712     return ssim360 / sum_weight;
 
  724     int x_floor = x_image;
 
  725     int y_floor = y_image;
 
  726     float x_diff = x_image - x_floor;
 
  727     float y_diff = y_image - y_floor;
 
  729     int x_ceil = x_floor + (x_diff > 1e-6);
 
  730     int y_ceil = y_floor + (y_diff > 1e-6);
 
  731     float x_inv_diff = 1.0f - x_diff;
 
  732     float y_inv_diff = 1.0f - y_diff;
 
  741     m->
tlf = x_inv_diff * y_inv_diff * fixed_point_scale;
 
  742     m->
trf = x_diff     * y_inv_diff * fixed_point_scale;
 
  743     m->
blf = x_inv_diff * y_diff     * fixed_point_scale;
 
  744     m->
brf = x_diff     * y_diff     * fixed_point_scale;
 
  749     *x = 0.5f + theta / (2.0f * 
M_PI_F);
 
  756     float abs_phi = 
FFABS(phi);
 
  767         float circle_x = radial_ratio * 
sinf(theta);
 
  768         float circle_y = radial_ratio * 
cosf(theta);
 
  769         float offset_y = 0.25f;
 
  776         *x = 0.8f + 0.1f * (1.0f + circle_x);
 
  777         *y = offset_y + 0.25f * circle_y;
 
  783     float abs_phi = 
FFABS(phi);
 
  787     float radian_pi_theta = theta / 
M_PI_F + 0.5f;
 
  790     if (radian_pi_theta < 0.0
f)
 
  791         radian_pi_theta += 2.0f;
 
  794     vFace = radian_pi_theta >= 1.0f;
 
  798         *x = 2.0f / 3.0f * (0.5f + (radian_pi_theta - vFace - 0.5f) / expand_coef);
 
  800         *y = 0.25f + 0.5f * vFace - phi / (
M_PI_F * expand_coef);
 
  804         float radial_ratio = 
cosf(abs_phi) /  (
sinf(abs_phi) * expand_coef);
 
  805         float circle_x = radial_ratio * 
sinf(theta);
 
  806         float circle_y = radial_ratio * 
cosf(theta);
 
  807         float offset_y = 0.25f;
 
  812             circle_y = (circle_y >= 0.0f) ? (1 - circle_y) : (-1 - circle_y);
 
  825         *x = 2.0f / 3.0f + 0.5f / 3.0f * (1.0f + circle_x);
 
  826         *y = offset_y + 0.25f * circle_y / expand_coef;  
 
  831 static int get_cubemap_face_map(
float axis_vec_x, 
float axis_vec_y, 
float axis_vec_z, 
float *face_x, 
float *face_y)
 
  838     if (
FFABS(axis_vec_y) > 0.577
f) {
 
  839         float x_hit = axis_vec_x / 
FFABS(axis_vec_y);
 
  840         float z_hit = axis_vec_z / axis_vec_y;
 
  851     if (
FFABS(axis_vec_x) > 0.577
f) {
 
  852         float z_hit = -axis_vec_z / axis_vec_x;
 
  853         float y_hit = axis_vec_y / 
FFABS(axis_vec_x);
 
  864     *face_x = axis_vec_x / axis_vec_z;
 
  866     *face_y = -axis_vec_y / 
FFABS(axis_vec_z);
 
  877     static const int face_projection_map[] = {
 
  882     float axis_vec_x = 
cosf(phi) * 
sinf(theta);
 
  883     float axis_vec_y = 
sinf(phi);
 
  884     float axis_vec_z = 
cosf(phi) * 
cosf(theta);
 
  885     float face_x = 0, face_y = 0;
 
  888     float x_offset = 1.f / 3.f * (face_projection_map[face_index] % 3);
 
  889     float y_offset = .5f * (face_projection_map[face_index] / 3);
 
  902     static const int face_projection_map[] = {
 
  908     float axis_yaw_vec_x, axis_yaw_vec_y, axis_yaw_vec_z;
 
  909     float axis_pitch_vec_z, axis_pitch_vec_y;
 
  910     float x_offset, y_offset;
 
  911     float face_x = 0, face_y = 0;
 
  919     axis_yaw_vec_x = 
cosf(phi) * 
sinf(theta);
 
  920     axis_yaw_vec_y = 
sinf(phi);
 
  921     axis_yaw_vec_z = 
cosf(phi) * 
cosf(theta);
 
  924     axis_pitch_vec_z = (axis_yaw_vec_z - axis_yaw_vec_y) / 
M_SQRT2_F;
 
  925     axis_pitch_vec_y = (axis_yaw_vec_y + axis_yaw_vec_z) / 
M_SQRT2_F;
 
  927     face_index = 
get_cubemap_face_map(axis_yaw_vec_x, axis_pitch_vec_y, axis_pitch_vec_z, &face_x, &face_y);
 
  930     if (face_index == 
LEFT || face_index == 
FRONT || face_index == 
RIGHT) {
 
  932         float upright_y = face_y;
 
  935     } 
else if (face_index == 
TOP || face_index == 
BOTTOM) {
 
  941     x_offset = .5f * (face_projection_map[face_index] & 1);
 
  942     y_offset = 1.f / 3.f * (face_projection_map[face_index] >> 1);
 
  944     *x = x_offset + (face_x / expand_coef + 1.f) / 4.
f;
 
  945     *y = y_offset + (face_y / expand_coef + 1.f) / 6.
f;
 
  999         return expand_coef / (
M_SQRT2_F * image_width / 4.f);
 
 1006         return FFMAX((expand_coef * 
M_PI_F) / (2.0
f / 3.0
f * image_width),
 
 1007                      expand_coef * 
M_PI_2_F / (image_height / 2.0
f));
 
 1022     int ref_image_height = ref_sample_params->
y_image_range + 1;
 
 1024     float angular_resolution =
 
 1026                                     ref_image_width, ref_image_height);
 
 1028     float conversion_factor = 
M_PI_2_F / (angular_resolution * angular_resolution);
 
 1029     float start_phi = -
M_PI_2_F + 4.0f * angular_resolution;
 
 1030     float start_x = conversion_factor * 
sinf(start_phi);
 
 1031     float end_phi = 
M_PI_2_F - 3.0f * angular_resolution;
 
 1032     float end_x = conversion_factor * 
sinf(end_phi);
 
 1033     float x_range = end_x - start_x;
 
 1036     int tape_length = 
s->tape_length[plane] = ((
int)
ROUNDED_DIV(x_range, 4)) << 2;
 
 1040     if (!
s->ref_tape_map[plane][eye] || !
s->main_tape_map[plane][eye])
 
 1043     s->angular_resolution[plane][eye] = angular_resolution;
 
 1046     for (
int y_index = 0; y_index < tape_length; y_index ++) {
 
 1047         int y_stride = y_index << 3;
 
 1049         float x = start_x + x_range * (y_index / (tape_length - 1.0f));
 
 1051         float mid_phi = asinf(x / conversion_factor);
 
 1053         float theta = mid_phi * 
M_PI_2_F / angular_resolution;
 
 1056         for (
int x_index = 0; x_index < 8; x_index ++) {
 
 1057             float phi = mid_phi + angular_resolution * (3.0f - x_index);
 
 1058             int tape_index = y_stride + x_index;
 
 1059             get_projected_map(phi, theta, ref_sample_params,  &
s->ref_tape_map [plane][eye][tape_index]);
 
 1060             get_projected_map(phi, theta, main_sample_params, &
s->main_tape_map[plane][eye][tape_index]);
 
 1071     int ref_stereo_format = 
s->ref_stereo_format;
 
 1072     int main_stereo_format = 
s->main_stereo_format;
 
 1074     int min_eye_count = 1 + are_both_stereo;
 
 1077     for (
int i = 0; 
i < 
s->nb_components; 
i ++) {
 
 1078         int ref_width = 
s->ref_planewidth[
i];
 
 1079         int ref_height = 
s->ref_planeheight[
i];
 
 1080         int main_width = 
s->main_planewidth[
i];
 
 1081         int main_height = 
s->main_planeheight[
i];
 
 1088         int ref_image_width = is_ref_LR ? ref_width >> 1 : ref_width;
 
 1089         int ref_image_height = is_ref_TB ? ref_height >> 1 : ref_height;
 
 1090         int main_image_width = is_main_LR ? main_width >> 1 : main_width;
 
 1091         int main_image_height = is_main_TB ? main_height >> 1 : main_height;
 
 1093         for (
int eye = 0; eye < min_eye_count; eye ++) {
 
 1096                 .planewidth     = ref_width,
 
 1097                 .planeheight    = ref_height,
 
 1098                 .x_image_range  = ref_image_width - 1,
 
 1099                 .y_image_range  = ref_image_height - 1,
 
 1100                 .x_image_offset = is_ref_LR * eye * ref_image_width,
 
 1101                 .y_image_offset = is_ref_TB * eye * ref_image_height,
 
 1102                 .projection     = 
s->ref_projection,
 
 1103                 .expand_coef    = 1.f + 
s->ref_pad,
 
 1108                 .planewidth     = main_width,
 
 1109                 .planeheight    = main_height,
 
 1110                 .x_image_range  = main_image_width - 1,
 
 1111                 .y_image_range  = main_image_height - 1,
 
 1112                 .x_image_offset = is_main_LR * eye * main_image_width,
 
 1113                 .y_image_offset = is_main_TB * eye * main_image_height,
 
 1114                 .projection     = 
s->main_projection,
 
 1115                 .expand_coef    = 1.f + 
s->main_pad,
 
 1133     double c[4], ssim360v = 0.0, ssim360p50 = 0.0;
 
 1135     int need_frame_skip = 
s->nb_net_frames % (
s->frame_skip_ratio + 1);
 
 1144     if (need_frame_skip)
 
 1147     metadata = &
master->metadata;
 
 1149     if (
s->use_tape && !
s->tape_length[0]) {
 
 1155     for (
i = 0; 
i < 
s->nb_components; 
i++) {
 
 1158                                 ref->data[
i],    
s->ref_tape_map [
i][0],
 
 1159                                 s->tape_length[
i], 
s->max, 
s->temp,
 
 1160                                 s->ssim360_hist[
i], &
s->ssim360_hist_net[
i],
 
 1161                                 s->angular_resolution[
i][0], 
s->heatmaps);
 
 1163             if (
s->ref_tape_map[
i][1]) {
 
 1165                                      ref->data[
i],    
s->ref_tape_map[
i][1],
 
 1166                                      s->tape_length[
i], 
s->max, 
s->temp,
 
 1167                                      s->ssim360_hist[
i], &
s->ssim360_hist_net[
i],
 
 1168                                      s->angular_resolution[
i][1], 
s->heatmaps);
 
 1174                                     s->ref_planewidth[
i], 
s->ref_planeheight[
i],
 
 1175                                     s->temp, 
s->max, 
s->density);
 
 1178         s->ssim360[
i] += 
c[
i];
 
 1179         ssim360v      += 
s->coefs[
i] * 
c[
i];
 
 1182     s->nb_ssim_frames++;
 
 1185         h_ptr = 
s->heatmaps;
 
 1186         s->heatmaps = 
s->heatmaps->next;
 
 1189     s->ssim360_total += ssim360v;
 
 1193         int i, p, hist_indices[4];
 
 1194         double hist_weight[4];
 
 1196         for (
i = 0; 
i < 
s->nb_components; 
i++) {
 
 1202             for (
i = 0; 
i < 
s->nb_components; 
i++) {
 
 1203                 double target_weight, ssim360p;
 
 1207                 target_weight = 
FFMAX(target_weight, 1);
 
 1208                 while(hist_indices[
i] >= 0 && hist_weight[
i] < target_weight) {
 
 1209                     hist_weight[
i] += 
s->ssim360_hist[
i][hist_indices[
i]];
 
 1215                     ssim360p50 += 
s->coefs[
i] * ssim360p;
 
 1216                 s->ssim360_percentile_sum[
i][p] += ssim360p;
 
 1220         for (
i = 0; 
i < 
s->nb_components; 
i++) {
 
 1222             s->ssim360_hist_net[
i] = 0;
 
 1225         for (
i = 0; 
i < 
s->nb_components; 
i++) {
 
 1226             int cidx = 
s->is_rgb ? 
s->rgba_map[
i] : 
i;
 
 1227             set_meta(metadata, 
"lavfi.ssim360.", 
s->comps[
i], 
c[cidx]);
 
 1231         set_meta(metadata, 
"lavfi.ssim360.All", 0, ssim360p50);
 
 1234         if (
s->stats_file) {
 
 1235             fprintf(
s->stats_file, 
"n:%"PRId64
" ", 
s->nb_ssim_frames);
 
 1237             for (
i = 0; 
i < 
s->nb_components; 
i++) {
 
 1238                 int cidx = 
s->is_rgb ? 
s->rgba_map[
i] : 
i;
 
 1239                 fprintf(
s->stats_file, 
"%c:%f ", 
s->comps[
i], 
c[cidx]);
 
 1242             fprintf(
s->stats_file, 
"All:%f (%f)\n", ssim360p50, 
ssim360_db(ssim360p50, 1.0));
 
 1250                           const char *
data, 
int w, 
int h)
 
 1268         char *saveptr, *
val;
 
 1316     if (
s->stats_file_str) {
 
 1317         if (!strcmp(
s->stats_file_str, 
"-")) {
 
 1318             s->stats_file = stdout;
 
 1321             if (!
s->stats_file) {
 
 1327                        s->stats_file_str, buf);
 
 1333     if (
s->use_tape && 
s->heatmap_str) {
 
 1335                              s->default_heatmap_w, 
s->default_heatmap_h);
 
 1350     s->main_planeheight[0] = 
inlink->h;
 
 1351     s->main_planeheight[3] = 
inlink->h;
 
 1355     s->main_planewidth[0]  = 
inlink->w;
 
 1356     s->main_planewidth[3]  = 
inlink->w;
 
 1362         s->main_projection = 
s->ref_projection;
 
 1366         s->main_stereo_format = 
s->ref_stereo_format;
 
 1373     double d, r_square, cos_square;
 
 1380     switch (
s->ref_stereo_format) {
 
 1389     switch (
s->ref_projection) {
 
 1391         for (
int i = 0; 
i < 
h; 
i++) {
 
 1392             d = cos(((0.5 + 
i) / 
h - 0.5) * 
M_PI);
 
 1393             for (
int j = 0; j < 
w; j++)
 
 1394                 s->density.value[
i * 
w + j] = 
d;
 
 1399         for (
int i = 0; 
i < 
h / 4; 
i++) {
 
 1400             for (
int j = 0; j < 
w / 6; j++) {
 
 1403                   (0.5 + 
i) / (
h / 2) * (0.5 + 
i) / (
h / 2) +
 
 1404                   (0.5 + j) / (
w / 3) * (0.5 + j) / (
w / 3);
 
 1406                 cos_square = 0.25 / (r_square + 0.25);
 
 1407                 d = pow(cos_square, 1.5);
 
 1409                 for (
int face = 0; face < 6; face++) {
 
 1422                         ow = 
w / 6 + 2 * 
w / 3;
 
 1434                         ow = 
w / 6 + 2 * 
w / 3;
 
 1437                     s->density.value[(oh - 1 - 
i) * 
w + ow - 1 - j] = 
d;
 
 1438                     s->density.value[(oh - 1 - 
i) * 
w + ow     + j] = 
d;
 
 1439                     s->density.value[(oh     + 
i) * 
w + ow - 1 - j] = 
d;
 
 1440                     s->density.value[(oh     + 
i) * 
w + ow     + j] = 
d;
 
 1447         for (
int i = 0; 
i < 
h / 6; 
i++) {
 
 1448             for (
int j = 0; j < 
w / 4; j++) {
 
 1451                     (0.5 + 
i) / (
h / 3) * (0.5 + 
i) / (
h / 3) +
 
 1452                     (0.5 + j) / (
w / 2) * (0.5 + j) / (
w / 2);
 
 1453                 r_square /= (1.f + 
s->ref_pad) * (1.
f + 
s->ref_pad);
 
 1454                 cos_square = 0.25 / (r_square + 0.25);
 
 1455                 d = pow(cos_square, 1.5);
 
 1457                 for (
int face = 0; face < 6; face++) {
 
 1470                         oh = 
h / 6 + 2 * 
h / 3;
 
 1482                         oh = 
h / 6 + 2 * 
h / 3;
 
 1485                   s->density.value[(oh - 1 - 
i) * 
w + ow - 1 - j] = 
d;
 
 1486                   s->density.value[(oh - 1 - 
i) * 
w + ow     + j] = 
d;
 
 1487                   s->density.value[(oh     + 
i) * 
w + ow - 1 - j] = 
d;
 
 1488                   s->density.value[(oh     + 
i) * 
w + ow     + j] = 
d;
 
 1495         for (
int i = 0; 
i < 
h; 
i++) {
 
 1496             for (
int j = 0; j < 
w * 4 / 5; j++) {
 
 1498                 s->density.value[
i * 
w + j] = 
d * 
d * 
d;
 
 1502         for (
int i = 0; 
i < 
h; 
i++) {
 
 1503             for (
int j = 
w * 4 / 5; j < 
w; j++) {
 
 1505                 double dx_squared = dx * dx;
 
 1508                 double top_dy_squared = top_dy * top_dy;
 
 1511                 double bottom_dy_squared = bottom_dy * bottom_dy;
 
 1514                 r_square = (
i < 
h / 2 ? top_dy_squared : bottom_dy_squared) + dx_squared;
 
 1518                 cos_square = 1.0 / (r_square + 1.0);
 
 1519                 d = pow(cos_square, 1.5);
 
 1520                 s->density.value[
i * 
w + j] = 
d;
 
 1526         for (
int i = 0; 
i < 
h; 
i++) {
 
 1527             for (
int j = 0; j < 
w; j++)
 
 1528                 s->density.value[
i * 
w + j] = 0;
 
 1532     switch (
s->ref_stereo_format) {
 
 1534         for (
int i = 0; 
i < 
h; 
i++) {
 
 1535             for (
int j = 0; j < 
w; j++)
 
 1536                 s->density.value[(
i + 
h) * 
w + j] = 
s->density.value[
i * 
w + j];
 
 1540         for (
int i = 0; 
i < 
h; 
i++) {
 
 1541             for (
int j = 0; j < 
w; j++)
 
 1542                 s->density.value[
i * 
w + j + 
w] = 
s->density.value[
i * 
w + j];
 
 1556     s->nb_components = 
desc->nb_components;
 
 1558     s->ref_planeheight[0] = 
inlink->h;
 
 1559     s->ref_planeheight[3] = 
inlink->h;
 
 1563     s->ref_planewidth[0]  = 
inlink->w;
 
 1564     s->ref_planewidth[3]  = 
inlink->w;
 
 1569     s->comps[0] = 
s->is_rgb ? 
'R' : 
'Y';
 
 1570     s->comps[1] = 
s->is_rgb ? 
'G' : 
'U';
 
 1571     s->comps[2] = 
s->is_rgb ? 
'B' : 
'V';
 
 1575     if (!
s->is_rgb && !
s->compute_chroma)
 
 1576         s->nb_components = 1;
 
 1578     s->max = (1 << 
desc->comp[0].depth) - 1;
 
 1582     for (
int i = 0; 
i < 
s->nb_components; 
i++)
 
 1583         sum += 
s->ref_planeheight[
i] * 
s->ref_planewidth[
i];
 
 1584     for (
int i = 0; 
i < 
s->nb_components; 
i++)
 
 1585         s->coefs[
i] = (
double) 
s->ref_planeheight[
i] * 
s->ref_planewidth[
i] / sum;
 
 1600     if (
ctx->inputs[0]->w != 
ctx->inputs[1]->w || 
ctx->inputs[0]->h != 
ctx->inputs[1]->h ||
 
 1601         s->ref_projection != 
s->main_projection || 
s->ref_stereo_format != 
s->main_stereo_format)
 
 1618         memset(
s->ssim360_percentile_sum, 0, 
sizeof(
s->ssim360_percentile_sum));
 
 1620         for (
int i = 0; 
i < 
s->nb_components; 
i++) {
 
 1622             if (!
s->ssim360_hist[
i])
 
 1630         if (!
s->density.value) {
 
 1641     outlink->
w = mainlink->
w;
 
 1642     outlink->
h = mainlink->
h;
 
 1647     s->fs.opt_shortest   = 1;
 
 1648     s->fs.opt_repeatlast = 1;
 
 1667     if (
s->nb_ssim_frames > 0) {
 
 1671         for (
int i = 0; 
i < 
s->nb_components; 
i++) {
 
 1672             int c = 
s->is_rgb ? 
s->rgba_map[
i] : 
i;
 
 1673             av_strlcatf(buf, 
sizeof(buf), 
" %c:%f (%f)", 
s->comps[
i], 
s->ssim360[
c] / 
s->nb_ssim_frames,
 
 1677                s->ssim360_total / 
s->nb_ssim_frames, 
ssim360_db(
s->ssim360_total, 
s->nb_ssim_frames));
 
 1683                 for (
int i = 0; 
i < 
s->nb_components; 
i++) {
 
 1684                     int c = 
s->is_rgb ? 
s->rgba_map[
i] : 
i;
 
 1685                     double ssim360p = 
s->ssim360_percentile_sum[
i][p] / (
double)(
s->nb_ssim_frames);
 
 1698     for (
int i = 0; 
i < 
s->nb_components; 
i++) {
 
 1699         for (
int eye = 0; eye < 2; eye++) {
 
 1708     if (
s->stats_file && 
s->stats_file != stdout)
 
 1709         fclose(
s->stats_file);
 
 1714 #define PF(suf) AV_PIX_FMT_YUV420##suf,  AV_PIX_FMT_YUV422##suf,  AV_PIX_FMT_YUV444##suf, AV_PIX_FMT_GBR##suf 
 1734         .name         = 
"reference",
 
 1751     .preinit       = ssim360_framesync_preinit,
 
 1756     .priv_class    = &ssim360_class,