av1/encoder/temporal_filter.c
// Gets filter weight for blocks in temporal filtering. The weights will be
// assigned based on the motion search errors.
// NOTE: Besides assigning filter weight for the block, this function will also
// determine whether to split the entire block into 4 sub-blocks for further
// filtering.
// TODO(any): Many magic numbers are used in this function. They may be tuned
// to improve the performance.
// Inputs:
//   block_error: Motion search error for the entire block.
//   subblock_errors: Pointer to the search errors for 4 sub-blocks.
//   use_planewise_strategy: Whether to use plane-wise filtering strategy. This
//                           field will affect the filter weight for the
//                           to-filter frame.
//   is_second_arf: Whether the to-filter frame is the second ARF. This field
//                  will affect the filter weight for the to-filter frame.
//   subblock_filter_weights: Pointer to the assigned filter weight for each
//                            sub-block. If not using sub-blocks, the first
//                            element will be used for the entire block.
// Returns: Whether to use 4 sub-blocks to replace the original block.
Gets filter weight for blocks in temporal filtering. The weights will be
assigned based on the motion search errors.
NOTE: Besides assigning filter weight for the block, this function will also
determine whether to split the entire block into 4 sub-blocks for further
filtering.
TODO(any): Many magic numbers are used in this function. They may be tuned
to improve the performance.
Inputs:
block_error: Motion search error for the entire block.
subblock_errors: Pointer to the search errors for 4 sub-blocks.
use_planewise_strategy: Whether to use plane-wise filtering strategy. This
field will affect the filter weight for the
to-filter frame.
is_second_arf: Whether the to-filter frame is the second ARF. This field
will affect the filter weight for the to-filter frame.
subblock_filter_weights: Pointer to the assigned filter weight for each
sub-block. If not using sub-blocks, the first
element will be used for the entire block.
Returns: Whether to use 4 sub-blocks to replace the original block.
Gets filter weight for blocks in temporal filtering . The weights will be assigned based on the motion search errors . NOTE : Besides assigning filter weight for the block this function will also determine whether to split the entire block into 4 sub - blocks for further filtering . TODO ( any ) : Many magic numbers are used in this function . They may be tuned to improve the performance . Inputs : block_error : Motion search error for the entire block . subblock_errors : Pointer to the search errors for 4 sub - blocks . use_planewise_strategy : Whether to use plane - wise filtering strategy . This field will affect the filter weight for the to - filter frame . is_second_arf : Whether the to - filter frame is the second ARF . This field will affect the filter weight for the to - filter frame . subblock_filter_weights : Pointer to the assigned filter weight for each sub - block . If not using sub - blocks the first element will be used for the entire block . Returns : Whether to use 4 sub - blocks to replace the original block .
static int tf_get_filter_weight(const int block_error,
                                const int *subblock_errors,
                                const int use_planewise_strategy,
                                const int is_second_arf,
                                int *subblock_filter_weights) {
  if (block_error == INT_MAX) {
    const int weight = use_planewise_strategy ? TF_PLANEWISE_FILTER_WEIGHT_SCALE
                                              : is_second_arf ? 64 : 32;
    subblock_filter_weights[0] = subblock_filter_weights[1] =
        subblock_filter_weights[2] = subblock_filter_weights[3] = weight;
    return 0;
  }
  const int thresh_low = is_second_arf ? 5000 : 10000;
  const int thresh_high = is_second_arf ? 10000 : 20000;
  int min_subblock_error = INT_MAX;
  int max_subblock_error = INT_MIN;
  int sum_subblock_error = 0;
  for (int i = 0; i < 4; ++i) {
    sum_subblock_error += subblock_errors[i];
    min_subblock_error = AOMMIN(min_subblock_error, subblock_errors[i]);
    max_subblock_error = AOMMAX(max_subblock_error, subblock_errors[i]);
    subblock_filter_weights[i] =
        get_weight_by_thresh(subblock_errors[i], thresh_low, thresh_high);
  }
  if (((block_error * 15 < sum_subblock_error * 16) &&
       max_subblock_error - min_subblock_error < 12000) ||
      ((block_error * 14 < sum_subblock_error * 16) &&
       max_subblock_error - min_subblock_error < 6000)) {  
    const int weight =
        get_weight_by_thresh(block_error, thresh_low * 4, thresh_high * 4);
    subblock_filter_weights[0] = subblock_filter_weights[1] =
        subblock_filter_weights[2] = subblock_filter_weights[3] = weight;
    return 0;
  } else {  
    return 1;
  }
}
static int tf_get_filter_weight ( const int block_error , const int * subblock_errors , const int use_planewise_strategy , const int is_second_arf , int * subblock_filter_weights ) { if ( block_error == INT_MAX ) { const int weight = use_planewise_strategy ? TF_PLANEWISE_FILTER_WEIGHT_SCALE : is_second_arf ? 64 : 32 ; subblock_filter_weights [ 0 ] = subblock_filter_weights [ 1 ] = subblock_filter_weights [ 2 ] = subblock_filter_weights [ 3 ] = weight ; return 0 ; } const int thresh_low = is_second_arf ? 5000 : 10000 ; const int thresh_high = is_second_arf ? 10000 : 20000 ; int min_subblock_error = INT_MAX ; int max_subblock_error = INT_MIN ; int sum_subblock_error = 0 ; for ( int i = 0 ; i < 4 ; ++ i ) { sum_subblock_error += subblock_errors [ i ] ; min_subblock_error = AOMMIN ( min_subblock_error , subblock_errors [ i ] ) ; max_subblock_error = AOMMAX ( max_subblock_error , subblock_errors [ i ] ) ; subblock_filter_weights [ i ] = get_weight_by_thresh ( subblock_errors [ i ] , thresh_low , thresh_high ) ; } if ( ( ( block_error * 15 < sum_subblock_error * 16 ) && max_subblock_error - min_subblock_error < 12000 ) || ( ( block_error * 14 < sum_subblock_error * 16 ) && max_subblock_error - min_subblock_error < 6000 ) ) { const int weight = get_weight_by_thresh ( block_error , thresh_low * 4 , thresh_high * 4 ) ; subblock_filter_weights [ 0 ] = subblock_filter_weights [ 1 ] = subblock_filter_weights [ 2 ] = subblock_filter_weights [ 3 ] = weight ; return 0 ; } else { return 1 ; } }
Gets filter weight for blocks in temporal filtering.
Gets filter weight for blocks in temporal filtering .
// `block_error` is initialized as INT_MAX and will be overwritten after // motion search with reference frame, therefore INT_MAX can ONLY be accessed // by to-filter frame. // No split. // Do split.