aom: update libaom to 0ec86ac7ae1e32a7e70410fa4972a655ec3670a4

This commit is contained in:
Roy Tam 2019-02-22 21:52:01 +08:00
commit eb361970c5
438 changed files with 52661 additions and 21905 deletions

View file

@ -59,7 +59,7 @@ typedef struct {
FRAME_CONTEXT fc;
} CODING_CONTEXT;
typedef enum {
enum {
// regular inter frame
REGULAR_FRAME = 0,
// alternate reference frame
@ -73,51 +73,54 @@ typedef enum {
// extra alternate reference frame
EXT_ARF_FRAME = 5,
FRAME_CONTEXT_INDEXES
} FRAME_CONTEXT_INDEX;
} UENUM1BYTE(FRAME_CONTEXT_INDEX);
typedef enum {
enum {
NORMAL = 0,
FOURFIVE = 1,
THREEFIVE = 2,
ONETWO = 3
} AOM_SCALING;
} UENUM1BYTE(AOM_SCALING);
typedef enum {
enum {
// Good Quality Fast Encoding. The encoder balances quality with the amount of
// time it takes to encode the output. Speed setting controls how fast.
GOOD
} MODE;
} UENUM1BYTE(MODE);
typedef enum {
enum {
FRAMEFLAGS_KEY = 1 << 0,
FRAMEFLAGS_GOLDEN = 1 << 1,
FRAMEFLAGS_BWDREF = 1 << 2,
// TODO(zoeliu): To determine whether a frame flag is needed for ALTREF2_FRAME
FRAMEFLAGS_ALTREF = 1 << 3,
} FRAMETYPE_FLAGS;
FRAMEFLAGS_INTRAONLY = 1 << 4,
FRAMEFLAGS_SWITCH = 1 << 5,
FRAMEFLAGS_ERROR_RESILIENT = 1 << 6,
} UENUM1BYTE(FRAMETYPE_FLAGS);
typedef enum {
enum {
NO_AQ = 0,
VARIANCE_AQ = 1,
COMPLEXITY_AQ = 2,
CYCLIC_REFRESH_AQ = 3,
AQ_MODE_COUNT // This should always be the last member of the enum
} AQ_MODE;
typedef enum {
} UENUM1BYTE(AQ_MODE);
enum {
NO_DELTA_Q = 0,
DELTA_Q_ONLY = 1,
DELTA_Q_LF = 2,
DELTAQ_MODE_COUNT // This should always be the last member of the enum
} DELTAQ_MODE;
} UENUM1BYTE(DELTAQ_MODE);
typedef enum {
enum {
RESIZE_NONE = 0, // No frame resizing allowed.
RESIZE_FIXED = 1, // All frames are coded at the specified scale.
RESIZE_RANDOM = 2, // All frames are coded at a random scale.
RESIZE_MODES
} RESIZE_MODE;
} UENUM1BYTE(RESIZE_MODE);
typedef enum {
enum {
SUPERRES_NONE = 0, // No frame superres allowed
SUPERRES_FIXED = 1, // All frames are coded at the specified scale,
// and super-resolved.
@ -126,7 +129,31 @@ typedef enum {
SUPERRES_QTHRESH = 3, // Superres scale for a frame is determined based on
// q_index
SUPERRES_MODES
} SUPERRES_MODE;
} UENUM1BYTE(SUPERRES_MODE);
typedef struct TplDepStats {
int64_t intra_cost;
int64_t inter_cost;
int64_t mc_flow;
int64_t mc_dep_cost;
int64_t mc_ref_cost;
int ref_frame_index;
int_mv mv;
} TplDepStats;
typedef struct TplDepFrame {
uint8_t is_valid;
TplDepStats *tpl_stats_ptr;
int stride;
int width;
int height;
int mi_rows;
int mi_cols;
int base_qindex;
} TplDepFrame;
#define TPL_DEP_COST_SCALE_LOG2 4
typedef struct AV1EncoderConfig {
BITSTREAM_PROFILE profile;
@ -188,6 +215,7 @@ typedef struct AV1EncoderConfig {
DELTAQ_MODE deltaq_mode;
int enable_cdef;
int enable_restoration;
int enable_obmc;
int disable_trellis_quant;
int using_qm;
int qm_y;
@ -247,6 +275,7 @@ typedef struct AV1EncoderConfig {
int min_gf_interval;
int max_gf_interval;
int gf_max_pyr_height;
int row_mt;
int tile_columns;
@ -256,10 +285,11 @@ typedef struct AV1EncoderConfig {
int tile_widths[MAX_TILE_COLS];
int tile_heights[MAX_TILE_ROWS];
int enable_tpl_model;
int max_threads;
aom_fixed_buf_t two_pass_stats_in;
struct aom_codec_pkt_list *output_pkt_list;
#if CONFIG_FP_MB_STATS
aom_fixed_buf_t firstpass_mb_stats_in;
@ -275,15 +305,12 @@ typedef struct AV1EncoderConfig {
int color_range;
int render_width;
int render_height;
aom_timing_info_type_t timing_info_type;
int timing_info_present;
aom_timing_info_t timing_info;
int decoder_model_info_present_flag;
int display_model_info_present_flag;
int buffer_removal_time_present;
aom_dec_model_info_t buffer_model;
aom_dec_model_op_parameters_t op_params[MAX_NUM_OPERATING_POINTS + 1];
aom_op_timing_info_t op_frame_timing[MAX_NUM_OPERATING_POINTS + 1];
int film_grain_test_vector;
const char *film_grain_table_filename;
@ -291,18 +318,36 @@ typedef struct AV1EncoderConfig {
aom_superblock_size_t superblock_size;
unsigned int large_scale_tile;
unsigned int single_tile_decoding;
int monochrome;
uint8_t monochrome;
unsigned int full_still_picture_hdr;
int enable_dual_filter;
unsigned int motion_vector_unit_test;
const cfg_options_t *cfg;
int enable_rect_partitions;
int enable_intra_edge_filter;
int enable_tx64;
int enable_order_hint;
int enable_jnt_comp;
int enable_dist_wtd_comp;
int enable_ref_frame_mvs;
unsigned int max_reference_frames;
unsigned int allow_ref_frame_mvs;
int enable_masked_comp;
int enable_interintra_comp;
int enable_smooth_interintra;
int enable_diff_wtd_comp;
int enable_interinter_wedge;
int enable_interintra_wedge;
int enable_global_motion;
int enable_warped_motion;
int allow_warped_motion;
int enable_filter_intra;
int enable_smooth_intra;
int enable_paeth_intra;
int enable_cfl_intra;
int enable_superres;
int enable_palette;
int enable_intrabc;
int enable_angle_delta;
unsigned int save_as_annexb;
#if CONFIG_DENOISE
@ -312,6 +357,11 @@ typedef struct AV1EncoderConfig {
unsigned int chroma_subsampling_x;
unsigned int chroma_subsampling_y;
int reduced_tx_type_set;
int use_intra_dct_only;
int use_inter_dct_only;
int quant_b_adapt;
int border_in_pixels;
} AV1EncoderConfig;
static INLINE int is_lossless_requested(const AV1EncoderConfig *cfg) {
@ -404,7 +454,6 @@ typedef struct FRAME_COUNTS {
[SWITCHABLE_FILTERS];
} FRAME_COUNTS;
#if CONFIG_COLLECT_INTER_MODE_RD_STATS
#define INTER_MODE_RD_DATA_OVERALL_SIZE 6400
typedef struct {
@ -439,22 +488,37 @@ typedef struct inter_modes_info {
int64_t est_rd_arr[MAX_INTER_MODES];
RdIdxPair rd_idx_pair_arr[MAX_INTER_MODES];
} InterModesInfo;
// Encoder row synchronization
typedef struct AV1RowMTSyncData {
#if CONFIG_MULTITHREAD
pthread_mutex_t *mutex_;
pthread_cond_t *cond_;
#endif
// Allocate memory to store the sb/mb block index in each row.
int *cur_col;
int sync_range;
int rows;
} AV1RowMTSync;
typedef struct AV1RowMTInfo {
int current_mi_row;
int num_threads_working;
} AV1RowMTInfo;
// TODO(jingning) All spatially adaptive variables should go to TileDataEnc.
typedef struct TileDataEnc {
TileInfo tile_info;
int thresh_freq_fact[BLOCK_SIZES_ALL][MAX_MODES];
int mode_map[BLOCK_SIZES_ALL][MAX_MODES];
int m_search_count;
int ex_search_count;
CFL_CTX cfl;
DECLARE_ALIGNED(16, FRAME_CONTEXT, tctx);
FRAME_CONTEXT *row_ctx;
uint8_t allow_update_cdf;
#if CONFIG_COLLECT_INTER_MODE_RD_STATS
InterModeRdModel inter_mode_rd_models[BLOCK_SIZES_ALL];
InterModesInfo inter_modes_info;
#endif
AV1RowMTSync row_mt_sync;
AV1RowMTInfo row_mt_info;
} TileDataEnc;
typedef struct {
@ -463,6 +527,13 @@ typedef struct {
unsigned int count;
} TOKENLIST;
typedef struct MultiThreadHandle {
int allocated_tile_rows;
int allocated_tile_cols;
int allocated_sb_rows;
int thread_id_to_tile_id[MAX_NUM_THREADS]; // Mapping of threads to tiles
} MultiThreadHandle;
typedef struct RD_COUNTS {
int64_t comp_pred_diff[REFERENCE_MODES];
// Stores number of 4x4 blocks using global motion per reference frame.
@ -477,6 +548,10 @@ typedef struct ThreadData {
FRAME_COUNTS *counts;
PC_TREE *pc_tree;
PC_TREE *pc_root[MAX_MIB_SIZE_LOG2 - MIN_MIB_SIZE_LOG2 + 1];
tran_low_t *tree_coeff_buf[MAX_MB_PLANE];
tran_low_t *tree_qcoeff_buf[MAX_MB_PLANE];
tran_low_t *tree_dqcoeff_buf[MAX_MB_PLANE];
InterModesInfo *inter_modes_info;
uint32_t *hash_value_buffer[2][2];
int32_t *wsrc_buf;
int32_t *mask_buf;
@ -485,7 +560,8 @@ typedef struct ThreadData {
PALETTE_BUFFER *palette_buffer;
CONV_BUF_TYPE *tmp_conv_dst;
uint8_t *tmp_obmc_bufs[2];
int intrabc_used_this_tile;
int intrabc_used;
FRAME_CONTEXT *tctx;
} ThreadData;
struct EncWorkerData;
@ -498,13 +574,13 @@ typedef struct ActiveMap {
#if CONFIG_INTERNAL_STATS
// types of stats
typedef enum {
enum {
STAT_Y,
STAT_U,
STAT_V,
STAT_ALL,
NUM_STAT_TYPES // This should always be the last member of the enum
} StatType;
} UENUM1BYTE(StatType);
typedef struct IMAGE_STAT {
double stat[NUM_STAT_TYPES];
@ -517,10 +593,14 @@ typedef struct {
YV12_BUFFER_CONFIG buf;
} EncRefCntBuffer;
typedef struct TileBufferEnc {
uint8_t *data;
size_t size;
} TileBufferEnc;
#if CONFIG_COLLECT_PARTITION_STATS
typedef struct PartitionStats {
int partition_decisions[6][EXT_PARTITION_TYPES];
int partition_attempts[6][EXT_PARTITION_TYPES];
int partition_redo;
} PartitionStats;
#endif
typedef struct AV1_COMP {
QUANTS quants;
@ -545,6 +625,9 @@ typedef struct AV1_COMP {
YV12_BUFFER_CONFIG *unscaled_last_source;
YV12_BUFFER_CONFIG scaled_last_source;
TplDepFrame tpl_stats[MAX_LAG_BUFFERS];
YV12_BUFFER_CONFIG *tpl_recon_frames[INTER_REFS_PER_FRAME + 1];
// For a still frame, this flag is set to 1 to skip partition search.
int partition_search_skippable_frame;
double csm_rate_array[32];
@ -553,23 +636,41 @@ typedef struct AV1_COMP {
int rate_index;
hash_table *previous_hash_table;
int previous_index;
int cur_poc; // DebugInfo
unsigned int row_mt;
int scaled_ref_idx[REF_FRAMES];
int ref_fb_idx[REF_FRAMES];
int refresh_fb_idx; // ref frame buffer index to refresh
RefCntBuffer *scaled_ref_buf[INTER_REFS_PER_FRAME];
int last_show_frame_buf_idx; // last show frame buffer index
RefCntBuffer *last_show_frame_buf; // last show frame buffer
// refresh_*_frame are boolean flags. If 'refresh_xyz_frame' is true, then
// after the current frame is encoded, the XYZ reference frame gets refreshed
// (updated) to be the current frame.
//
// Special case: 'refresh_last_frame' specifies that:
// - LAST_FRAME reference should be updated to be the current frame (as usual)
// - Also, LAST2_FRAME and LAST3_FRAME references are implicitly updated to be
// the two past reference frames just before LAST_FRAME that are available.
//
// Note: Usually at most one of these refresh flags is true at a time.
// But a key-frame is special, for which all the flags are true at once.
int refresh_last_frame;
int refresh_golden_frame;
int refresh_bwd_ref_frame;
int refresh_alt2_ref_frame;
int refresh_alt_ref_frame;
#if USE_SYMM_MULTI_LAYER
// For each type of reference frame, this contains the index of a reference
// frame buffer for a reference frame of the same type. We use this to
// choose our primary reference frame (which is the most recent reference
// frame of the same type as the current frame).
int fb_of_context_type[REF_FRAMES];
// When true, a new rule for backward (future) reference frames is in effect:
// - BWDREF_FRAME is always the closest future frame available
// - ALTREF2_FRAME is always the 2nd closest future frame available
// - 'refresh_bwd_ref_frame' flag is used for updating both the BWDREF_FRAME
// and ALTREF2_FRAME. ('refresh_alt2_ref_frame' flag is irrelevant).
int new_bwdref_update_rule;
#endif
int ext_refresh_frame_flags_pending;
int ext_refresh_last_frame;
@ -608,9 +709,10 @@ typedef struct AV1_COMP {
RATE_CONTROL rc;
double framerate;
// NOTE(zoeliu): Any inter frame allows maximum of REF_FRAMES inter
// references; Plus the currently coded frame itself, it is needed to allocate
// sufficient space to the size of the maximum possible number of frames.
// Relevant for an inter frame.
// - Index '0' corresponds to the values for the currently coded frame.
// - Indices LAST_FRAME ... EXTREF_FRAMES are used to store values for all the
// possible inter reference frames.
int interp_filter_selected[REF_FRAMES + 1][SWITCHABLE];
struct aom_codec_pkt_list *output_pkt_list;
@ -620,14 +722,15 @@ typedef struct AV1_COMP {
int static_mb_pct; // % forced skip mbs by segmentation
int ref_frame_flags;
int ext_ref_frame_flags;
RATE_FACTOR_LEVEL frame_rf_level[FRAME_BUFFERS];
// speed is passed as a per-frame parameter into the encoder
int speed;
// sf contains fine-grained config set internally based on speed
SPEED_FEATURES sf;
unsigned int max_mv_magnitude;
int mv_step_param;
int allow_comp_inter_inter;
int all_one_sided_refs;
uint8_t *segmentation_map;
@ -641,7 +744,6 @@ typedef struct AV1_COMP {
uint64_t time_receive_data;
uint64_t time_compress_data;
uint64_t time_pick_lpf;
uint64_t time_encode_sb_row;
#if CONFIG_FP_MB_STATS
int use_fp_mb_stats;
@ -680,6 +782,9 @@ typedef struct AV1_COMP {
Metrics metrics;
#endif
int b_calculate_psnr;
#if CONFIG_SPEED_STATS
unsigned int tx_search_count;
#endif // CONFIG_SPEED_STATS
int droppable;
@ -705,15 +810,11 @@ typedef struct AV1_COMP {
int allocated_tiles; // Keep track of memory allocated for tiles.
TOKENEXTRA *tile_tok[MAX_TILE_ROWS][MAX_TILE_COLS];
unsigned int tok_count[MAX_TILE_ROWS][MAX_TILE_COLS];
TOKENLIST *tplist[MAX_TILE_ROWS][MAX_TILE_COLS];
TileBufferEnc tile_buffers[MAX_TILE_ROWS][MAX_TILE_COLS];
int resize_state;
int resize_avg_qp;
int resize_buffer_underflow;
int resize_count;
// Sequence parameters have been transmitted already and locked
// or not. Once locked av1_change_config cannot change the seq
@ -727,14 +828,12 @@ typedef struct AV1_COMP {
int num_workers;
AVxWorker *workers;
struct EncWorkerData *tile_thr_data;
int refresh_frame_mask;
int existing_fb_idx_to_show;
int is_arf_filter_off[MAX_EXT_ARFS + 1];
int num_extra_arfs;
int arf_pos_in_gf[MAX_EXT_ARFS + 1];
int arf_pos_for_ovrly[MAX_EXT_ARFS + 1];
int global_motion_search_done;
tran_low_t *tcoeff_buf[MAX_MB_PLANE];
int extra_arf_allowed;
// A flag to indicate if intrabc is ever used in current frame.
int intrabc_used;
@ -743,10 +842,16 @@ typedef struct AV1_COMP {
int dv_joint_cost[MV_JOINTS];
int has_lossless_segment;
// For frame refs short signaling:
// A mapping of each reference frame from its encoder side value to the
// decoder side value obtained following the short signaling procedure.
int ref_conv[REF_FRAMES];
// Factors to control gating of compound type selection based on best
// approximate rd so far
int max_comp_type_rd_threshold_mul;
int max_comp_type_rd_threshold_div;
unsigned int tx_domain_dist_threshold;
// Factor to control R-D optimization of coeffs based on block
// mse.
unsigned int coeff_opt_dist_threshold;
AV1LfSync lf_row_sync;
AV1LrSync lr_row_sync;
@ -760,8 +865,50 @@ typedef struct AV1_COMP {
// Set as 1 for monochrome and 3 for other color formats
int default_interp_skip_flags;
int preserve_arf_as_gld;
MultiThreadHandle multi_thread_ctxt;
void (*row_mt_sync_read_ptr)(AV1RowMTSync *const, int, int);
void (*row_mt_sync_write_ptr)(AV1RowMTSync *const, int, int, const int);
#if CONFIG_MULTITHREAD
pthread_mutex_t *row_mt_mutex_;
#endif
// Set if screen content is set or relevant tools are enabled
int is_screen_content_type;
#if CONFIG_COLLECT_PARTITION_STATS
PartitionStats partition_stats;
#endif
} AV1_COMP;
typedef struct {
YV12_BUFFER_CONFIG *source;
YV12_BUFFER_CONFIG *last_source;
int64_t ts_duration;
} EncodeFrameInput;
// EncodeFrameParams contains per-frame encoding parameters decided upon by
// av1_encode_strategy() and passed down to av1_encode()
struct EncodeFrameParams {
int error_resilient_mode;
FRAME_TYPE frame_type;
int primary_ref_frame;
int order_offset;
int show_frame;
// This is a bitmask of which reference slots can be used in this frame
int ref_frame_flags;
// Speed level to use for this frame: Bigger number means faster.
int speed;
unsigned int *frame_flags;
};
typedef struct EncodeFrameParams EncodeFrameParams;
// EncodeFrameResults contains information about the result of encoding a
// single frame
typedef struct {
size_t size; // Size of resulting bitstream
} EncodeFrameResults;
// Must not be called more than once.
void av1_initialize_enc(void);
@ -782,6 +929,11 @@ int av1_get_compressed_data(AV1_COMP *cpi, unsigned int *frame_flags,
int64_t *time_end, int flush,
const aom_rational_t *timebase);
int av1_encode(AV1_COMP *const cpi, uint8_t *const dest,
const EncodeFrameInput *const frame_input,
const EncodeFrameParams *const frame_params,
EncodeFrameResults *const frame_results);
int av1_get_preview_raw_frame(AV1_COMP *cpi, YV12_BUFFER_CONFIG *dest);
int av1_get_last_show_frame(AV1_COMP *cpi, YV12_BUFFER_CONFIG *frame);
@ -792,12 +944,12 @@ aom_codec_err_t av1_copy_new_frame_enc(AV1_COMMON *cm,
int av1_use_as_reference(AV1_COMP *cpi, int ref_frame_flags);
void av1_update_reference(AV1_COMP *cpi, int ref_frame_flags);
int av1_copy_reference_enc(AV1_COMP *cpi, int idx, YV12_BUFFER_CONFIG *sd);
int av1_set_reference_enc(AV1_COMP *cpi, int idx, YV12_BUFFER_CONFIG *sd);
void av1_set_frame_size(AV1_COMP *cpi, int width, int height);
int av1_update_entropy(AV1_COMP *cpi, int update);
int av1_set_active_map(AV1_COMP *cpi, unsigned char *map, int rows, int cols);
@ -811,59 +963,62 @@ int av1_get_quantizer(struct AV1_COMP *cpi);
int av1_convert_sect5obus_to_annexb(uint8_t *buffer, size_t *input_size);
int64_t timebase_units_to_ticks(const aom_rational_t *timebase, int64_t n);
int64_t ticks_to_timebase_units(const aom_rational_t *timebase, int64_t n);
// av1 uses 10,000,000 ticks/second as time stamp
#define TICKS_PER_SEC 10000000LL
static INLINE int64_t timebase_units_to_ticks(const aom_rational_t *timebase,
int64_t n) {
return n * TICKS_PER_SEC * timebase->num / timebase->den;
}
static INLINE int64_t ticks_to_timebase_units(const aom_rational_t *timebase,
int64_t n) {
const int64_t round = TICKS_PER_SEC * timebase->num / 2 - 1;
return (n * timebase->den + round) / timebase->num / TICKS_PER_SEC;
}
static INLINE int frame_is_kf_gf_arf(const AV1_COMP *cpi) {
return frame_is_intra_only(&cpi->common) || cpi->refresh_alt_ref_frame ||
(cpi->refresh_golden_frame && !cpi->rc.is_src_frame_alt_ref);
}
static INLINE int get_ref_frame_map_idx(const AV1_COMP *cpi,
MV_REFERENCE_FRAME ref_frame) {
return (ref_frame >= 1) ? cpi->ref_fb_idx[ref_frame - 1] : INVALID_IDX;
}
static INLINE int get_ref_frame_buf_idx(const AV1_COMP *cpi,
MV_REFERENCE_FRAME ref_frame) {
const AV1_COMMON *const cm = &cpi->common;
const int map_idx = get_ref_frame_map_idx(cpi, ref_frame);
return (map_idx != INVALID_IDX) ? cm->ref_frame_map[map_idx] : INVALID_IDX;
}
// TODO(huisu@google.com, youzhou@microsoft.com): enable hash-me for HBD.
static INLINE int av1_use_hash_me(const AV1_COMMON *const cm) {
return cm->allow_screen_content_tools;
}
static INLINE hash_table *av1_get_ref_frame_hash_map(
const AV1_COMP *cpi, MV_REFERENCE_FRAME ref_frame) {
const AV1_COMMON *const cm = &cpi->common;
const int buf_idx = get_ref_frame_buf_idx(cpi, ref_frame);
return buf_idx != INVALID_IDX
? &cm->buffer_pool->frame_bufs[buf_idx].hash_table
: NULL;
const AV1_COMMON *cm, MV_REFERENCE_FRAME ref_frame) {
const int map_idx = get_ref_frame_map_idx(cm, ref_frame);
RefCntBuffer *buf =
(map_idx != INVALID_IDX) ? cm->ref_frame_map[map_idx] : NULL;
return buf ? &buf->hash_table : NULL;
}
static INLINE YV12_BUFFER_CONFIG *get_ref_frame_buffer(
const AV1_COMP *cpi, MV_REFERENCE_FRAME ref_frame) {
const AV1_COMMON *const cm = &cpi->common;
const int buf_idx = get_ref_frame_buf_idx(cpi, ref_frame);
return buf_idx != INVALID_IDX ? &cm->buffer_pool->frame_bufs[buf_idx].buf
: NULL;
static INLINE const YV12_BUFFER_CONFIG *get_ref_frame_yv12_buf(
const AV1_COMMON *const cm, MV_REFERENCE_FRAME ref_frame) {
const RefCntBuffer *const buf = get_ref_frame_buf(cm, ref_frame);
return buf != NULL ? &buf->buf : NULL;
}
static INLINE int enc_is_ref_frame_buf(AV1_COMP *cpi, RefCntBuffer *frame_buf) {
static INLINE int enc_is_ref_frame_buf(const AV1_COMMON *const cm,
const RefCntBuffer *const frame_buf) {
MV_REFERENCE_FRAME ref_frame;
AV1_COMMON *const cm = &cpi->common;
for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
const int buf_idx = get_ref_frame_buf_idx(cpi, ref_frame);
if (buf_idx == INVALID_IDX) continue;
if (frame_buf == &cm->buffer_pool->frame_bufs[buf_idx]) break;
const RefCntBuffer *const buf = get_ref_frame_buf(cm, ref_frame);
if (buf == NULL) continue;
if (frame_buf == buf) break;
}
return (ref_frame <= ALTREF_FRAME);
}
static INLINE void alloc_frame_mvs(AV1_COMMON *const cm, RefCntBuffer *buf) {
assert(buf != NULL);
ensure_mv_buffer(buf, cm);
buf->width = cm->width;
buf->height = cm->height;
}
// Token buffer is only used for palette tokens.
static INLINE unsigned int get_token_alloc(int mb_rows, int mb_cols,
int sb_size_log2,
@ -919,10 +1074,10 @@ static INLINE int is_altref_enabled(const AV1_COMP *const cpi) {
static INLINE void set_ref_ptrs(const AV1_COMMON *cm, MACROBLOCKD *xd,
MV_REFERENCE_FRAME ref0,
MV_REFERENCE_FRAME ref1) {
xd->block_refs[0] =
&cm->frame_refs[ref0 >= LAST_FRAME ? ref0 - LAST_FRAME : 0];
xd->block_refs[1] =
&cm->frame_refs[ref1 >= LAST_FRAME ? ref1 - LAST_FRAME : 0];
xd->block_ref_scale_factors[0] =
get_ref_scale_factors_const(cm, ref0 >= LAST_FRAME ? ref0 : 1);
xd->block_ref_scale_factors[1] =
get_ref_scale_factors_const(cm, ref1 >= LAST_FRAME ? ref1 : 1);
}
static INLINE int get_chessboard_index(int frame_index) {
@ -935,20 +1090,10 @@ static INLINE int *cond_cost_list(const struct AV1_COMP *cpi, int *cost_list) {
void av1_new_framerate(AV1_COMP *cpi, double framerate);
void av1_setup_frame_size(AV1_COMP *cpi);
#define LAYER_IDS_TO_IDX(sl, tl, num_tl) ((sl) * (num_tl) + (tl))
// Update up-sampled reference frame index.
static INLINE void uref_cnt_fb(EncRefCntBuffer *ubufs, int *uidx,
int new_uidx) {
const int ref_index = *uidx;
if (ref_index >= 0 && ubufs[ref_index].ref_count > 0)
ubufs[ref_index].ref_count--;
*uidx = new_uidx;
ubufs[new_uidx].ref_count++;
}
// Returns 1 if a frame is scaled and 0 otherwise.
static INLINE int av1_resize_scaled(const AV1_COMMON *cm) {
return !(cm->superres_upscaled_width == cm->render_width &&
@ -963,8 +1108,8 @@ static INLINE int av1_frame_scaled(const AV1_COMMON *cm) {
// frame. An exception can be made for a forward keyframe since it has no
// previous dependencies.
static INLINE int encode_show_existing_frame(const AV1_COMMON *cm) {
return cm->show_existing_frame &&
(!cm->error_resilient_mode || cm->frame_type == KEY_FRAME);
return cm->show_existing_frame && (!cm->error_resilient_mode ||
cm->current_frame.frame_type == KEY_FRAME);
}
// Returns a Sequence Header OBU stored in an aom_fixed_buf_t, or NULL upon
@ -978,6 +1123,52 @@ static INLINE int encode_show_existing_frame(const AV1_COMMON *cm) {
// field.
aom_fixed_buf_t *av1_get_global_headers(AV1_COMP *cpi);
#if CONFIG_COLLECT_PARTITION_STATS
static INLINE void av1_print_partition_stats(PartitionStats *part_stats) {
FILE *f = fopen("partition_stats.csv", "w");
if (!f) {
return;
}
fprintf(f, "bsize,redo,");
for (int part = 0; part < EXT_PARTITION_TYPES; part++) {
fprintf(f, "decision_%d,", part);
}
for (int part = 0; part < EXT_PARTITION_TYPES; part++) {
fprintf(f, "attempt_%d,", part);
}
fprintf(f, "\n");
const int bsizes[6] = { 128, 64, 32, 16, 8, 4 };
for (int bsize_idx = 0; bsize_idx < 6; bsize_idx++) {
fprintf(f, "%d,%d,", bsizes[bsize_idx], part_stats->partition_redo);
for (int part = 0; part < EXT_PARTITION_TYPES; part++) {
fprintf(f, "%d,", part_stats->partition_decisions[bsize_idx][part]);
}
for (int part = 0; part < EXT_PARTITION_TYPES; part++) {
fprintf(f, "%d,", part_stats->partition_attempts[bsize_idx][part]);
}
fprintf(f, "\n");
}
fclose(f);
}
static INLINE int av1_get_bsize_idx_for_part_stats(BLOCK_SIZE bsize) {
assert(bsize == BLOCK_128X128 || bsize == BLOCK_64X64 ||
bsize == BLOCK_32X32 || bsize == BLOCK_16X16 || bsize == BLOCK_8X8);
switch (bsize) {
case BLOCK_128X128: return 0;
case BLOCK_64X64: return 1;
case BLOCK_32X32: return 2;
case BLOCK_16X16: return 3;
case BLOCK_8X8: return 4;
case BLOCK_4X4: return 5;
default: assert(0 && "Invalid bsize for partition_stats."); return -1;
}
}
#endif
#ifdef __cplusplus
} // extern "C"
#endif