美文网首页
av1代码学习8---av1_encode_frame()

av1代码学习8---av1_encode_frame()

作者: 青吟乐 | 来源:发表于2020-06-23 11:11 被阅读0次

    1,函数功能

    主要进行参考帧相关设置后进行编码调用encode_frame_internal(cpi)进行编码

    2,代码学习

    void av1_encode_frame(AV1_COMP *cpi) {
      AV1_COMMON *const cm = &cpi->common;
      CurrentFrame *const current_frame = &cm->current_frame;
      const int num_planes = av1_num_planes(cm);
      // Indicates whether or not to use a default reduced set for ext-tx
      // rather than the potential full set of 16 transforms
      cm->reduced_tx_set_used = cpi->oxcf.reduced_tx_type_set;
    
      // Make sure segment_id is no larger than last_active_segid.
      if (cm->seg.enabled && cm->seg.update_map) {
        const int mi_rows = cm->mi_rows;
        const int mi_cols = cm->mi_cols;
        const int last_active_segid = cm->seg.last_active_segid;
        uint8_t *map = cpi->segmentation_map;
        for (int mi_row = 0; mi_row < mi_rows; ++mi_row) {
          for (int mi_col = 0; mi_col < mi_cols; ++mi_col) {
            map[mi_col] = AOMMIN(map[mi_col], last_active_segid);
          }
          map += mi_cols;
        }
      }
    
      av1_setup_frame_buf_refs(cm);//参考帧
      enforce_max_ref_frames(cpi);//强制参考帧引用数
      set_rel_frame_dist(cpi);//设置参考帧w.r.t.与当前帧的相对距离
      av1_setup_frame_sign_bias(cm);//设置标志位偏移量
    
    #if CHECK_PRECOMPUTED_REF_FRAME_MAP
      GF_GROUP *gf_group = &cpi->gf_group;
      // TODO(yuec): The check is disabled on OVERLAY frames for now, because info
      // in cpi->gf_group has been refreshed for the next GOP when the check is
      // performed for OVERLAY frames. Since we have not support inter-GOP ref
      // frame map computation, the precomputed ref map for an OVERLAY frame is all
      // -1 at this point (although it is meaning before gf_group is refreshed).
      if (!frame_is_intra_only(cm) && gf_group->index != 0) {
        const RefCntBuffer *const golden_buf = get_ref_frame_buf(cm, GOLDEN_FRAME);
    
        if (golden_buf) {
          const int golden_order_hint = golden_buf->order_hint;
    
          for (int ref = LAST_FRAME; ref < EXTREF_FRAME; ++ref) {
            const RefCntBuffer *const buf = get_ref_frame_buf(cm, ref);
            const int ref_disp_idx_precomputed =
                gf_group->ref_frame_disp_idx[gf_group->index][ref - LAST_FRAME];
    
            (void)ref_disp_idx_precomputed;
    
            if (buf != NULL) {
              const int ref_disp_idx =
                  get_relative_dist(&cm->seq_params.order_hint_info,
                                    buf->order_hint, golden_order_hint);
    
              if (ref_disp_idx >= 0)
                assert(ref_disp_idx == ref_disp_idx_precomputed);
              else
                assert(ref_disp_idx_precomputed == -1);
            } else {
              assert(ref_disp_idx_precomputed == -1);
            }
          }
        }
      }
    #endif
    
    #if CONFIG_MISMATCH_DEBUG
      mismatch_reset_frame(num_planes);
    #else
      (void)num_planes;
    #endif
    
      if (cpi->sf.frame_parameter_update) {//s帧,帧级编码参数
        int i;
        RD_OPT *const rd_opt = &cpi->rd;
        RD_COUNTS *const rdc = &cpi->td.rd_counts;
    
        // This code does a single RD pass over the whole frame assuming
        // either compound, single or hybrid prediction as per whatever has
        // worked best for that type of frame in the past.
        // It also predicts whether another coding mode would have worked
        // better than this coding mode. If that is the case, it remembers
        // that for subsequent frames.
        // It does the same analysis for transform size selection also.
        //这段代码在整个帧上执行一次RD传递,假设根据过去对该类型帧最有效的方法进行复合、单一或混合预测。
        //它还预测了另一种编码模式是否比这种编码模式工作得更好。
        //如果是这样的话,它会记住后面的帧。它对变换大小的选择也做同样的分析。
        // TODO(zoeliu): To investigate whether a frame_type other than
        // INTRA/ALTREF/GOLDEN/LAST needs to be specified seperately.
        const MV_REFERENCE_FRAME frame_type = get_frame_type(cpi);
        int64_t *const mode_thrs = rd_opt->prediction_type_threshes[frame_type];
        const int is_alt_ref = frame_type == ALTREF_FRAME;
    
        /* prediction (compound, single or hybrid) mode selection */
        // NOTE: "is_alt_ref" is true only for OVERLAY/INTNL_OVERLAY frames
        /*预测模式选择*/
        if (is_alt_ref || frame_is_intra_only(cm))//只帧内单独预测,否则就要进行选择
          current_frame->reference_mode = SINGLE_REFERENCE;
        else
          current_frame->reference_mode = REFERENCE_MODE_SELECT;
    
        cm->interp_filter = SWITCHABLE;
        if (cm->large_scale_tile) cm->interp_filter = EIGHTTAP_REGULAR;
    
        cm->switchable_motion_mode = 1;//运动模式选择1
    
        rdc->compound_ref_used_flag = 0;//字面意思:复合参考帧使用标志?
        rdc->skip_mode_used_flag = 0;//跳过某些模式的标志
    
        encode_frame_internal(cpi);//编码入口
    
        for (i = 0; i < REFERENCE_MODES; ++i)
          mode_thrs[i] = (mode_thrs[i] + rdc->comp_pred_diff[i] / cm->MBs) / 2;
        //参考模式
        if (current_frame->reference_mode == REFERENCE_MODE_SELECT) {
          // Use a flag that includes 4x4 blocks
          if (rdc->compound_ref_used_flag == 0) {
            current_frame->reference_mode = SINGLE_REFERENCE;
    #if CONFIG_ENTROPY_STATS
            av1_zero(cpi->td.counts->comp_inter);
    #endif  // CONFIG_ENTROPY_STATS
          }
        }
        // Re-check on the skip mode status as reference mode may have been changed.
        // 重新检查跳过模式状态,因为参考模式可能已更改。
        SkipModeInfo *const skip_mode_info = &current_frame->skip_mode_info;
        if (frame_is_intra_only(cm) ||
            current_frame->reference_mode == SINGLE_REFERENCE) {
          skip_mode_info->skip_mode_allowed = 0;
          skip_mode_info->skip_mode_flag = 0;
        }
        if (skip_mode_info->skip_mode_flag && rdc->skip_mode_used_flag == 0)
          skip_mode_info->skip_mode_flag = 0;
    
        if (!cm->large_scale_tile) {
          if (cm->tx_mode == TX_MODE_SELECT && cpi->td.mb.txb_split_count == 0)
            cm->tx_mode = TX_MODE_LARGEST;
        }
      } else {
        encode_frame_internal(cpi);
      }
    }
    

    相关文章

      网友评论

          本文标题:av1代码学习8---av1_encode_frame()

          本文链接:https://www.haomeiwen.com/subject/xcicfktx.html