chromium/third_party/libvpx/source/libvpx/vp8/encoder/onyx_if.c

/*
 *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "vpx_config.h"
#include "./vpx_scale_rtcd.h"
#include "./vpx_dsp_rtcd.h"
#include "./vp8_rtcd.h"
#include "bitstream.h"
#include "vp8/common/onyxc_int.h"
#include "vp8/common/blockd.h"
#include "onyx_int.h"
#include "vp8/common/systemdependent.h"
#include "vp8/common/vp8_skin_detection.h"
#include "vp8/encoder/quantize.h"
#include "vp8/common/alloccommon.h"
#include "mcomp.h"
#include "firstpass.h"
#include "vpx_dsp/psnr.h"
#include "vpx_scale/vpx_scale.h"
#include "vp8/common/extend.h"
#include "ratectrl.h"
#include "vp8/common/quant_common.h"
#include "segmentation.h"
#if CONFIG_POSTPROC
#include "vp8/common/postproc.h"
#endif
#include "vpx_mem/vpx_mem.h"
#include "vp8/common/reconintra.h"
#include "vp8/common/swapyv12buffer.h"
#include "vp8/common/threading.h"
#include "vpx_ports/system_state.h"
#include "vpx_ports/vpx_once.h"
#include "vpx_ports/vpx_timer.h"
#include "vpx_util/vpx_write_yuv_frame.h"
#if VPX_ARCH_ARM
#include "vpx_ports/arm.h"
#endif
#if CONFIG_MULTI_RES_ENCODING
#include "mr_dissim.h"
#endif
#include "encodeframe.h"
#if CONFIG_MULTITHREAD
#include "ethreading.h"
#endif
#include "picklpf.h"
#if !CONFIG_REALTIME_ONLY
#include "temporal_filter.h"
#endif

#include <assert.h>
#include <math.h>
#include <stdio.h>
#include <limits.h>

#if CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING
extern int vp8_update_coef_context(VP8_COMP *cpi);
#endif

extern unsigned int vp8_get_processor_freq(void);

int vp8_calc_ss_err(YV12_BUFFER_CONFIG *source, YV12_BUFFER_CONFIG *dest);

static void set_default_lf_deltas(VP8_COMP *cpi);

extern const int vp8_gf_interval_table[101];

#if CONFIG_INTERNAL_STATS
#include "math.h"
#include "vpx_dsp/ssim.h"
#endif

#ifdef OUTPUT_YUV_SRC
FILE *yuv_file;
#endif
#ifdef OUTPUT_YUV_DENOISED
FILE *yuv_denoised_file;
#endif
#ifdef OUTPUT_YUV_SKINMAP
static FILE *yuv_skinmap_file = NULL;
#endif

#if 0
FILE *framepsnr;
FILE *kf_list;
FILE *keyfile;
#endif

#if 0
extern int skip_true_count;
extern int skip_false_count;
#endif

#ifdef SPEEDSTATS
unsigned int frames_at_speed[16] = { 0, 0, 0, 0, 0, 0, 0, 0,
                                     0, 0, 0, 0, 0, 0, 0, 0 };
unsigned int tot_pm = 0;
unsigned int cnt_pm = 0;
unsigned int tot_ef = 0;
unsigned int cnt_ef = 0;
#endif

#ifdef MODE_STATS
extern unsigned __int64 Sectionbits[50];
extern int y_modes[5];
extern int uv_modes[4];
extern int b_modes[10];

extern int inter_y_modes[10];
extern int inter_uv_modes[4];
extern unsigned int inter_b_modes[15];
#endif

extern const int vp8_bits_per_mb[2][QINDEX_RANGE];

extern const int qrounding_factors[129];
extern const int qzbin_factors[129];
extern void vp8cx_init_quantizer(VP8_COMP *cpi);
extern const int vp8cx_base_skip_false_prob[128];

/* Tables relating active max Q to active min Q */
static const unsigned char kf_low_motion_minq[QINDEX_RANGE] =;
static const unsigned char kf_high_motion_minq[QINDEX_RANGE] =;
static const unsigned char gf_low_motion_minq[QINDEX_RANGE] =;
static const unsigned char gf_mid_motion_minq[QINDEX_RANGE] =;
static const unsigned char gf_high_motion_minq[QINDEX_RANGE] =;
static const unsigned char inter_minq[QINDEX_RANGE] =;

#ifdef PACKET_TESTING
extern FILE *vpxlogc;
#endif

void vp8_save_layer_context(VP8_COMP *cpi) {}

void vp8_restore_layer_context(VP8_COMP *cpi, const int layer) {}

static int rescale(int val, int num, int denom) {}

void vp8_init_temporal_layer_context(VP8_COMP *cpi, const VP8_CONFIG *oxcf,
                                     const int layer,
                                     double prev_layer_framerate) {}

