• Ryan's avatar
    Fix enc/dec mismatch related delta_lf · 2d3d0cd2
    Ryan authored
    AV1 encoder's logic for handling current_delta_lf_from_base value has
    a hole, which could cause enc/dec mismatch due to deblocking filter
    level mismatch.
    
    On the encoder side, when delta_lf is used. current_delta_lf_from_base
    value is only written into the bit stream when the following condition
    is true:
    
    ((bsize != BLOCK_LARGEST || skip == 0) && super_block_upper_left)
    
    i.e., it is only written into the bit stream when current mi is the top
    left corner of a super block, and it is not skipped or block size is not
    64x64. this is applied to both INTRA and INTER blocks in write_mbmi_b().
    
    And the following code is used to handle the case when the above condition
    is not true.
    
    if (!dry_run) {
        mbmi = &xd->mi[0]->mbmi;
        if (bsize == BLOCK_64X64 && mbmi->skip == 1 && is_inter_block(mbmi) &&
            cpi->common.delta_lf_present_flag) {
          mbmi->current_delta_lf_from_base = xd->prev_delta_lf_from_base;
        }
    
    The idea is that if the above condition is not true, then the
    current_delta_lf_from_base should be reset to the previous delta lf,
    which is prev_delta_lf_frame_base.
    
    However, there is a hole in this logic. For INTRA 64x64 blocks, even it
    is skipped, the current_delta_lf_frame_base is not reset back to the
    previous delta_lf. So, in this case, decoder side won't receive any new
    delta_lf from bit stream, so it will use previous delta_lf. encoder side
    will use the new delta_lf value. this mismatch will cause final loop
    filter level calculation inconsistent in the deblocking stage and thus
    cause encoder and decoder mismatch.
    
    BUG=aomedia:826
    
    Change-Id: I90c1dcca5da106e4f3e0bcba1ed539c1cd99c370
    2d3d0cd2
encodeframe.c 283 KB