美文网首页
av1代码学习4---denoise_and_encode()

av1代码学习4---denoise_and_encode()

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

1,函数功能

函数从名称上来看就可以得到是要抑制噪声再进行编码,顺序一般为先进行噪声估算,根据噪声估算的结果得到一个noise_level,根据这个noise_level和其他的属性(编码次数,帧类型,帧用途等)进行av1_temporal_filter时空域的滤波,然后进入av1_encode进行下一步编码

2,代码学习

// Apply temporal filtering to key frames and encode the filtered frame.
// If the current frame is not key frame, this function is identical to
// av1_encode().
/*第三层编码
*该函数会实施降噪操作
*通过函数av1_estimate_noise_from_single_plane()使用soble梯度算子评估噪声程度。
*若噪声程度、帧类型(要求为KEY_FRAME)和其他一些条件成立,则会对该帧进行时域滤波。
*时域滤波通过av1_temporal_filter()完成。
*此后调用函数av1_encode()进行编码。
*/
static int denoise_and_encode(AV1_COMP *const cpi, uint8_t *const dest,
                              EncodeFrameInput *const frame_input,
                              EncodeFrameParams *const frame_params,
                              EncodeFrameResults *const frame_results,
                              int *temporal_filtered) {
  //判读是否关键帧,是关键帧的话就直接av1_encode
  if (frame_params->frame_type != KEY_FRAME) {
    cpi->pack_bitstream = 1;
    if (av1_encode(cpi, dest, frame_input, frame_params, frame_results) !=
        AOM_CODEC_OK) {
      return AOM_CODEC_ERROR;
    }
    return AOM_CODEC_OK;
  }
  //如果不是关键帧
  const AV1EncoderConfig *const oxcf = &cpi->oxcf;
  AV1_COMMON *const cm = &cpi->common;
  double noise_level;
  const int use_hbd = frame_input->source->flags & YV12_FLAG_HIGHBITDEPTH;
  //高低bit不同估算噪声水平
  if (use_hbd) {
    noise_level = highbd_estimate_noise(
        frame_input->source->y_buffer, frame_input->source->y_crop_width,
        frame_input->source->y_crop_height, frame_input->source->y_stride,
        cm->seq_params.bit_depth, EDGE_THRESHOLD);
  } else {
    noise_level = estimate_noise(frame_input->source->y_buffer,
                                 frame_input->source->y_crop_width,
                                 frame_input->source->y_crop_height,
                                 frame_input->source->y_stride, EDGE_THRESHOLD);
  }
  const int apply_filtering =
      oxcf->pass == 2 && frame_params->frame_type == KEY_FRAME &&
      cpi->rc.frames_to_key > NUM_KEY_FRAME_DENOISING && noise_level > 0 &&
      !is_lossless_requested(oxcf) && oxcf->arnr_max_frames > 0;

  // Apply filtering to key frame and encode.
  // 对关键帧进行过滤并且编码
  if (apply_filtering) {
    // Initialization for frame motion estimation.
    //帧运动估计的初始化。
    MACROBLOCKD *const xd = &cpi->td.mb.e_mbd;
    av1_init_context_buffers(cm);
    setup_mi(cpi, frame_input->source);
    av1_init_macroblockd(cm, xd, NULL);
    memset(cpi->mbmi_ext_base, 0,
           cm->mi_rows * cm->mi_cols * sizeof(*cpi->mbmi_ext_base));

    av1_set_speed_features_framesize_independent(cpi, oxcf->speed);
    av1_set_speed_features_framesize_dependent(cpi, oxcf->speed);
    av1_set_rd_speed_thresholds(cpi);
    av1_setup_frame_buf_refs(cm);
    av1_setup_frame_sign_bias(cm);
    av1_frame_init_quantizer(cpi);
    av1_setup_past_independence(cm);

    //保存一个原始图像的buffer
    const int num_planes = av1_num_planes(cm);
    aom_yv12_copy_frame(frame_input->source, &cpi->source_kf_buffer,
                        num_planes);
    av1_temporal_filter(cpi, -1);
    aom_extend_frame_borders(&cpi->alt_ref_buffer, num_planes);
    // Use the filtered frame for encoding.
    frame_input->source = &cpi->alt_ref_buffer;
    *temporal_filtered = 1;
    cpi->pack_bitstream = 1;
    if (av1_encode(cpi, dest, frame_input, frame_params, frame_results) !=
        AOM_CODEC_OK) {
      return AOM_CODEC_ERROR;
    }
    // Set frame_input source to true source for psnr calculation.
    //保留一份原来的buffer用于计算psnr
    if (oxcf->arnr_max_frames > 0 && *temporal_filtered) {
      aom_yv12_copy_frame(&cpi->source_kf_buffer, cpi->source, num_planes);
      aom_yv12_copy_frame(&cpi->source_kf_buffer, cpi->unscaled_source,
                          num_planes);
    }
  } else {
    // Encode other frames.
    cpi->pack_bitstream = 1;
    if (av1_encode(cpi, dest, frame_input, frame_params, frame_results) !=
        AOM_CODEC_OK) {
      return AOM_CODEC_ERROR;
    }
  }
  return AOM_CODEC_OK;
}
#endif  // !CONFIG_REALTIME_ONLY

相关文章

网友评论

      本文标题:av1代码学习4---denoise_and_encode()

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