// Upon a run-time change in temporal layers, reset the layer context parameters
// for any "new" layers. For "existing" layers, let them inherit the parameters
// from the previous layer state (at the same layer #). In future we may want
// to better map the previous layer state(s) to the "new" ones.
void vp8_reset_temporal_layer_change(VP8_COMP *cpi, const VP8_CONFIG *oxcf,
                                     const int prev_num_layers) {}

static void setup_features(VP8_COMP *cpi) {}

static void dealloc_raw_frame_buffers(VP8_COMP *cpi);

static void initialize_enc(void) {}

void vp8_initialize_enc(void) {}

static void dealloc_compressor_data(VP8_COMP *cpi) {}

static void enable_segmentation(VP8_COMP *cpi) {}
static void disable_segmentation(VP8_COMP *cpi) {}

/* Valid values for a segment are 0 to 3
 * Segmentation map is arrange as [Rows][Columns]
 */
static void set_segmentation_map(VP8_COMP *cpi,
                                 unsigned char *segmentation_map) {}

/* The values given for each segment can be either deltas (from the default
 * value chosen for the frame) or absolute values.
 *
 * Valid range for abs values is:
 *    (0-127 for MB_LVL_ALT_Q), (0-63 for SEGMENT_ALT_LF)
 * Valid range for delta values are:
 *    (+/-127 for MB_LVL_ALT_Q), (+/-63 for SEGMENT_ALT_LF)
 *
 * abs_delta = SEGMENT_DELTADATA (deltas)
 * abs_delta = SEGMENT_ABSDATA (use the absolute values given).
 *
 */
static void set_segment_data(VP8_COMP *cpi, signed char *feature_data,
                             unsigned char abs_delta) {}

/* A simple function to cyclically refresh the background at a lower Q */
static void cyclic_background_refresh(VP8_COMP *cpi, int Q, int lf_adjustment) {}

static void compute_skin_map(VP8_COMP *cpi) {}

static void set_default_lf_deltas(VP8_COMP *cpi) {}

/* Convenience macros for mapping speed and mode into a continuous
 * range
 */
#define GOOD
#define RT

static int speed_map(int speed, const int *map) {}

static const int thresh_mult_map_znn[] =;

static const int thresh_mult_map_vhpred[] =;

static const int thresh_mult_map_bpred[] =;

static const int thresh_mult_map_tm[] =;

static const int thresh_mult_map_new1[] =;

static const int thresh_mult_map_new2[] =;

static const int thresh_mult_map_split1[] =;

static const int thresh_mult_map_split2[] =;

static const int mode_check_freq_map_zn2[] =;

static const int mode_check_freq_map_vhbpred[] =;

static const int mode_check_freq_map_near2[] =;

static const int mode_check_freq_map_new1[] =;

static const int mode_check_freq_map_new2[] =;

static const int mode_check_freq_map_split1[] =;

static const int mode_check_freq_map_split2[] =;

void vp8_set_speed_features(VP8_COMP *cpi) {}
#undef GOOD
#undef RT

static void alloc_raw_frame_buffers(VP8_COMP *cpi) {}

static void dealloc_raw_frame_buffers(VP8_COMP *cpi) {}

static int vp8_alloc_partition_data(VP8_COMP *cpi) {}

void vp8_alloc_compressor_data(VP8_COMP *cpi) {}

/* Quant MOD */
static const int q_trans[] =;

int vp8_reverse_trans(int x) {}
void vp8_new_framerate(VP8_COMP *cpi, double framerate) {}

static void init_config(VP8_COMP *cpi, const VP8_CONFIG *oxcf) {}

void vp8_update_layer_contexts(VP8_COMP *cpi) {}

void vp8_change_config(VP8_COMP *cpi, const VP8_CONFIG *oxcf) {}

#ifndef M_LOG2_E
#define M_LOG2_E
#endif
#define log2f(x)

static void cal_mvsadcosts(int *mvsadcost[2]) {}

struct VP8_COMP *vp8_create_compressor(const VP8_CONFIG *oxcf) {}

void vp8_remove_compressor(VP8_COMP **comp) {}

static uint64_t calc_plane_error(unsigned char *orig, int orig_stride,
                                 unsigned char *recon, int recon_stride,
                                 unsigned int cols, unsigned int rows) {}

static void generate_psnr_packet(VP8_COMP *cpi) {}

int vp8_use_as_reference(VP8_COMP *cpi, int ref_frame_flags) {}
int vp8_update_reference(VP8_COMP *cpi, int ref_frame_flags) {}

int vp8_get_reference(VP8_COMP *cpi, enum vpx_ref_frame_type ref_frame_flag,
                      YV12_BUFFER_CONFIG *sd) {}
