| Index: source/libvpx/vp9/common/vp9_postproc.c
|
| ===================================================================
|
| --- source/libvpx/vp9/common/vp9_postproc.c (revision 293588)
|
| +++ source/libvpx/vp9/common/vp9_postproc.c (working copy)
|
| @@ -79,6 +79,9 @@
|
| 0, 9, 5, 5, 11, 10, 13, 9, 10, 13,
|
| };
|
|
|
| +static const uint8_t q_diff_thresh = 20;
|
| +static const uint8_t last_q_thresh = 170;
|
| +
|
| void vp9_post_proc_down_and_across_c(const uint8_t *src_ptr,
|
| uint8_t *dst_ptr,
|
| int src_pixels_per_line,
|
| @@ -616,6 +619,17 @@
|
| }
|
| }
|
|
|
| +static void swap_mi_and_prev_mi(VP9_COMMON *cm) {
|
| + // Current mip will be the prev_mip for the next frame.
|
| + MODE_INFO *temp = cm->postproc_state.prev_mip;
|
| + cm->postproc_state.prev_mip = cm->mip;
|
| + cm->mip = temp;
|
| +
|
| + // Update the upper left visible macroblock ptrs.
|
| + cm->mi = cm->mip + cm->mi_stride + 1;
|
| + cm->postproc_state.prev_mi = cm->postproc_state.prev_mip + cm->mi_stride + 1;
|
| +}
|
| +
|
| int vp9_post_proc_frame(struct VP9Common *cm,
|
| YV12_BUFFER_CONFIG *dest, vp9_ppflags_t *ppflags) {
|
| const int q = MIN(63, cm->lf.filter_level * 10 / 6);
|
| @@ -633,18 +647,74 @@
|
|
|
| vp9_clear_system_state();
|
|
|
| -#if CONFIG_VP9_POSTPROC || CONFIG_INTERNAL_STATS
|
| + // Alloc memory for prev_mip in the first frame.
|
| + if (cm->current_video_frame == 1) {
|
| + cm->postproc_state.last_base_qindex = cm->base_qindex;
|
| + cm->postproc_state.last_frame_valid = 1;
|
| + ppstate->prev_mip = vpx_calloc(cm->mi_alloc_size, sizeof(*cm->mip));
|
| + if (!ppstate->prev_mip) {
|
| + return 1;
|
| + }
|
| + ppstate->prev_mi = ppstate->prev_mip + cm->mi_stride + 1;
|
| + vpx_memset(ppstate->prev_mip, 0,
|
| + cm->mi_stride * (cm->mi_rows + 1) * sizeof(*cm->mip));
|
| + }
|
| +
|
| + // Allocate post_proc_buffer_int if needed.
|
| + if ((flags & VP9D_MFQE) && !cm->post_proc_buffer_int.buffer_alloc) {
|
| + if ((flags & VP9D_DEMACROBLOCK) || (flags & VP9D_DEBLOCK)) {
|
| + const int width = ALIGN_POWER_OF_TWO(cm->width, 4);
|
| + const int height = ALIGN_POWER_OF_TWO(cm->height, 4);
|
| +
|
| + if (vp9_alloc_frame_buffer(&cm->post_proc_buffer_int, width, height,
|
| + cm->subsampling_x, cm->subsampling_y,
|
| +#if CONFIG_VP9_HIGHBITDEPTH
|
| + cm->use_highbitdepth,
|
| +#endif // CONFIG_VP9_HIGHBITDEPTH
|
| + VP9_ENC_BORDER_IN_PIXELS,
|
| + cm->byte_alignment) < 0) {
|
| + vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
|
| + "Failed to allocate MFQE framebuffer");
|
| + }
|
| +
|
| + // Ensure that postproc is set to all 0s so that post proc
|
| + // doesn't pull random data in from edge.
|
| + vpx_memset(cm->post_proc_buffer_int.buffer_alloc, 128,
|
| + cm->post_proc_buffer.frame_size);
|
| + }
|
| + }
|
| +
|
| if (vp9_realloc_frame_buffer(&cm->post_proc_buffer, cm->width, cm->height,
|
| cm->subsampling_x, cm->subsampling_y,
|
| #if CONFIG_VP9_HIGHBITDEPTH
|
| cm->use_highbitdepth,
|
| #endif
|
| - VP9_DEC_BORDER_IN_PIXELS, NULL, NULL, NULL) < 0)
|
| + VP9_DEC_BORDER_IN_PIXELS, cm->byte_alignment,
|
| + NULL, NULL, NULL) < 0)
|
| vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
|
| "Failed to allocate post-processing buffer");
|
| -#endif
|
|
|
| - if (flags & VP9D_DEMACROBLOCK) {
|
| + if ((flags & VP9D_MFQE) && cm->current_video_frame >= 2 &&
|
| + cm->postproc_state.last_frame_valid && cm->bit_depth == 8 &&
|
| + cm->postproc_state.last_base_qindex <= last_q_thresh &&
|
| + cm->base_qindex - cm->postproc_state.last_base_qindex >= q_diff_thresh) {
|
| + vp9_mfqe(cm);
|
| + // TODO(jackychen): Consider whether enable deblocking by default
|
| + // if mfqe is enabled. Need to take both the quality and the speed
|
| + // into consideration.
|
| + if ((flags & VP9D_DEMACROBLOCK) || (flags & VP9D_DEBLOCK)) {
|
| + vp8_yv12_copy_frame(ppbuf, &cm->post_proc_buffer_int);
|
| + }
|
| + if ((flags & VP9D_DEMACROBLOCK) && cm->post_proc_buffer_int.buffer_alloc) {
|
| + deblock_and_de_macro_block(&cm->post_proc_buffer_int, ppbuf,
|
| + q + (ppflags->deblocking_level - 5) * 10,
|
| + 1, 0);
|
| + } else if (flags & VP9D_DEBLOCK) {
|
| + vp9_deblock(&cm->post_proc_buffer_int, ppbuf, q);
|
| + } else {
|
| + vp8_yv12_copy_frame(&cm->post_proc_buffer_int, ppbuf);
|
| + }
|
| + } else if (flags & VP9D_DEMACROBLOCK) {
|
| deblock_and_de_macro_block(cm->frame_to_show, ppbuf,
|
| q + (ppflags->deblocking_level - 5) * 10, 1, 0);
|
| } else if (flags & VP9D_DEBLOCK) {
|
| @@ -653,6 +723,9 @@
|
| vp8_yv12_copy_frame(cm->frame_to_show, ppbuf);
|
| }
|
|
|
| + cm->postproc_state.last_base_qindex = cm->base_qindex;
|
| + cm->postproc_state.last_frame_valid = 1;
|
| +
|
| if (flags & VP9D_ADDNOISE) {
|
| const int noise_level = ppflags->noise_level;
|
| if (ppstate->last_q != q ||
|
| @@ -673,6 +746,7 @@
|
| dest->uv_width = dest->y_width >> cm->subsampling_x;
|
| dest->uv_height = dest->y_height >> cm->subsampling_y;
|
|
|
| + swap_mi_and_prev_mi(cm);
|
| return 0;
|
| }
|
| -#endif
|
| +#endif // CONFIG_VP9_POSTPROC
|
|
|