diff options
Diffstat (limited to 'media/libvpx/vp8/encoder/onyx_int.h')
-rw-r--r-- | media/libvpx/vp8/encoder/onyx_int.h | 751 |
1 files changed, 751 insertions, 0 deletions
diff --git a/media/libvpx/vp8/encoder/onyx_int.h b/media/libvpx/vp8/encoder/onyx_int.h new file mode 100644 index 000000000..c48e2f447 --- /dev/null +++ b/media/libvpx/vp8/encoder/onyx_int.h @@ -0,0 +1,751 @@ +/* + * 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. + */ + + +#ifndef VP8_ENCODER_ONYX_INT_H_ +#define VP8_ENCODER_ONYX_INT_H_ + +#include <stdio.h> +#include "vpx_config.h" +#include "vp8/common/onyx.h" +#include "treewriter.h" +#include "tokenize.h" +#include "vp8/common/onyxc_int.h" +#include "vp8/common/variance.h" +#include "encodemb.h" +#include "quantize.h" +#include "vp8/common/entropy.h" +#include "vp8/common/threading.h" +#include "vpx_ports/mem.h" +#include "vpx/internal/vpx_codec_internal.h" +#include "vpx/vp8.h" +#include "mcomp.h" +#include "vp8/common/findnearmv.h" +#include "lookahead.h" +#if CONFIG_TEMPORAL_DENOISING +#include "vp8/encoder/denoising.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#define MIN_GF_INTERVAL 4 +#define DEFAULT_GF_INTERVAL 7 + +#define KEY_FRAME_CONTEXT 5 + +#define MAX_LAG_BUFFERS (CONFIG_REALTIME_ONLY? 1 : 25) + +#define AF_THRESH 25 +#define AF_THRESH2 100 +#define ARF_DECAY_THRESH 12 + + +#define MIN_THRESHMULT 32 +#define MAX_THRESHMULT 512 + +#define GF_ZEROMV_ZBIN_BOOST 12 +#define LF_ZEROMV_ZBIN_BOOST 6 +#define MV_ZBIN_BOOST 4 +#define ZBIN_OQ_MAX 192 + +#if !(CONFIG_REALTIME_ONLY) +#define VP8_TEMPORAL_ALT_REF 1 +#endif + +typedef struct +{ + int kf_indicated; + unsigned int frames_since_key; + unsigned int frames_since_golden; + int filter_level; + int frames_till_gf_update_due; + int recent_ref_frame_usage[MAX_REF_FRAMES]; + + MV_CONTEXT mvc[2]; + int mvcosts[2][MVvals+1]; + +#ifdef MODE_STATS + int y_modes[5]; + int uv_modes[4]; + int b_modes[10]; + int inter_y_modes[10]; + int inter_uv_modes[4]; + int inter_b_modes[10]; +#endif + + vp8_prob ymode_prob[4], uv_mode_prob[3]; /* interframe intra mode probs */ + vp8_prob kf_ymode_prob[4], kf_uv_mode_prob[3]; /* keyframe "" */ + + int ymode_count[5], uv_mode_count[4]; /* intra MB type cts this frame */ + + int count_mb_ref_frame_usage[MAX_REF_FRAMES]; + + int this_frame_percent_intra; + int last_frame_percent_intra; + + +} CODING_CONTEXT; + +typedef struct +{ + double frame; + double intra_error; + double coded_error; + double ssim_weighted_pred_err; + double pcnt_inter; + double pcnt_motion; + double pcnt_second_ref; + double pcnt_neutral; + double MVr; + double mvr_abs; + double MVc; + double mvc_abs; + double MVrv; + double MVcv; + double mv_in_out_count; + double new_mv_count; + double duration; + double count; +} +FIRSTPASS_STATS; + +typedef struct +{ + int frames_so_far; + double frame_intra_error; + double frame_coded_error; + double frame_pcnt_inter; + double frame_pcnt_motion; + double frame_mvr; + double frame_mvr_abs; + double frame_mvc; + double frame_mvc_abs; + +} ONEPASS_FRAMESTATS; + + +typedef enum +{ + THR_ZERO1 = 0, + THR_DC = 1, + + THR_NEAREST1 = 2, + THR_NEAR1 = 3, + + THR_ZERO2 = 4, + THR_NEAREST2 = 5, + + THR_ZERO3 = 6, + THR_NEAREST3 = 7, + + THR_NEAR2 = 8, + THR_NEAR3 = 9, + + THR_V_PRED = 10, + THR_H_PRED = 11, + THR_TM = 12, + + THR_NEW1 = 13, + THR_NEW2 = 14, + THR_NEW3 = 15, + + THR_SPLIT1 = 16, + THR_SPLIT2 = 17, + THR_SPLIT3 = 18, + + THR_B_PRED = 19 +} +THR_MODES; + +typedef enum +{ + DIAMOND = 0, + NSTEP = 1, + HEX = 2 +} SEARCH_METHODS; + +typedef struct +{ + int RD; + SEARCH_METHODS search_method; + int improved_quant; + int improved_dct; + int auto_filter; + int recode_loop; + int iterative_sub_pixel; + int half_pixel_search; + int quarter_pixel_search; + int thresh_mult[MAX_MODES]; + int max_step_search_steps; + int first_step; + int optimize_coefficients; + + int use_fastquant_for_pick; + int no_skip_block4x4_search; + int improved_mv_pred; + +} SPEED_FEATURES; + +typedef struct +{ + MACROBLOCK mb; + int segment_counts[MAX_MB_SEGMENTS]; + int totalrate; +} MB_ROW_COMP; + +typedef struct +{ + TOKENEXTRA *start; + TOKENEXTRA *stop; +} TOKENLIST; + +typedef struct +{ + int ithread; + void *ptr1; + void *ptr2; +} ENCODETHREAD_DATA; +typedef struct +{ + int ithread; + void *ptr1; +} LPFTHREAD_DATA; + +enum +{ + BLOCK_16X8, + BLOCK_8X16, + BLOCK_8X8, + BLOCK_4X4, + BLOCK_16X16, + BLOCK_MAX_SEGMENTS +}; + +typedef struct +{ + /* Layer configuration */ + double framerate; + int target_bandwidth; + + /* Layer specific coding parameters */ + int64_t starting_buffer_level; + int64_t optimal_buffer_level; + int64_t maximum_buffer_size; + int64_t starting_buffer_level_in_ms; + int64_t optimal_buffer_level_in_ms; + int64_t maximum_buffer_size_in_ms; + + int avg_frame_size_for_layer; + + int64_t buffer_level; + int64_t bits_off_target; + + int64_t total_actual_bits; + int total_target_vs_actual; + + int worst_quality; + int active_worst_quality; + int best_quality; + int active_best_quality; + + int ni_av_qi; + int ni_tot_qi; + int ni_frames; + int avg_frame_qindex; + + double rate_correction_factor; + double key_frame_rate_correction_factor; + double gf_rate_correction_factor; + + int zbin_over_quant; + + int inter_frame_target; + int64_t total_byte_count; + + int filter_level; + + int last_frame_percent_intra; + + int count_mb_ref_frame_usage[MAX_REF_FRAMES]; + +} LAYER_CONTEXT; + +typedef struct VP8_COMP +{ + + DECLARE_ALIGNED(16, short, Y1quant[QINDEX_RANGE][16]); + DECLARE_ALIGNED(16, short, Y1quant_shift[QINDEX_RANGE][16]); + DECLARE_ALIGNED(16, short, Y1zbin[QINDEX_RANGE][16]); + DECLARE_ALIGNED(16, short, Y1round[QINDEX_RANGE][16]); + + DECLARE_ALIGNED(16, short, Y2quant[QINDEX_RANGE][16]); + DECLARE_ALIGNED(16, short, Y2quant_shift[QINDEX_RANGE][16]); + DECLARE_ALIGNED(16, short, Y2zbin[QINDEX_RANGE][16]); + DECLARE_ALIGNED(16, short, Y2round[QINDEX_RANGE][16]); + + DECLARE_ALIGNED(16, short, UVquant[QINDEX_RANGE][16]); + DECLARE_ALIGNED(16, short, UVquant_shift[QINDEX_RANGE][16]); + DECLARE_ALIGNED(16, short, UVzbin[QINDEX_RANGE][16]); + DECLARE_ALIGNED(16, short, UVround[QINDEX_RANGE][16]); + + DECLARE_ALIGNED(16, short, zrun_zbin_boost_y1[QINDEX_RANGE][16]); + DECLARE_ALIGNED(16, short, zrun_zbin_boost_y2[QINDEX_RANGE][16]); + DECLARE_ALIGNED(16, short, zrun_zbin_boost_uv[QINDEX_RANGE][16]); + DECLARE_ALIGNED(16, short, Y1quant_fast[QINDEX_RANGE][16]); + DECLARE_ALIGNED(16, short, Y2quant_fast[QINDEX_RANGE][16]); + DECLARE_ALIGNED(16, short, UVquant_fast[QINDEX_RANGE][16]); + + + MACROBLOCK mb; + VP8_COMMON common; + vp8_writer bc[9]; /* one boolcoder for each partition */ + + VP8_CONFIG oxcf; + + struct lookahead_ctx *lookahead; + struct lookahead_entry *source; + struct lookahead_entry *alt_ref_source; + struct lookahead_entry *last_source; + + YV12_BUFFER_CONFIG *Source; + YV12_BUFFER_CONFIG *un_scaled_source; + YV12_BUFFER_CONFIG scaled_source; + YV12_BUFFER_CONFIG *last_frame_unscaled_source; + + unsigned int frames_till_alt_ref_frame; + /* frame in src_buffers has been identified to be encoded as an alt ref */ + int source_alt_ref_pending; + /* an alt ref frame has been encoded and is usable */ + int source_alt_ref_active; + /* source of frame to encode is an exact copy of an alt ref frame */ + int is_src_frame_alt_ref; + + /* golden frame same as last frame ( short circuit gold searches) */ + int gold_is_last; + /* Alt reference frame same as last ( short circuit altref search) */ + int alt_is_last; + /* don't do both alt and gold search ( just do gold). */ + int gold_is_alt; + + YV12_BUFFER_CONFIG pick_lf_lvl_frame; + + TOKENEXTRA *tok; + unsigned int tok_count; + + + unsigned int frames_since_key; + unsigned int key_frame_frequency; + unsigned int this_key_frame_forced; + unsigned int next_key_frame_forced; + + /* Ambient reconstruction err target for force key frames */ + int ambient_err; + + unsigned int mode_check_freq[MAX_MODES]; + + int rd_baseline_thresh[MAX_MODES]; + + int RDMULT; + int RDDIV ; + + CODING_CONTEXT coding_context; + + /* Rate targetting variables */ + int64_t last_prediction_error; + int64_t last_intra_error; + + int this_frame_target; + int projected_frame_size; + int last_q[2]; /* Separate values for Intra/Inter */ + + double rate_correction_factor; + double key_frame_rate_correction_factor; + double gf_rate_correction_factor; + + unsigned int frames_since_golden; + /* Count down till next GF */ + int frames_till_gf_update_due; + + /* GF interval chosen when we coded the last GF */ + int current_gf_interval; + + /* Total bits overspent becasue of GF boost (cumulative) */ + int gf_overspend_bits; + + /* Used in the few frames following a GF to recover the extra bits + * spent in that GF + */ + int non_gf_bitrate_adjustment; + + /* Extra bits spent on key frames that need to be recovered */ + int kf_overspend_bits; + + /* Current number of bit s to try and recover on each inter frame. */ + int kf_bitrate_adjustment; + int max_gf_interval; + int baseline_gf_interval; + int active_arnr_frames; + + int64_t key_frame_count; + int prior_key_frame_distance[KEY_FRAME_CONTEXT]; + /* Current section per frame bandwidth target */ + int per_frame_bandwidth; + /* Average frame size target for clip */ + int av_per_frame_bandwidth; + /* Minimum allocation that should be used for any frame */ + int min_frame_bandwidth; + int inter_frame_target; + double output_framerate; + int64_t last_time_stamp_seen; + int64_t last_end_time_stamp_seen; + int64_t first_time_stamp_ever; + + int ni_av_qi; + int ni_tot_qi; + int ni_frames; + int avg_frame_qindex; + + int64_t total_byte_count; + + int buffered_mode; + + double framerate; + double ref_framerate; + int64_t buffer_level; + int64_t bits_off_target; + + int rolling_target_bits; + int rolling_actual_bits; + + int long_rolling_target_bits; + int long_rolling_actual_bits; + + int64_t total_actual_bits; + int total_target_vs_actual; /* debug stats */ + + int worst_quality; + int active_worst_quality; + int best_quality; + int active_best_quality; + + int cq_target_quality; + + int drop_frames_allowed; /* Are we permitted to drop frames? */ + int drop_frame; /* Drop this frame? */ + + vp8_prob frame_coef_probs [BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [ENTROPY_NODES]; + char update_probs [BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [ENTROPY_NODES]; + + unsigned int frame_branch_ct [BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [ENTROPY_NODES][2]; + + int gfu_boost; + int kf_boost; + int last_boost; + + int target_bandwidth; + struct vpx_codec_pkt_list *output_pkt_list; + +#if 0 + /* Experimental code for lagged and one pass */ + ONEPASS_FRAMESTATS one_pass_frame_stats[MAX_LAG_BUFFERS]; + int one_pass_frame_index; +#endif + + int decimation_factor; + int decimation_count; + + /* for real time encoding */ + int avg_encode_time; /* microsecond */ + int avg_pick_mode_time; /* microsecond */ + int Speed; + int compressor_speed; + + int auto_gold; + int auto_adjust_gold_quantizer; + int auto_worst_q; + int cpu_used; + int pass; + + + int prob_intra_coded; + int prob_last_coded; + int prob_gf_coded; + int prob_skip_false; + int last_skip_false_probs[3]; + int last_skip_probs_q[3]; + int recent_ref_frame_usage[MAX_REF_FRAMES]; + + int this_frame_percent_intra; + int last_frame_percent_intra; + + int ref_frame_flags; + + SPEED_FEATURES sf; + + /* Count ZEROMV on all reference frames. */ + int zeromv_count; + int lf_zeromv_pct; + + unsigned char *segmentation_map; + signed char segment_feature_data[MB_LVL_MAX][MAX_MB_SEGMENTS]; + int segment_encode_breakout[MAX_MB_SEGMENTS]; + + unsigned char *active_map; + unsigned int active_map_enabled; + + /* Video conferencing cyclic refresh mode flags. This is a mode + * designed to clean up the background over time in live encoding + * scenarious. It uses segmentation. + */ + int cyclic_refresh_mode_enabled; + int cyclic_refresh_mode_max_mbs_perframe; + int cyclic_refresh_mode_index; + int cyclic_refresh_q; + signed char *cyclic_refresh_map; + // Count on how many (consecutive) times a macroblock uses ZER0MV_LAST. + unsigned char *consec_zero_last; + // Counter that is reset when a block is checked for a mode-bias against + // ZEROMV_LASTREF. + unsigned char *consec_zero_last_mvbias; + + // Frame counter for the temporal pattern. Counter is rest when the temporal + // layers are changed dynamically (run-time change). + unsigned int temporal_pattern_counter; + // Temporal layer id. + int temporal_layer_id; + + // Measure of average squared difference between source and denoised signal. + int mse_source_denoised; + + int force_maxqp; + +#if CONFIG_MULTITHREAD + /* multithread data */ + int * mt_current_mb_col; + int mt_sync_range; + int b_multi_threaded; + int encoding_thread_count; + int b_lpf_running; + + pthread_t *h_encoding_thread; + pthread_t h_filter_thread; + + MB_ROW_COMP *mb_row_ei; + ENCODETHREAD_DATA *en_thread_data; + LPFTHREAD_DATA lpf_thread_data; + + /* events */ + sem_t *h_event_start_encoding; + sem_t h_event_end_encoding; + sem_t h_event_start_lpf; + sem_t h_event_end_lpf; +#endif + + TOKENLIST *tplist; + unsigned int partition_sz[MAX_PARTITIONS]; + unsigned char *partition_d[MAX_PARTITIONS]; + unsigned char *partition_d_end[MAX_PARTITIONS]; + + + fractional_mv_step_fp *find_fractional_mv_step; + vp8_full_search_fn_t full_search_sad; + vp8_refining_search_fn_t refining_search_sad; + vp8_diamond_search_fn_t diamond_search_sad; + vp8_variance_fn_ptr_t fn_ptr[BLOCK_MAX_SEGMENTS]; + uint64_t time_receive_data; + uint64_t time_compress_data; + uint64_t time_pick_lpf; + uint64_t time_encode_mb_row; + + int base_skip_false_prob[128]; + + FRAME_CONTEXT lfc_n; /* last frame entropy */ + FRAME_CONTEXT lfc_a; /* last alt ref entropy */ + FRAME_CONTEXT lfc_g; /* last gold ref entropy */ + + + struct twopass_rc + { + unsigned int section_intra_rating; + double section_max_qfactor; + unsigned int next_iiratio; + unsigned int this_iiratio; + FIRSTPASS_STATS total_stats; + FIRSTPASS_STATS this_frame_stats; + FIRSTPASS_STATS *stats_in, *stats_in_end, *stats_in_start; + FIRSTPASS_STATS total_left_stats; + int first_pass_done; + int64_t bits_left; + int64_t clip_bits_total; + double avg_iiratio; + double modified_error_total; + double modified_error_used; + double modified_error_left; + double kf_intra_err_min; + double gf_intra_err_min; + int frames_to_key; + int maxq_max_limit; + int maxq_min_limit; + int gf_decay_rate; + int static_scene_max_gf_interval; + int kf_bits; + /* Remaining error from uncoded frames in a gf group. */ + int gf_group_error_left; + /* Projected total bits available for a key frame group of frames */ + int64_t kf_group_bits; + /* Error score of frames still to be coded in kf group */ + int64_t kf_group_error_left; + /* Projected Bits available for a group including 1 GF or ARF */ + int64_t gf_group_bits; + /* Bits for the golden frame or ARF */ + int gf_bits; + int alt_extra_bits; + double est_max_qcorrection_factor; + } twopass; + +#if VP8_TEMPORAL_ALT_REF + YV12_BUFFER_CONFIG alt_ref_buffer; + YV12_BUFFER_CONFIG *frames[MAX_LAG_BUFFERS]; + int fixed_divide[512]; +#endif + +#if CONFIG_INTERNAL_STATS + int count; + double total_y; + double total_u; + double total_v; + double total ; + double total_sq_error; + double totalp_y; + double totalp_u; + double totalp_v; + double totalp; + double total_sq_error2; + int bytes; + double summed_quality; + double summed_weights; + unsigned int tot_recode_hits; + + + double total_ssimg_y; + double total_ssimg_u; + double total_ssimg_v; + double total_ssimg_all; + + int b_calculate_ssimg; +#endif + int b_calculate_psnr; + + /* Per MB activity measurement */ + unsigned int activity_avg; + unsigned int * mb_activity_map; + + /* Record of which MBs still refer to last golden frame either + * directly or through 0,0 + */ + unsigned char *gf_active_flags; + int gf_active_count; + + int output_partition; + + /* Store last frame's MV info for next frame MV prediction */ + int_mv *lfmv; + int *lf_ref_frame_sign_bias; + int *lf_ref_frame; + + /* force next frame to intra when kf_auto says so */ + int force_next_frame_intra; + + int droppable; + + int initial_width; + int initial_height; + +#if CONFIG_TEMPORAL_DENOISING + VP8_DENOISER denoiser; +#endif + + /* Coding layer state variables */ + unsigned int current_layer; + LAYER_CONTEXT layer_context[VPX_TS_MAX_LAYERS]; + + int64_t frames_in_layer[VPX_TS_MAX_LAYERS]; + int64_t bytes_in_layer[VPX_TS_MAX_LAYERS]; + double sum_psnr[VPX_TS_MAX_LAYERS]; + double sum_psnr_p[VPX_TS_MAX_LAYERS]; + double total_error2[VPX_TS_MAX_LAYERS]; + double total_error2_p[VPX_TS_MAX_LAYERS]; + double sum_ssim[VPX_TS_MAX_LAYERS]; + double sum_weights[VPX_TS_MAX_LAYERS]; + + double total_ssimg_y_in_layer[VPX_TS_MAX_LAYERS]; + double total_ssimg_u_in_layer[VPX_TS_MAX_LAYERS]; + double total_ssimg_v_in_layer[VPX_TS_MAX_LAYERS]; + double total_ssimg_all_in_layer[VPX_TS_MAX_LAYERS]; + +#if CONFIG_MULTI_RES_ENCODING + /* Number of MBs per row at lower-resolution level */ + int mr_low_res_mb_cols; + /* Indicate if lower-res mv info is available */ + unsigned char mr_low_res_mv_avail; +#endif + /* The frame number of each reference frames */ + unsigned int current_ref_frames[MAX_REF_FRAMES]; + // Closest reference frame to current frame. + MV_REFERENCE_FRAME closest_reference_frame; + + struct rd_costs_struct + { + int mvcosts[2][MVvals+1]; + int mvsadcosts[2][MVfpvals+1]; + int mbmode_cost[2][MB_MODE_COUNT]; + int intra_uv_mode_cost[2][MB_MODE_COUNT]; + int bmode_costs[10][10][10]; + int inter_bmode_costs[B_MODE_COUNT]; + int token_costs[BLOCK_TYPES][COEF_BANDS] + [PREV_COEF_CONTEXTS][MAX_ENTROPY_TOKENS]; + } rd_costs; +} VP8_COMP; + +void vp8_alloc_compressor_data(VP8_COMP *cpi); +int vp8_reverse_trans(int x); +void vp8_new_framerate(VP8_COMP *cpi, double framerate); +void vp8_loopfilter_frame(VP8_COMP *cpi, VP8_COMMON *cm); + +void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, + unsigned char *dest_end, unsigned long *size); + +void vp8_tokenize_mb(VP8_COMP *, MACROBLOCK *, TOKENEXTRA **); + +void vp8_set_speed_features(VP8_COMP *cpi); + +#if CONFIG_DEBUG +#define CHECK_MEM_ERROR(lval,expr) do {\ + lval = (expr); \ + if(!lval) \ + vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR,\ + "Failed to allocate "#lval" at %s:%d", \ + __FILE__,__LINE__);\ + } while(0) +#else +#define CHECK_MEM_ERROR(lval,expr) do {\ + lval = (expr); \ + if(!lval) \ + vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR,\ + "Failed to allocate "#lval);\ + } while(0) +#endif +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // VP8_ENCODER_ONYX_INT_H_ |