int vp8_set_reference(VP8_COMP *cpi, enum vpx_ref_frame_type ref_frame_flag,
                      YV12_BUFFER_CONFIG *sd) {}
int vp8_update_entropy(VP8_COMP *cpi, int update) {}

static void scale_and_extend_source(YV12_BUFFER_CONFIG *sd, VP8_COMP *cpi) {}

static int resize_key_frame(VP8_COMP *cpi) {}

static void update_alt_ref_frame_stats(VP8_COMP *cpi) {}
static void update_golden_frame_stats(VP8_COMP *cpi) {}

/* This function updates the reference frame probability estimates that
 * will be used during mode selection
 */
static void update_rd_ref_frame_probs(VP8_COMP *cpi) {}

#if !CONFIG_REALTIME_ONLY
/* 1 = key, 0 = inter */
static int decide_key_frame(VP8_COMP *cpi) {
  VP8_COMMON *cm = &cpi->common;

  int code_key_frame = 0;

  cpi->kf_boost = 0;

  if (cpi->Speed > 11) return 0;

  /* Clear down mmx registers */
  vpx_clear_system_state();

  if ((cpi->compressor_speed == 2) && (cpi->Speed >= 5) && (cpi->sf.RD == 0)) {
    double change = 1.0 *
                    abs((int)(cpi->mb.intra_error - cpi->last_intra_error)) /
                    (1 + cpi->last_intra_error);
    double change2 =
        1.0 *
        abs((int)(cpi->mb.prediction_error - cpi->last_prediction_error)) /
        (1 + cpi->last_prediction_error);
    double minerror = cm->MBs * 256;

    cpi->last_intra_error = cpi->mb.intra_error;
    cpi->last_prediction_error = cpi->mb.prediction_error;

    if (10 * cpi->mb.intra_error / (1 + cpi->mb.prediction_error) < 15 &&
        cpi->mb.prediction_error > minerror &&
        (change > .25 || change2 > .25)) {
      /*(change > 1.4 || change < .75)&& cpi->this_frame_percent_intra >
       * cpi->last_frame_percent_intra + 3*/
      return 1;
    }

    return 0;
  }

  /* If the following are true we might as well code a key frame */
  if (((cpi->this_frame_percent_intra == 100) &&
       (cpi->this_frame_percent_intra > (cpi->last_frame_percent_intra + 2))) ||
      ((cpi->this_frame_percent_intra > 95) &&
       (cpi->this_frame_percent_intra >=
        (cpi->last_frame_percent_intra + 5)))) {
    code_key_frame = 1;
  }
  /* in addition if the following are true and this is not a golden frame
   * then code a key frame Note that on golden frames there often seems
   * to be a pop in intra usage anyway hence this restriction is
   * designed to prevent spurious key frames. The Intra pop needs to be
   * investigated.
   */
  else if (((cpi->this_frame_percent_intra > 60) &&
            (cpi->this_frame_percent_intra >
             (cpi->last_frame_percent_intra * 2))) ||
           ((cpi->this_frame_percent_intra > 75) &&
            (cpi->this_frame_percent_intra >
             (cpi->last_frame_percent_intra * 3 / 2))) ||
           ((cpi->this_frame_percent_intra > 90) &&
            (cpi->this_frame_percent_intra >
             (cpi->last_frame_percent_intra + 10)))) {
    if (!cm->refresh_golden_frame) code_key_frame = 1;
  }

  return code_key_frame;
}

static void Pass1Encode(VP8_COMP *cpi) {
  vp8_set_quantizer(cpi, 26);
  vp8_first_pass(cpi);
}
#endif

#if 0
void write_cx_frame_to_file(YV12_BUFFER_CONFIG *frame, int this_frame)
{

    /* write the frame */
    FILE *yframe;
    int i;
    char filename[255];

    sprintf(filename, "cx\\y%04d.raw", this_frame);
    yframe = fopen(filename, "wb");

    for (i = 0; i < frame->y_height; ++i)
        fwrite(frame->y_buffer + i * frame->y_stride, frame->y_width, 1, yframe);

    fclose(yframe);
    sprintf(filename, "cx\\u%04d.raw", this_frame);
    yframe = fopen(filename, "wb");

    for (i = 0; i < frame->uv_height; ++i)
        fwrite(frame->u_buffer + i * frame->uv_stride, frame->uv_width, 1, yframe);

    fclose(yframe);
    sprintf(filename, "cx\\v%04d.raw", this_frame);
    yframe = fopen(filename, "wb");

    for (i = 0; i < frame->uv_height; ++i)
        fwrite(frame->v_buffer + i * frame->uv_stride, frame->uv_width, 1, yframe);

    fclose(yframe);
}
#endif

