| @@ -12,9 +12,12 @@ · 11 unmodified lines |
| 12 | #include "vpx_config.h" | 12 | #include "vpx_config.h" |
| 13 | #include "vpx_scale/yv12config.h" | 13 | #include "vpx_scale/yv12config.h" |
| 14 | #include "postproc.h" | 14 | #include "postproc.h" |
| | 15 | #include "common.h" |
| | 16 | #include "recon.h" |
| 15 | #include "vpx_scale/yv12extend.h" | 17 | #include "vpx_scale/yv12extend.h" |
| 16 | #include "vpx_scale/vpxscale.h" | 18 | #include "vpx_scale/vpxscale.h" |
| 17 | #include "systemdependent.h" | 19 | #include "systemdependent.h" |
| | 20 | #include "../encoder/variance.h" |
| 18 | | 21 | |
| 19 | #include <math.h> | 22 | #include <math.h> |
| 20 | #include <stdlib.h> | 23 | #include <stdlib.h> |
| @@ -121,7 +124,6 @@ const short vp8_rv[] = · 100 unmodified lines |
| 121 | 0, 9, 5, 5, 11, 10, 13, 9, 10, 13, | 124 | 0, 9, 5, 5, 11, 10, 13, 9, 10, 13, |
| 122 | }; | 125 | }; |
| 123 | | 126 | |
| 124 | | | |
| 125 | extern void vp8_blit_text(const char *msg, unsigned char *address, const int pitch); | 127 | extern void vp8_blit_text(const char *msg, unsigned char *address, const int pitch); |
| 126 | extern void vp8_blit_line(int x0, int x1, int y0, int y1, unsigned char *image, const int pitch); | 128 | extern void vp8_blit_line(int x0, int x1, int y0, int y1, unsigned char *image, const int pitch); |
| 127 | /*********************************************************************************************************** | 129 | /*********************************************************************************************************** |
| @@ -323,11 +325,11 @@ static void vp8_deblock_and_de_macro_block(YV12_BUFFER_CONFIG *source, · 195 unmodified lines |
| 323 | } | 325 | } |
| 324 | | 326 | |
| 325 | void vp8_deblock(YV12_BUFFER_CONFIG *source, | 327 | void vp8_deblock(YV12_BUFFER_CONFIG *source, |
| 326 | YV12_BUFFER_CONFIG *post, | 328 | YV12_BUFFER_CONFIG *post, |
| 327 | int q, | 329 | int q, |
| 328 | int low_var_thresh, | 330 | int low_var_thresh, |
| 329 | int flag, | 331 | int flag, |
| 330 | vp8_postproc_rtcd_vtable_t *rtcd) | 332 | vp8_postproc_rtcd_vtable_t *rtcd) |
| 331 | { | 333 | { |
| 332 | double level = 6.0e-05 * q * q * q - .0067 * q * q + .306 * q + .0065; | 334 | double level = 6.0e-05 * q * q * q - .0067 * q * q + .306 * q + .0065; |
| 333 | int ppl = (int)(level + .5); | 335 | int ppl = (int)(level + .5); |
| @@ -671,6 +673,210 @@ static void constrain_line (int x0, int *x1, int y0, int *y1, int width, int hei · 337 unmodified lines |
| 671 | } | 673 | } |
| 672 | } | 674 | } |
| 673 | | 675 | |
| | 676 | static void multiframe_quality_enhance_block |
| | 677 | ( |
| | 678 | int blksize, /* Currently only values supported are 16, 8, 4 */ |
| | 679 | int qcurr, |
| | 680 | int qprev, |
| | 681 | unsigned char *y, |
| | 682 | unsigned char *u, |
| | 683 | unsigned char *v, |
| | 684 | int y_stride, |
| | 685 | int uv_stride, |
| | 686 | unsigned char *yd, |
| | 687 | unsigned char *ud, |
| | 688 | unsigned char *vd, |
| | 689 | int yd_stride, |
| | 690 | int uvd_stride |
| | 691 | ) |
| | 692 | { |
| | 693 | static const unsigned char VP8_ZEROS[16]= |
| | 694 | { |
| | 695 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 |
| | 696 | }; |
| | 697 | int blksizeby2 = blksize >> 1; |
| | 698 | int blksizesq = blksize * blksize; |
| | 699 | |
| | 700 | int i, j; |
| | 701 | unsigned char *yp; |
| | 702 | unsigned char *ydp; |
| | 703 | unsigned char *up; |
| | 704 | unsigned char *udp; |
| | 705 | unsigned char *vp; |
| | 706 | unsigned char *vdp; |
| | 707 | |
| | 708 | unsigned int act, sse, sad, thr; |
| | 709 | if (blksize == 16) |
| | 710 | { |
| | 711 | act = vp8_variance_var16x16(y, y_stride, VP8_ZEROS, 0, &sse); |
| | 712 | sad = vp8_variance_sad16x16(y, y_stride, yd, yd_stride, 0); |
| | 713 | } |
| | 714 | else if (blksize == 8) |
| | 715 | { |
| | 716 | act = vp8_variance_var8x8(y, y_stride, VP8_ZEROS, 0, &sse); |
| | 717 | sad = vp8_variance_sad8x8(y, y_stride, yd, yd_stride, 0); |
| | 718 | } |
| | 719 | else |
| | 720 | { |
| | 721 | act = vp8_variance_var4x4(y, y_stride, VP8_ZEROS, 0, &sse); |
| | 722 | sad = vp8_variance_sad4x4(y, y_stride, yd, yd_stride, 0); |
| | 723 | } |
| | 724 | |
| | 725 | thr = 6 * blksizesq + (act >> 3); |
| | 726 | if (thr > 12 * blksizesq) thr = 12 * blksizesq; |
| | 727 | // These thresholds should be adapted later based on qcurr and qprev |
| | 728 | if (sad < thr) |
| | 729 | { |
| | 730 | static const int precision = 4; |
| | 731 | static const int roundoff = (1 << (precision - 1)); |
| | 732 | int ifactor = (sad << precision) / thr; |
| | 733 | // TODO: SIMD optimize this section |
| | 734 | if (ifactor) |
| | 735 | { |
| | 736 | int icfactor = (1 << precision) - ifactor; |
| | 737 | for (yp = y, ydp = yd, i = 0; i < blksize; ++i, yp += y_stride, ydp += yd_stride) |
| | 738 | { |
| | 739 | for (j = 0; j < blksize; ++j) |
| | 740 | ydp[j] = (int)((yp[j] * ifactor + ydp[j] * icfactor + roundoff) >> precision); |
| | 741 | } |
| | 742 | for (up = u, udp = ud, i = 0; i < blksizeby2; ++i, up += uv_stride, udp += uvd_stride) |
| | 743 | { |
| | 744 | for (j = 0; j < blksizeby2; ++j) |
| | 745 | udp[j] = (int)((up[j] * ifactor + udp[j] * icfactor + roundoff) >> precision); |
| | 746 | } |
| | 747 | for (vp = v, vdp = vd, i = 0; i < blksizeby2; ++i, vp += uv_stride, vdp += uvd_stride) |
| | 748 | { |
| | 749 | for (j = 0; j < blksizeby2; ++j) |
| | 750 | vdp[j] = (int)((vp[j] * ifactor + vdp[j] * icfactor + roundoff) >> precision); |
| | 751 | } |
| | 752 | } |
| | 753 | } |
| | 754 | else |
| | 755 | { |
| | 756 | if (blksize == 16) |
| | 757 | { |
| | 758 | vp8_recon_copy16x16(y, y_stride, yd, yd_stride); |
| | 759 | vp8_recon_copy8x8(u, uv_stride, ud, uvd_stride); |
| | 760 | vp8_recon_copy8x8(v, uv_stride, vd, uvd_stride); |
| | 761 | } |
| | 762 | else if (blksize == 8) |
| | 763 | { |
| | 764 | vp8_recon_copy8x8(y, y_stride, yd, yd_stride); |
| | 765 | for (up = u, udp = ud, i = 0; i < blksizeby2; ++i, up += uv_stride, udp += uvd_stride) |
| | 766 | vpx_memcpy(udp, up, blksizeby2); |
| | 767 | for (vp = v, vdp = vd, i = 0; i < blksizeby2; ++i, vp += uv_stride, vdp += uvd_stride) |
| | 768 | vpx_memcpy(vdp, vp, blksizeby2); |
| | 769 | } |
| | 770 | else |
| | 771 | { |
| | 772 | for (yp = y, ydp = yd, i = 0; i < blksize; ++i, yp += y_stride, ydp += yd_stride) |
| | 773 | vpx_memcpy(ydp, yp, blksize); |
| | 774 | for (up = u, udp = ud, i = 0; i < blksizeby2; ++i, up += uv_stride, udp += uvd_stride) |
| | 775 | vpx_memcpy(udp, up, blksizeby2); |
| | 776 | for (vp = v, vdp = vd, i = 0; i < blksizeby2; ++i, vp += uv_stride, vdp += uvd_stride) |
| | 777 | vpx_memcpy(vdp, vp, blksizeby2); |
| | 778 | } |
| | 779 | } |
| | 780 | } |
| | 781 | |
| | 782 | void vp8_multiframe_quality_enhance |
| | 783 | ( |
| | 784 | VP8_COMMON *cm |
| | 785 | ) |
| | 786 | { |
| | 787 | YV12_BUFFER_CONFIG *show = cm->frame_to_show; |
| | 788 | YV12_BUFFER_CONFIG *dest = &cm->post_proc_buffer; |
| | 789 | |
| | 790 | FRAME_TYPE frame_type = cm->frame_type; |
| | 791 | /* Point at base of Mb MODE_INFO list has motion vectors etc */ |
| | 792 | const MODE_INFO *mode_info_context = cm->mi; |
| | 793 | int qcurr = cm->base_qindex; |
| | 794 | int qprev = cm->postproc_state.last_base_qindex; |
| | 795 | |
| | 796 | int mb_row; |
| | 797 | int mb_col; |
| | 798 | |
| | 799 | unsigned char *y_ptr, *u_ptr, *v_ptr; |
| | 800 | unsigned char *yd_ptr, *ud_ptr, *vd_ptr; |
| | 801 | |
| | 802 | /* Set up the buffer pointers */ |
| | 803 | y_ptr = show->y_buffer; |
| | 804 | u_ptr = show->u_buffer; |
| | 805 | v_ptr = show->v_buffer; |
| | 806 | yd_ptr = dest->y_buffer; |
| | 807 | ud_ptr = dest->u_buffer; |
| | 808 | vd_ptr = dest->v_buffer; |
| | 809 | |
| | 810 | /* postprocess each macro block */ |
| | 811 | for (mb_row = 0; mb_row < cm->mb_rows; mb_row++) |
| | 812 | { |
| | 813 | for (mb_col = 0; mb_col < cm->mb_cols; mb_col++) |
| | 814 | { |
| | 815 | /* if motion is high there will likely be no benefit */ |
| | 816 | if (((frame_type == INTER_FRAME && |
| | 817 | abs(mode_info_context->mbmi.mv.as_mv.row) <= 10 && |
| | 818 | abs(mode_info_context->mbmi.mv.as_mv.col) <= 10) || |
| | 819 | (frame_type == KEY_FRAME)) && |
| | 820 | mode_info_context->mbmi.mode != B_PRED) |
| | 821 | { |
| | 822 | multiframe_quality_enhance_block(16, |
| | 823 | qcurr, |
| | 824 | qprev, |
| | 825 | y_ptr, |
| | 826 | u_ptr, |
| | 827 | v_ptr, |
| | 828 | show->y_stride, |
| | 829 | show->uv_stride, |
| | 830 | yd_ptr, |
| | 831 | ud_ptr, |
| | 832 | vd_ptr, |
| | 833 | dest->y_stride, |
| | 834 | dest->uv_stride); |
| | 835 | } |
| | 836 | else if (mode_info_context->mbmi.mode == B_PRED) |
| | 837 | { |
| | 838 | int i, j; |
| | 839 | for (i=0; i<2; ++i) |
| | 840 | for (j=0; j<2; ++j) |
| | 841 | multiframe_quality_enhance_block(8, |
| | 842 | qcurr, |
| | 843 | qprev, |
| | 844 | y_ptr + 8*(i*show->y_stride+j), |
| | 845 | u_ptr + 4*(i*show->uv_stride+j), |
| | 846 | v_ptr + 4*(i*show->uv_stride+j), |
| | 847 | show->y_stride, |
| | 848 | show->uv_stride, |
| | 849 | yd_ptr + 8*(i*dest->y_stride+j), |
| | 850 | ud_ptr + 4*(i*dest->uv_stride+j), |
| | 851 | vd_ptr + 4*(i*dest->uv_stride+j), |
| | 852 | dest->y_stride, |
| | 853 | dest->uv_stride); |
| | 854 | } |
| | 855 | else |
| | 856 | { |
| | 857 | vp8_recon_copy16x16(y_ptr, show->y_stride, yd_ptr, dest->y_stride); |
| | 858 | vp8_recon_copy8x8(u_ptr, show->uv_stride, ud_ptr, dest->uv_stride); |
| | 859 | vp8_recon_copy8x8(v_ptr, show->uv_stride, vd_ptr, dest->uv_stride); |
| | 860 | } |
| | 861 | y_ptr += 16; |
| | 862 | u_ptr += 8; |
| | 863 | v_ptr += 8; |
| | 864 | yd_ptr += 16; |
| | 865 | ud_ptr += 8; |
| | 866 | vd_ptr += 8; |
| | 867 | mode_info_context++; /* step to next MB */ |
| | 868 | } |
| | 869 | |
| | 870 | y_ptr += show->y_stride * 16 - 16 * cm->mb_cols; |
| | 871 | u_ptr += show->uv_stride * 8 - 8 * cm->mb_cols; |
| | 872 | v_ptr += show->uv_stride * 8 - 8 * cm->mb_cols; |
| | 873 | yd_ptr += dest->y_stride * 16 - 16 * cm->mb_cols; |
| | 874 | ud_ptr += dest->uv_stride * 8 - 8 * cm->mb_cols; |
| | 875 | vd_ptr += dest->uv_stride * 8 - 8 * cm->mb_cols; |
| | 876 | |
| | 877 | mode_info_context++; /* Skip border mb */ |
| | 878 | } |
| | 879 | } |
| 674 | | 880 | |
| 675 | #if CONFIG_RUNTIME_CPU_DETECT | 881 | #if CONFIG_RUNTIME_CPU_DETECT |
| 676 | #define RTCD_VTABLE(oci) (&(oci)->rtcd.postproc) | 882 | #define RTCD_VTABLE(oci) (&(oci)->rtcd.postproc) |
| @@ -699,8 +905,8 @@ int vp8_post_proc_frame(VP8_COMMON *oci, YV12_BUFFER_CONFIG *dest, vp8_ppflags_t · 22 unmodified lines |
| 699 | dest->y_width = oci->Width; | 905 | dest->y_width = oci->Width; |
| 700 | dest->y_height = oci->Height; | 906 | dest->y_height = oci->Height; |
| 701 | dest->uv_height = dest->y_height / 2; | 907 | dest->uv_height = dest->y_height / 2; |
| | 908 | oci->postproc_state.last_base_qindex = oci->base_qindex; |
| 702 | return 0; | 909 | return 0; |
| 703 | | | |
| 704 | } | 910 | } |
| 705 | | 911 | |
| 706 | #if ARCH_X86||ARCH_X86_64 | 912 | #if ARCH_X86||ARCH_X86_64 |
| @@ -717,6 +923,12 @@ int vp8_post_proc_frame(VP8_COMMON *oci, YV12_BUFFER_CONFIG *dest, vp8_ppflags_t · 10 unmodified lines |
| 717 | vp8_deblock(oci->frame_to_show, &oci->post_proc_buffer, | 923 | vp8_deblock(oci->frame_to_show, &oci->post_proc_buffer, |
| 718 | q, 1, 0, RTCD_VTABLE(oci)); | 924 | q, 1, 0, RTCD_VTABLE(oci)); |
| 719 | } | 925 | } |
| | 926 | else if ((flags & VP8D_MFQE) && |
| | 927 | oci->current_video_frame >= 2 && |
| | 928 | oci->base_qindex - oci->postproc_state.last_base_qindex >= 10) |
| | 929 | { |
| | 930 | vp8_multiframe_quality_enhance(oci); |
| | 931 | } |
| 720 | else | 932 | else |
| 721 | { | 933 | { |
| 722 | vp8_yv12_copy_frame_ptr(oci->frame_to_show, &oci->post_proc_buffer); | 934 | vp8_yv12_copy_frame_ptr(oci->frame_to_show, &oci->post_proc_buffer); |
| @@ -1105,5 +1317,6 @@ int vp8_post_proc_frame(VP8_COMMON *oci, YV12_BUFFER_CONFIG *dest, vp8_ppflags_t · 382 unmodified lines |
| 1105 | dest->y_width = oci->Width; | 1317 | dest->y_width = oci->Width; |
| 1106 | dest->y_height = oci->Height; | 1318 | dest->y_height = oci->Height; |
| 1107 | dest->uv_height = dest->y_height / 2; | 1319 | dest->uv_height = dest->y_height / 2; |
| | 1320 | oci->postproc_state.last_base_qindex = oci->base_qindex; |
| 1108 | return 0; | 1321 | return 0; |
| 1109 | } | 1322 | } |