// Structure to keep win flags for HORZ and VERT partition evaluations. typedefstruct {
int rect_part_win[NUM_RECT_PARTS];
} RD_RECT_PART_WIN_INFO;
enum { PICK_MODE_RD = 0, PICK_MODE_NONRD };
enum {
SB_SINGLE_PASS, // Single pass encoding: all ctxs get updated normally
SB_DRY_PASS, // First pass of multi-pass: does not update the ctxs
SB_WET_PASS // Second pass of multi-pass: finalize and update the ctx
} UENUM1BYTE(SB_MULTI_PASS_MODE);
// This struct is used to store the statistics used by sb-level multi-pass // encoding. Currently, this is only used to make a copy of the state before we // perform the first pass typedefstruct SB_FIRST_PASS_STATS {
RD_SEARCH_MACROBLOCK_CONTEXT x_ctx;
RD_COUNTS rd_count;
int split_count;
FRAME_COUNTS fc;
InterModeRdModel inter_mode_rd_models[BLOCK_SIZES_ALL];
int thresh_freq_fact[BLOCK_SIZES_ALL][MAX_MODES];
int current_qindex;
#if CONFIG_INTERNAL_STATS unsigned int mode_chosen_counts[MAX_MODES]; #endif// CONFIG_INTERNAL_STATS
} SB_FIRST_PASS_STATS;
// This structure contains block size related // variables for use in rd_pick_partition(). typedefstruct { // Half of block width to determine block edge.
int mi_step;
// Block row and column indices.
int mi_row;
int mi_col;
// Block edge row and column indices.
int mi_row_edge;
int mi_col_edge;
// Block width of current partition block.
int width;
// Block width of minimum partition size allowed.
int min_partition_size_1d;
// Flag to indicate if partition is 8x8 or higher size.
int bsize_at_least_8x8;
// Indicates edge blocks in frame.
int has_rows;
int has_cols;
// Block size of current partition.
BLOCK_SIZE bsize;
// Size of current sub-partition.
BLOCK_SIZE subsize;
// Size of split partition.
BLOCK_SIZE split_bsize2;
} PartitionBlkParams;
#if CONFIG_COLLECT_PARTITION_STATS typedefstruct PartitionTimingStats { // Tracks the number of partition decision used in the current call to \ref // av1_rd_pick_partition
int partition_decisions[EXT_PARTITION_TYPES]; // Tracks the number of partition_block searched in the current call to \ref // av1_rd_pick_partition
int partition_attempts[EXT_PARTITION_TYPES]; // Tracks the time spent on each partition search in the current call to \ref // av1_rd_pick_partition
int64_t partition_times[EXT_PARTITION_TYPES]; // Tracks the rdcost spent on each partition search in the current call to // \ref av1_rd_pick_partition
int64_t partition_rdcost[EXT_PARTITION_TYPES]; // Timer used to time the partitions. struct aom_usec_timer timer; // Whether the timer is on
int timer_is_on;
} PartitionTimingStats; #endif// CONFIG_COLLECT_PARTITION_STATS
// Structure holding state variables for partition search. typedefstruct { // Intra partitioning related info.
PartitionSearchInfo *intra_part_info;
// Parameters related to partition block size.
PartitionBlkParams part_blk_params;
// Win flags for HORZ and VERT partition evaluations.
RD_RECT_PART_WIN_INFO split_part_rect_win[SUB_PARTITIONS_SPLIT];
// RD cost for the current block of given partition type.
RD_STATS this_rdc;
// RD cost summed across all blocks of partition type.
RD_STATS sum_rdc;
// Array holding partition type cost.
int tmp_partition_cost[PARTITION_TYPES];
// Pointer to partition cost buffer
int *partition_cost;
// RD costs for different partition types.
int64_t none_rd;
int64_t split_rd[SUB_PARTITIONS_SPLIT]; // RD costs for rectangular partitions. // rect_part_rd[0][i] is the RD cost of ith partition index of PARTITION_HORZ. // rect_part_rd[1][i] is the RD cost of ith partition index of PARTITION_VERT.
int64_t rect_part_rd[NUM_RECT_PARTS][SUB_PARTITIONS_RECT];
// Flags indicating if the corresponding partition was winner or not. // Used to bypass similar blocks during AB partition evaluation.
int is_split_ctx_is_ready[2];
int is_rect_ctx_is_ready[NUM_RECT_PARTS];
// If true, skips the rest of partition evaluation at the current bsize level.
int terminate_partition_search;
// If false, skips rdopt on PARTITION_NONE.
int partition_none_allowed;
// If partition_rect_allowed[HORZ] is false, skips searching PARTITION_HORZ, // PARTITION_HORZ_A, PARTITIO_HORZ_B, PARTITION_HORZ_4. Same holds for VERT.
int partition_rect_allowed[NUM_RECT_PARTS];
// If false, skips searching rectangular partition unless some logic related // to edge detection holds.
int do_rectangular_split;
// If false, skips searching PARTITION_SPLIT.
int do_square_split;
// If true, prunes the corresponding PARTITION_HORZ/PARTITION_VERT. Note that // this does not directly affect the extended partitions, so this can be used // to prune out PARTITION_HORZ/PARTITION_VERT while still allowing rdopt of // PARTITION_HORZ_AB4, etc.
int prune_rect_part[NUM_RECT_PARTS];
// Chroma subsampling in x and y directions.
int ss_x;
int ss_y;
// Partition plane context index.
int pl_ctx_idx;
// This flag will be set if best partition is found from the search. bool found_best_partition;
// Disables all possible rectangular splits. This includes PARTITION_AB4 as they // depend on the corresponding partition_rect_allowed. static inline void av1_disable_rect_partitions(
PartitionSearchState *part_state) {
part_state->do_rectangular_split = 0;
part_state->partition_rect_allowed[HORZ] = 0;
part_state->partition_rect_allowed[VERT] = 0;
}
// Disables all possible splits so that only PARTITION_NONE *might* be allowed. static inline void av1_disable_all_splits(PartitionSearchState *part_state) {
av1_disable_square_split_partition(part_state);
av1_disable_rect_partitions(part_state);
}
static inline void av1_alloc_mb_data(const AV1_COMP *cpi, struct macroblock *mb) { const AV1_COMMON *cm = &cpi->common; const SPEED_FEATURES *sf = &cpi->sf;
if (!sf->rt_sf.use_nonrd_pick_mode) { // Memory for mb_rd_record is allocated only when use_mb_rd_hash sf is // enabled.
if (sf->rd_sf.use_mb_rd_hash)
CHECK_MEM_ERROR(cm, mb->txfm_search_info.mb_rd_record,
(MB_RD_RECORD *)aom_malloc(sizeof(MB_RD_RECORD)));
if (!frame_is_intra_only(cm))
CHECK_MEM_ERROR(
cm, mb->inter_modes_info,
(InterModesInfo *)aom_malloc(sizeof(*mb->inter_modes_info)));
}
const int max_sb_square_y = 1
<< num_pels_log2_lookup[cm->seq_params->sb_size];
CHECK_MEM_ERROR(
cm, mb->dqcoeff_buf,
(tran_low_t *)aom_memalign(32, max_sb_square_y * sizeof(tran_low_t)));
}
// This function will compute the number of reference frames to be disabled // based on selective_ref_frame speed feature. static inline unsigned int get_num_refs_to_disable( const AV1_COMP *cpi, const int *ref_frame_flags, constunsigned int *ref_display_order_hint, unsigned int cur_frame_display_index) { unsigned int num_refs_to_disable = 0;
if (cpi->sf.inter_sf.selective_ref_frame >= 3) {
num_refs_to_disable++;
if (cpi->sf.inter_sf.selective_ref_frame >= 6) { // Disable LAST2_FRAME and ALTREF2_FRAME
num_refs_to_disable += 2;
} else if (cpi->sf.inter_sf.selective_ref_frame == 5 &&
*ref_frame_flags & av1_ref_frame_flag_list[LAST2_FRAME]) { const int last2_frame_dist = av1_encoder_get_relative_dist(
ref_display_order_hint[LAST2_FRAME - LAST_FRAME],
cur_frame_display_index); // Disable LAST2_FRAME if it is a temporally distant frame
if (abs(last2_frame_dist) > 2) {
num_refs_to_disable++;
} #if !CONFIG_REALTIME_ONLY else if (is_stat_consumption_stage_twopass(cpi)) { const FIRSTPASS_STATS *const this_frame_stats =
read_one_frame_stats(&cpi->ppi->twopass, cur_frame_display_index); constdouble coded_error_per_mb = this_frame_stats->coded_error; // Disable LAST2_FRAME if the coded error of the current frame based on // first pass stats is very low.
if (coded_error_per_mb < 100.0) num_refs_to_disable++;
} #endif// CONFIG_REALTIME_ONLY
}
} return num_refs_to_disable;
}
static inline int get_max_allowed_ref_frames( const AV1_COMP *cpi, const int *ref_frame_flags, constunsigned int *ref_display_order_hint, unsigned int cur_frame_display_index) { constunsigned int max_reference_frames =
cpi->oxcf.ref_frm_cfg.max_reference_frames; constunsigned int num_refs_to_disable = get_num_refs_to_disable(
cpi, ref_frame_flags, ref_display_order_hint, cur_frame_display_index); constunsigned int max_allowed_refs_for_given_speed =
INTER_REFS_PER_FRAME - num_refs_to_disable; return AOMMIN(max_allowed_refs_for_given_speed, max_reference_frames);
}
// Enforce the number of references for each arbitrary frame based on user // options and speed. static inline void enforce_max_ref_frames(
AV1_COMP *cpi, int *ref_frame_flags, constunsigned int *ref_display_order_hint, unsigned int cur_frame_display_index) {
MV_REFERENCE_FRAME ref_frame;
int total_valid_refs = 0;
for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
if (*ref_frame_flags & av1_ref_frame_flag_list[ref_frame]) {
total_valid_refs++;
}
}
const int max_allowed_refs = get_max_allowed_ref_frames(
cpi, ref_frame_flags, ref_display_order_hint, cur_frame_display_index);
for (int i = 0; i < 4 && total_valid_refs > max_allowed_refs; ++i) { const MV_REFERENCE_FRAME ref_frame_to_disable = disable_order[i];
if (!(*ref_frame_flags & av1_ref_frame_flag_list[ref_frame_to_disable])) { continue;
}
switch (ref_frame_to_disable) { case LAST3_FRAME: *ref_frame_flags &= ~AOM_LAST3_FLAG; break; case LAST2_FRAME: *ref_frame_flags &= ~AOM_LAST2_FLAG; break; case ALTREF2_FRAME: *ref_frame_flags &= ~AOM_ALT2_FLAG; break; case BWDREF_FRAME: *ref_frame_flags &= ~AOM_GOLD_FLAG; break; default: assert(0);
}
--total_valid_refs;
}
assert(total_valid_refs <= max_allowed_refs);
}
#ifdef __cplusplus
} // extern "C" #endif
#endif// AOM_AV1_ENCODER_ENCODEFRAME_UTILS_H_
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.16 Sekunden
(vorverarbeitet am 2026-08-26)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.