OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2010 The WebM project authors. All Rights Reserved. | 2 * Copyright (c) 2010 The WebM project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
72 0, 3, 10, 5, 8, 0, 11, 6, 7, 8, | 72 0, 3, 10, 5, 8, 0, 11, 6, 7, 8, |
73 10, 7, 13, 9, 2, 5, 1, 5, 10, 2, | 73 10, 7, 13, 9, 2, 5, 1, 5, 10, 2, |
74 4, 3, 5, 6, 10, 8, 9, 4, 11, 14, | 74 4, 3, 5, 6, 10, 8, 9, 4, 11, 14, |
75 3, 8, 3, 7, 8, 5, 11, 4, 12, 3, | 75 3, 8, 3, 7, 8, 5, 11, 4, 12, 3, |
76 11, 9, 14, 8, 14, 13, 4, 3, 1, 2, | 76 11, 9, 14, 8, 14, 13, 4, 3, 1, 2, |
77 14, 6, 5, 4, 4, 11, 4, 6, 2, 1, | 77 14, 6, 5, 4, 4, 11, 4, 6, 2, 1, |
78 5, 8, 8, 12, 13, 5, 14, 10, 12, 13, | 78 5, 8, 8, 12, 13, 5, 14, 10, 12, 13, |
79 0, 9, 5, 5, 11, 10, 13, 9, 10, 13, | 79 0, 9, 5, 5, 11, 10, 13, 9, 10, 13, |
80 }; | 80 }; |
81 | 81 |
| 82 static const uint8_t q_diff_thresh = 20; |
| 83 static const uint8_t last_q_thresh = 170; |
| 84 |
82 void vp9_post_proc_down_and_across_c(const uint8_t *src_ptr, | 85 void vp9_post_proc_down_and_across_c(const uint8_t *src_ptr, |
83 uint8_t *dst_ptr, | 86 uint8_t *dst_ptr, |
84 int src_pixels_per_line, | 87 int src_pixels_per_line, |
85 int dst_pixels_per_line, | 88 int dst_pixels_per_line, |
86 int rows, | 89 int rows, |
87 int cols, | 90 int cols, |
88 int flimit) { | 91 int flimit) { |
89 uint8_t const *p_src; | 92 uint8_t const *p_src; |
90 uint8_t *p_dst; | 93 uint8_t *p_dst; |
91 int row; | 94 int row; |
(...skipping 517 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
609 pos[j] = blackclamp[0]; | 612 pos[j] = blackclamp[0]; |
610 | 613 |
611 if (pos[j] > 255 + whiteclamp[0]) | 614 if (pos[j] > 255 + whiteclamp[0]) |
612 pos[j] = 255 + whiteclamp[0]; | 615 pos[j] = 255 + whiteclamp[0]; |
613 | 616 |
614 pos[j] += ref[j]; | 617 pos[j] += ref[j]; |
615 } | 618 } |
616 } | 619 } |
617 } | 620 } |
618 | 621 |
| 622 static void swap_mi_and_prev_mi(VP9_COMMON *cm) { |
| 623 // Current mip will be the prev_mip for the next frame. |
| 624 MODE_INFO *temp = cm->postproc_state.prev_mip; |
| 625 cm->postproc_state.prev_mip = cm->mip; |
| 626 cm->mip = temp; |
| 627 |
| 628 // Update the upper left visible macroblock ptrs. |
| 629 cm->mi = cm->mip + cm->mi_stride + 1; |
| 630 cm->postproc_state.prev_mi = cm->postproc_state.prev_mip + cm->mi_stride + 1; |
| 631 } |
| 632 |
619 int vp9_post_proc_frame(struct VP9Common *cm, | 633 int vp9_post_proc_frame(struct VP9Common *cm, |
620 YV12_BUFFER_CONFIG *dest, vp9_ppflags_t *ppflags) { | 634 YV12_BUFFER_CONFIG *dest, vp9_ppflags_t *ppflags) { |
621 const int q = MIN(63, cm->lf.filter_level * 10 / 6); | 635 const int q = MIN(63, cm->lf.filter_level * 10 / 6); |
622 const int flags = ppflags->post_proc_flag; | 636 const int flags = ppflags->post_proc_flag; |
623 YV12_BUFFER_CONFIG *const ppbuf = &cm->post_proc_buffer; | 637 YV12_BUFFER_CONFIG *const ppbuf = &cm->post_proc_buffer; |
624 struct postproc_state *const ppstate = &cm->postproc_state; | 638 struct postproc_state *const ppstate = &cm->postproc_state; |
625 | 639 |
626 if (!cm->frame_to_show) | 640 if (!cm->frame_to_show) |
627 return -1; | 641 return -1; |
628 | 642 |
629 if (!flags) { | 643 if (!flags) { |
630 *dest = *cm->frame_to_show; | 644 *dest = *cm->frame_to_show; |
631 return 0; | 645 return 0; |
632 } | 646 } |
633 | 647 |
634 vp9_clear_system_state(); | 648 vp9_clear_system_state(); |
635 | 649 |
636 #if CONFIG_VP9_POSTPROC || CONFIG_INTERNAL_STATS | 650 // Alloc memory for prev_mip in the first frame. |
| 651 if (cm->current_video_frame == 1) { |
| 652 cm->postproc_state.last_base_qindex = cm->base_qindex; |
| 653 cm->postproc_state.last_frame_valid = 1; |
| 654 ppstate->prev_mip = vpx_calloc(cm->mi_alloc_size, sizeof(*cm->mip)); |
| 655 if (!ppstate->prev_mip) { |
| 656 return 1; |
| 657 } |
| 658 ppstate->prev_mi = ppstate->prev_mip + cm->mi_stride + 1; |
| 659 vpx_memset(ppstate->prev_mip, 0, |
| 660 cm->mi_stride * (cm->mi_rows + 1) * sizeof(*cm->mip)); |
| 661 } |
| 662 |
| 663 // Allocate post_proc_buffer_int if needed. |
| 664 if ((flags & VP9D_MFQE) && !cm->post_proc_buffer_int.buffer_alloc) { |
| 665 if ((flags & VP9D_DEMACROBLOCK) || (flags & VP9D_DEBLOCK)) { |
| 666 const int width = ALIGN_POWER_OF_TWO(cm->width, 4); |
| 667 const int height = ALIGN_POWER_OF_TWO(cm->height, 4); |
| 668 |
| 669 if (vp9_alloc_frame_buffer(&cm->post_proc_buffer_int, width, height, |
| 670 cm->subsampling_x, cm->subsampling_y, |
| 671 #if CONFIG_VP9_HIGHBITDEPTH |
| 672 cm->use_highbitdepth, |
| 673 #endif // CONFIG_VP9_HIGHBITDEPTH |
| 674 VP9_ENC_BORDER_IN_PIXELS, |
| 675 cm->byte_alignment) < 0) { |
| 676 vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR, |
| 677 "Failed to allocate MFQE framebuffer"); |
| 678 } |
| 679 |
| 680 // Ensure that postproc is set to all 0s so that post proc |
| 681 // doesn't pull random data in from edge. |
| 682 vpx_memset(cm->post_proc_buffer_int.buffer_alloc, 128, |
| 683 cm->post_proc_buffer.frame_size); |
| 684 } |
| 685 } |
| 686 |
637 if (vp9_realloc_frame_buffer(&cm->post_proc_buffer, cm->width, cm->height, | 687 if (vp9_realloc_frame_buffer(&cm->post_proc_buffer, cm->width, cm->height, |
638 cm->subsampling_x, cm->subsampling_y, | 688 cm->subsampling_x, cm->subsampling_y, |
639 #if CONFIG_VP9_HIGHBITDEPTH | 689 #if CONFIG_VP9_HIGHBITDEPTH |
640 cm->use_highbitdepth, | 690 cm->use_highbitdepth, |
641 #endif | 691 #endif |
642 VP9_DEC_BORDER_IN_PIXELS, NULL, NULL, NULL) < 0) | 692 VP9_DEC_BORDER_IN_PIXELS, cm->byte_alignment, |
| 693 NULL, NULL, NULL) < 0) |
643 vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR, | 694 vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR, |
644 "Failed to allocate post-processing buffer"); | 695 "Failed to allocate post-processing buffer"); |
645 #endif | |
646 | 696 |
647 if (flags & VP9D_DEMACROBLOCK) { | 697 if ((flags & VP9D_MFQE) && cm->current_video_frame >= 2 && |
| 698 cm->postproc_state.last_frame_valid && cm->bit_depth == 8 && |
| 699 cm->postproc_state.last_base_qindex <= last_q_thresh && |
| 700 cm->base_qindex - cm->postproc_state.last_base_qindex >= q_diff_thresh) { |
| 701 vp9_mfqe(cm); |
| 702 // TODO(jackychen): Consider whether enable deblocking by default |
| 703 // if mfqe is enabled. Need to take both the quality and the speed |
| 704 // into consideration. |
| 705 if ((flags & VP9D_DEMACROBLOCK) || (flags & VP9D_DEBLOCK)) { |
| 706 vp8_yv12_copy_frame(ppbuf, &cm->post_proc_buffer_int); |
| 707 } |
| 708 if ((flags & VP9D_DEMACROBLOCK) && cm->post_proc_buffer_int.buffer_alloc) { |
| 709 deblock_and_de_macro_block(&cm->post_proc_buffer_int, ppbuf, |
| 710 q + (ppflags->deblocking_level - 5) * 10, |
| 711 1, 0); |
| 712 } else if (flags & VP9D_DEBLOCK) { |
| 713 vp9_deblock(&cm->post_proc_buffer_int, ppbuf, q); |
| 714 } else { |
| 715 vp8_yv12_copy_frame(&cm->post_proc_buffer_int, ppbuf); |
| 716 } |
| 717 } else if (flags & VP9D_DEMACROBLOCK) { |
648 deblock_and_de_macro_block(cm->frame_to_show, ppbuf, | 718 deblock_and_de_macro_block(cm->frame_to_show, ppbuf, |
649 q + (ppflags->deblocking_level - 5) * 10, 1, 0); | 719 q + (ppflags->deblocking_level - 5) * 10, 1, 0); |
650 } else if (flags & VP9D_DEBLOCK) { | 720 } else if (flags & VP9D_DEBLOCK) { |
651 vp9_deblock(cm->frame_to_show, ppbuf, q); | 721 vp9_deblock(cm->frame_to_show, ppbuf, q); |
652 } else { | 722 } else { |
653 vp8_yv12_copy_frame(cm->frame_to_show, ppbuf); | 723 vp8_yv12_copy_frame(cm->frame_to_show, ppbuf); |
654 } | 724 } |
655 | 725 |
| 726 cm->postproc_state.last_base_qindex = cm->base_qindex; |
| 727 cm->postproc_state.last_frame_valid = 1; |
| 728 |
656 if (flags & VP9D_ADDNOISE) { | 729 if (flags & VP9D_ADDNOISE) { |
657 const int noise_level = ppflags->noise_level; | 730 const int noise_level = ppflags->noise_level; |
658 if (ppstate->last_q != q || | 731 if (ppstate->last_q != q || |
659 ppstate->last_noise != noise_level) { | 732 ppstate->last_noise != noise_level) { |
660 fillrd(ppstate, 63 - q, noise_level); | 733 fillrd(ppstate, 63 - q, noise_level); |
661 } | 734 } |
662 | 735 |
663 vp9_plane_add_noise(ppbuf->y_buffer, ppstate->noise, ppstate->blackclamp, | 736 vp9_plane_add_noise(ppbuf->y_buffer, ppstate->noise, ppstate->blackclamp, |
664 ppstate->whiteclamp, ppstate->bothclamp, | 737 ppstate->whiteclamp, ppstate->bothclamp, |
665 ppbuf->y_width, ppbuf->y_height, ppbuf->y_stride); | 738 ppbuf->y_width, ppbuf->y_height, ppbuf->y_stride); |
666 } | 739 } |
667 | 740 |
668 *dest = *ppbuf; | 741 *dest = *ppbuf; |
669 | 742 |
670 /* handle problem with extending borders */ | 743 /* handle problem with extending borders */ |
671 dest->y_width = cm->width; | 744 dest->y_width = cm->width; |
672 dest->y_height = cm->height; | 745 dest->y_height = cm->height; |
673 dest->uv_width = dest->y_width >> cm->subsampling_x; | 746 dest->uv_width = dest->y_width >> cm->subsampling_x; |
674 dest->uv_height = dest->y_height >> cm->subsampling_y; | 747 dest->uv_height = dest->y_height >> cm->subsampling_y; |
675 | 748 |
| 749 swap_mi_and_prev_mi(cm); |
676 return 0; | 750 return 0; |
677 } | 751 } |
678 #endif | 752 #endif // CONFIG_VP9_POSTPROC |
OLD | NEW |