#if !CONFIG_REALTIME_ONLY
/* Function to test for conditions that indeicate we should loop
 * back and recode a frame.
 */
static int recode_loop_test(VP8_COMP *cpi, int high_limit, int low_limit, int q,
                            int maxq, int minq) {
  int force_recode = 0;
  VP8_COMMON *cm = &cpi->common;

  /* Is frame recode allowed at all
   * Yes if either recode mode 1 is selected or mode two is selcted
   * and the frame is a key frame. golden frame or alt_ref_frame
   */
  if ((cpi->sf.recode_loop == 1) ||
      ((cpi->sf.recode_loop == 2) &&
       ((cm->frame_type == KEY_FRAME) || cm->refresh_golden_frame ||
        cm->refresh_alt_ref_frame))) {
    /* General over and under shoot tests */
    if (((cpi->projected_frame_size > high_limit) && (q < maxq)) ||
        ((cpi->projected_frame_size < low_limit) && (q > minq))) {
      force_recode = 1;
    }
    /* Special Constrained quality tests */
    else if (cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY) {
      /* Undershoot and below auto cq level */
      if ((q > cpi->cq_target_quality) &&
          (cpi->projected_frame_size < ((cpi->this_frame_target * 7) >> 3))) {
        force_recode = 1;
      }
      /* Severe undershoot and between auto and user cq level */
      else if ((q > cpi->oxcf.cq_level) &&
               (cpi->projected_frame_size < cpi->min_frame_bandwidth) &&
               (cpi->active_best_quality > cpi->oxcf.cq_level)) {
        force_recode = 1;
        cpi->active_best_quality = cpi->oxcf.cq_level;
      }
    }
  }

  return force_recode;
}
#endif  // !CONFIG_REALTIME_ONLY

static void update_reference_frames(VP8_COMP *cpi) {}

static int measure_square_diff_partial(YV12_BUFFER_CONFIG *source,
                                       YV12_BUFFER_CONFIG *dest,
                                       VP8_COMP *cpi) {}

#if CONFIG_TEMPORAL_DENOISING
static void process_denoiser_mode_change(VP8_COMP *cpi) {}
#endif

void vp8_loopfilter_frame(VP8_COMP *cpi, VP8_COMMON *cm) {}
// Return 1 if frame is to be dropped. Update frame drop decimation
// counters.
int vp8_check_drop_buffer(VP8_COMP *cpi) {}

static void encode_frame_to_data_rate(VP8_COMP *cpi, size_t *size,
                                      unsigned char *dest,
                                      unsigned char *dest_end,
                                      unsigned int *frame_flags) {}
#if !CONFIG_REALTIME_ONLY
static void Pass2Encode(VP8_COMP *cpi, size_t *size, unsigned char *dest,
                        unsigned char *dest_end, unsigned int *frame_flags) {
  if (!cpi->common.refresh_alt_ref_frame) vp8_second_pass(cpi);

  encode_frame_to_data_rate(cpi, size, dest, dest_end, frame_flags);
  cpi->twopass.bits_left -= 8 * (int)(*size);

  if (!cpi->common.refresh_alt_ref_frame) {
    double two_pass_min_rate =
        (double)(cpi->oxcf.target_bandwidth *
                 cpi->oxcf.two_pass_vbrmin_section / 100);
    cpi->twopass.bits_left += (int64_t)(two_pass_min_rate / cpi->framerate);
  }
}
#endif

int vp8_receive_raw_frame(VP8_COMP *cpi, unsigned int frame_flags,
                          YV12_BUFFER_CONFIG *sd, int64_t time_stamp,
                          int64_t end_time) {}

static int frame_is_reference(const VP8_COMP *cpi) {}

int vp8_get_compressed_data(VP8_COMP *cpi, unsigned int *frame_flags,
                            size_t *size, unsigned char *dest,
                            unsigned char *dest_end, int64_t *time_stamp,
                            int64_t *time_end, int flush) {}

int vp8_get_preview_raw_frame(VP8_COMP *cpi, YV12_BUFFER_CONFIG *dest,
                              vp8_ppflags_t *flags) {}

int vp8_set_roimap(VP8_COMP *cpi, unsigned char *map, unsigned int rows,
                   unsigned int cols, int delta_q[4], int delta_lf[4],
                   unsigned int threshold[4]) {}

int vp8_set_active_map(VP8_COMP *cpi, unsigned char *map, unsigned int rows,
                       unsigned int cols) {}

int vp8_set_internal_size(VP8_COMP *cpi, VPX_SCALING_MODE horiz_mode,
                          VPX_SCALING_MODE vert_mode) {}

int vp8_calc_ss_err(YV12_BUFFER_CONFIG *source, YV12_BUFFER_CONFIG *dest) {}

int vp8_get_quantizer(VP8_COMP *cpi) {}