Exemplo n.º 1
0
static void
schro_encoder_generate_subband_histogram (SchroEncoderFrame *frame,
    int component, int index, SchroHistogram *hist, int skip)
{
  int i;
  int j;
  int16_t *data;
  int16_t *line;
  int stride;
  int width;
  int height;
  int position;

  schro_histogram_init (hist);

  position = schro_subband_get_position (index);
  schro_subband_get (frame->iwt_frame, component, position,
      &frame->params, &data, &stride, &width, &height);

  if (index > 0) {
    for(j=0;j<height;j+=skip){
      schro_histogram_add_array_s16 (hist, OFFSET(data, j*stride), width);
    }
    schro_histogram_scale (hist, skip);
  } else {
    for(j=0;j<height;j+=skip){
      line = OFFSET(data, j*stride);
      for(i=1;i<width;i+=skip){
        schro_histogram_add(hist, (line[i] - line[i-1]));
      }
    }
    schro_histogram_scale (hist, skip*skip);
  }
}
Exemplo n.º 2
0
static double
measure_error_subband (SchroEncoderFrame *frame, int component, int index,
    int quant_index)
{
  int i;
  int j;
  int16_t *data;
  int16_t *line;
  int stride;
  int width;
  int height;
  int skip = 1;
  double error = 0;
  int q;
  int quant_factor;
  int quant_offset;
  int value;
  int position;

  position = schro_subband_get_position (index);
  schro_subband_get (frame->iwt_frame, component, position,
      &frame->params, &data, &stride, &width, &height);

  quant_factor = schro_table_quant[quant_index];
  if (frame->params.num_refs > 0) {
    quant_offset = schro_table_offset_3_8[quant_index];
  } else {
    quant_offset = schro_table_offset_1_2[quant_index];
  }

  error = 0;
  if (index == 0) {
    for(j=0;j<height;j+=skip){
      line = OFFSET(data, j*stride);
      for(i=1;i<width;i+=skip){
        q = schro_quantise(abs(line[i] - line[i-1]), quant_factor, quant_offset);
        value = schro_dequantise(q, quant_factor, quant_offset);
        error += pow2(value - abs(line[i] - line[i-1]));
      }
    }
  } else {
    for(j=0;j<height;j+=skip){
      line = OFFSET(data, j*stride);
      for(i=0;i<width;i+=skip){
        q = schro_quantise(line[i], quant_factor, quant_offset);
        value = schro_dequantise(q, quant_factor, quant_offset);
        error += pow2(value - line[i]);
      }
    }
  }
  error *= skip*skip;

  return error;
}
Exemplo n.º 3
0
static void
schro_encoder_dump_subband_curves (SchroEncoderFrame *frame)
{
  SchroParams *params = &frame->params;
  int i;
  int component;
  int pos;

  SCHRO_ASSERT(frame->have_histograms);

  for(component=0;component<3;component++){
    for(i=0;i<1 + 3*params->transform_depth; i++) {
      int vol;
      int16_t *data;
      int stride;
      int width, height;
      int j;
      SchroHistogram *hist;

      pos = schro_subband_get_position (i);
      schro_subband_get (frame->iwt_frame, component, pos,
          &frame->params, &data, &stride, &width, &height);
      vol = width * height;
      hist = &frame->subband_hists[component][i];

      for(j=0;j<60;j++){
        double est_entropy;
        double error;
        double est_error;
        double arith_entropy;

        error = measure_error_subband (frame, component, i, j);
        est_entropy = schro_histogram_estimate_entropy (
            &frame->subband_hists[component][i], j, params->is_noarith);
        est_error = schro_histogram_apply_table (hist,
            &frame->encoder->intra_hist_tables[j]);
        arith_entropy = schro_encoder_estimate_subband_arith (frame,
            component, i, j);

        schro_dump (SCHRO_DUMP_SUBBAND_CURVE, "%d %d %d %g %g %g %g\n",
            component, i, j, est_entropy/vol, arith_entropy/vol,
            est_error/vol, error/vol);
      }
    }
  }
}
Exemplo n.º 4
0
void
generate_noise (SchroFrame *frame, int n_transforms, double *weights)
{
  int i;
  int j;
  int k;
  int l;
  int pos;
  int w, h, x_offset, y_offset, y_skip;
  int16_t *data;
  SchroFrameData *comp;

  for(k=0;k<3;k++){
    comp = frame->components + k;

    for(l=0;l<1+3*n_transforms;l++){
      pos = schro_subband_get_position (l);

      w = comp->width >> (n_transforms - SCHRO_SUBBAND_SHIFT(pos));
      h = comp->height >> (n_transforms - SCHRO_SUBBAND_SHIFT(pos));
      y_skip = 1<<(n_transforms - SCHRO_SUBBAND_SHIFT(pos));
      if (pos&1) {
        x_offset = w;
      } else {
        x_offset = 0;
      }
      if (pos&2) {
        y_offset = y_skip / 2;
      } else {
        y_offset = 0;
      }
//printf("%d %d w %d h %d x_offset %d y_offset %d y_skip %d\n", l, pos, w, h, x_offset, y_offset, y_skip);

      for(j=0;j<h;j++){
        data = OFFSET(comp->data,
            (j*y_skip + y_offset)*comp->stride);
        data += x_offset;
        for(i=0;i<w;i++){
          data[i] = rint(random_std()*AMPLITUDE*weights[l]);
          //data[i] = rint(random_std()*AMPLITUDE);
        }
      }
    }
  }
}
Exemplo n.º 5
0
void
schro_encoder_init_subbands (SchroEncoderFrame *frame)
{
  int i;
  int pos;
  SchroParams *params = &frame->params;

  for(i=0;i<1+3*params->transform_depth;i++) {
    pos = schro_subband_get_position (i);

    schro_subband_get_frame_data (frame->luma_subbands + i,
        frame->iwt_frame, 0, pos, params);
    schro_subband_get_frame_data (frame->chroma1_subbands + i,
        frame->iwt_frame, 0, pos, params);
    schro_subband_get_frame_data (frame->chroma2_subbands + i,
        frame->iwt_frame, 0, pos, params);
  }
}
Exemplo n.º 6
0
static void
schro_encoder_generate_subband_histograms (SchroEncoderFrame *frame)
{
  SchroParams *params = &frame->params;
  int i;
  int component;
  int pos;
  int skip;

  for(component=0;component<3;component++){
    for(i=0;i<1 + 3*params->transform_depth; i++) {
      pos = schro_subband_get_position (i);
      skip = 1<<MAX(0,SCHRO_SUBBAND_SHIFT(pos)-1);
      schro_encoder_generate_subband_histogram (frame, component, i,
          &frame->subband_hists[component][i], skip);
    }
  }

  frame->have_histograms = TRUE;
}
Exemplo n.º 7
0
static void
schro_lowdelay_init (SchroLowDelay *lowdelay, SchroFrame *frame,
    SchroParams *params)
{
  int i;
  int size;

  lowdelay->params = params;
  for(i=0;i<1+3*params->transform_depth;i++){
    int position = schro_subband_get_position(i);

    schro_subband_get_frame_data (lowdelay->luma_subbands + i,
        frame, 0, position, params);
    schro_subband_get_frame_data (lowdelay->chroma1_subbands + i,
        frame, 1, position, params);
    schro_subband_get_frame_data (lowdelay->chroma2_subbands + i,
        frame, 2, position, params);
  }

  size = 1000;
  lowdelay->saved_dc_values = schro_malloc (sizeof(int16_t) * size);
}
Exemplo n.º 8
0
static void
schro_encoder_calc_estimates (SchroEncoderFrame *frame)
{
  SchroParams *params = &frame->params;
  int i;
  int j;
  int component;

  SCHRO_ASSERT(frame->have_histograms);

#ifdef DUMP_SUBBAND_CURVES
  schro_encoder_dump_subband_curves (frame);
#endif

  for(component=0;component<3;component++){
    for(i=0;i<1 + 3*params->transform_depth; i++) {
      for(j=0;j<60;j++){
        int vol;
        int16_t *data;
        int stride;
        int width, height;
        int position;
        SchroHistogram *hist;

        position = schro_subband_get_position (i);
        schro_subband_get (frame->iwt_frame, component, position,
            &frame->params, &data, &stride, &width, &height);
        vol = width * height;

        hist = &frame->subband_hists[component][i];
        frame->est_entropy[component][i][j] =
          schro_histogram_estimate_entropy (hist, j, params->is_noarith);
        frame->est_error[component][i][j] = schro_histogram_apply_table (hist,
              &frame->encoder->intra_hist_tables[j]);
      }
    }
  }
  frame->have_estimate_tables = TRUE;
}
Exemplo n.º 9
0
void
schro_encoder_rate_distortion_test (SchroEncoderFrame *frame)
{
  SchroParams *params = &frame->params;
  int i;
  int component;
  int j;
  double lambda_mult;
  double n;
  double base_lambda;
  int qsum;

base_lambda = 0.1;
  schro_encoder_generate_subband_histograms (frame);
  schro_encoder_calc_estimates (frame);

  for(j=0;j<40;j++){
    lambda_mult = pow(1.1, j-20);
    n = 0;
    qsum = 0;

  for(component=0;component<3;component++){
    for(i=0;i<1 + 3*params->transform_depth; i++) {
      int vol;
      int16_t *data;
      int stride;
      int width, height;
      double lambda;
      int position;
      double weight;
      int quant_index;

      position = schro_subband_get_position (i);
      schro_subband_get (frame->iwt_frame, component, position,
          &frame->params, &data, &stride, &width, &height);
      vol = width * height;

      lambda = base_lambda;
      lambda *= lambda_mult;
      if (i == 0) {
        //lambda *= 10;
      }
#if 0
      if (component > 0) {
        lambda *= 0.3;
      }
#endif
      if (frame->is_ref) {
        lambda *= 10;
      }

      weight = frame->encoder->subband_weights[frame->params.wavelet_filter_index]
        [frame->params.transform_depth-1][i];
      lambda /= weight*weight;
      
      quant_index = schro_subband_pick_quant (frame, component, i, lambda);
      n += frame->est_entropy[component][i][quant_index];
      qsum += quant_index;
    }
  }
    schro_dump (SCHRO_DUMP_LAMBDA_CURVE, "%d %g %g %d",
        j, lambda_mult * base_lambda, n, qsum);
  }
}
Exemplo n.º 10
0
static double
schro_encoder_estimate_subband_arith (SchroEncoderFrame *frame, int component,
    int index, int quant_index)
{
  int i;
  int j;
  int16_t *data;
  int16_t *line;
  int stride;
  int width;
  int height;
  int q;
  int quant_factor;
  int quant_offset;
  int estimated_entropy;
  SchroArith *arith;
  int position;

  arith = schro_arith_new ();
  schro_arith_estimate_init (arith);

  position = schro_subband_get_position (index);
  schro_subband_get (frame->iwt_frame, component, position,
      &frame->params, &data, &stride, &width, &height);

  quant_factor = schro_table_quant[quant_index];
  quant_offset = schro_table_offset_1_2[quant_index];

  if (index == 0) {
    for(j=0;j<height;j++) {
      line = OFFSET(data, j*stride);
      schro_arith_estimate_sint (arith,
          SCHRO_CTX_ZPZN_F1, SCHRO_CTX_COEFF_DATA, SCHRO_CTX_SIGN_ZERO, 0);
      for(i=1;i<width;i++) {
        q = schro_quantise(line[i] - line[i-1], quant_factor, quant_offset);
        schro_arith_estimate_sint (arith,
            SCHRO_CTX_ZPZN_F1, SCHRO_CTX_COEFF_DATA, SCHRO_CTX_SIGN_ZERO, q);
      }
    }
  } else {
    for(j=0;j<height;j++) {
      line = OFFSET(data, j*stride);
      for(i=0;i<width;i++) {
        q = schro_quantise(line[i], quant_factor, quant_offset);
        schro_arith_estimate_sint (arith,
            SCHRO_CTX_ZPZN_F1, SCHRO_CTX_COEFF_DATA, SCHRO_CTX_SIGN_ZERO, q);
      }
    }
  }

  estimated_entropy = 0;

  estimated_entropy += arith->contexts[SCHRO_CTX_ZPZN_F1].n_bits;
  estimated_entropy += arith->contexts[SCHRO_CTX_ZP_F2].n_bits;
  estimated_entropy += arith->contexts[SCHRO_CTX_ZP_F3].n_bits;
  estimated_entropy += arith->contexts[SCHRO_CTX_ZP_F4].n_bits;
  estimated_entropy += arith->contexts[SCHRO_CTX_ZP_F5].n_bits;
  estimated_entropy += arith->contexts[SCHRO_CTX_ZP_F6p].n_bits;

  estimated_entropy += arith->contexts[SCHRO_CTX_COEFF_DATA].n_bits;

  estimated_entropy += arith->contexts[SCHRO_CTX_SIGN_ZERO].n_bits;

  schro_arith_free (arith);

  return estimated_entropy;
}
Exemplo n.º 11
0
void
schro_encoder_calculate_subband_weights (SchroEncoder *encoder,
    double (*perceptual_weight)(double))
{
  int wavelet;
  int n_levels;
  double *matrix;
  int n;
  int i,j;
  double column[SCHRO_LIMIT_SUBBANDS];
  double *weight;

  matrix = schro_malloc (sizeof(double)*SCHRO_LIMIT_SUBBANDS*SCHRO_LIMIT_SUBBANDS);
  weight = schro_malloc (sizeof(double)*CURVE_SIZE*CURVE_SIZE);

  for(j=0;j<CURVE_SIZE;j++){
    for(i=0;i<CURVE_SIZE;i++){
      double fv = j*encoder->cycles_per_degree_vert*(1.0/CURVE_SIZE);
      double fh = i*encoder->cycles_per_degree_horiz*(1.0/CURVE_SIZE);

      weight[j*CURVE_SIZE+i] = perceptual_weight (sqrt(fv*fv+fh*fh));
    }
  }

  for(wavelet=0;wavelet<SCHRO_N_WAVELETS;wavelet++) {
    for(n_levels=1;n_levels<=4;n_levels++){
      const float *h_curve[SCHRO_LIMIT_SUBBANDS];
      const float *v_curve[SCHRO_LIMIT_SUBBANDS];
      int hi[SCHRO_LIMIT_SUBBANDS];
      int vi[SCHRO_LIMIT_SUBBANDS];

      n = 3*n_levels+1;

      for(i=0;i<n;i++){
        int position = schro_subband_get_position(i);
        int n_transforms;

        n_transforms = n_levels - SCHRO_SUBBAND_SHIFT(position);
        if (position&1) {
          hi[i] = (n_transforms-1)*2;
        } else {
          hi[i] = (n_transforms-1)*2+1;
        }
        if (position&2) {
          vi[i] = (n_transforms-1)*2;
        } else {
          vi[i] = (n_transforms-1)*2+1;
        }
        h_curve[i] = schro_tables_wavelet_noise_curve[wavelet][hi[i]];
        v_curve[i] = schro_tables_wavelet_noise_curve[wavelet][vi[i]];
      }

      if (0) {
        for(i=0;i<n;i++){
          column[i] = weighted_sum(h_curve[i], v_curve[i], weight);
          matrix[i*n+i] = dot_product (h_curve[i], v_curve[i],
              h_curve[i], v_curve[i], weight);
          for(j=i+1;j<n;j++) {
            matrix[i*n+j] = dot_product (h_curve[i], v_curve[i],
                h_curve[j], v_curve[j], weight);
            matrix[j*n+i] = matrix[i*n+j];
          }
        }

        solve (matrix, column, n);

        for(i=0;i<n;i++){
          if (column[i] < 0) {
            SCHRO_ERROR("BROKEN wavelet %d n_levels %d", wavelet, n_levels);
            break;
          }
        }

        SCHRO_DEBUG("wavelet %d n_levels %d", wavelet, n_levels);
        for(i=0;i<n;i++){
          SCHRO_DEBUG("%g", 1.0/sqrt(column[i]));
          encoder->subband_weights[wavelet][n_levels-1][i] = sqrt(column[i]);
        }
      } else {
        for(i=0;i<n;i++){
          int position = schro_subband_get_position(i);
          int n_transforms;
          double size;

          n_transforms = n_levels - SCHRO_SUBBAND_SHIFT(position);
          size = (1.0/CURVE_SIZE)*(1<<n_transforms);
          encoder->subband_weights[wavelet][n_levels-1][i] = 1.0/(size *
            sqrt(weighted_sum(h_curve[i], v_curve[i], weight)));
        }
      }
    }
  }

#if 0
  for(wavelet=0;wavelet<8;wavelet++) {
    for(n_levels=1;n_levels<=4;n_levels++){
      double alpha, beta, shift;
      double gain;

      alpha = schro_tables_wavelet_gain[wavelet][0];
      beta = schro_tables_wavelet_gain[wavelet][1];
      shift = (1<<filtershift[wavelet]);

      n = 3*n_levels+1;

      gain = shift;
      for(i=n_levels-1;i>=0;i--){
        encoder->subband_weights[wavelet][n_levels-1][1+3*i+0] =
          sqrt(alpha*beta)*gain;
        encoder->subband_weights[wavelet][n_levels-1][1+3*i+1] =
          sqrt(alpha*beta)*gain;
        encoder->subband_weights[wavelet][n_levels-1][1+3*i+2] =
          sqrt(beta*beta)*gain;
        gain *= alpha;
        gain *= shift;
      }
      encoder->subband_weights[wavelet][n_levels-1][0] = gain / shift;
      if (wavelet == 3 && n_levels == 3) {
        for(i=0;i<10;i++){
          SCHRO_ERROR("%g",
              encoder->subband_weights[wavelet][n_levels-1][i]);
        }
      }
    }
  }
#endif

  schro_free(weight);
  schro_free(matrix);
}