The behavior is the same as that of detect_transition_still, only we void using cpi and twopass->stats_in
Unified · Split
| @@ -1804,33 +1804,46 @@ static double get_prediction_decay_rate(const FRAME_INFO *frame_info, · 1803 unmodified lines | ||
| 1804 | 1804 | (sr_decay_rate + ((1.0 - sr_decay_rate) * zero_motion_factor))); |
| 1805 | 1805 | } |
| 1806 | 1806 | |
| 1807 | +static int get_show_idx(const TWO_PASS *twopass) { | |
| 1808 | + return (int)(twopass->stats_in - twopass->stats_in_start); | |
| 1809 | +} | |
| 1807 | 1810 | // Function to test for a condition where a complex transition is followed |
| 1808 | 1811 | // by a static section. For example in slide shows where there is a fade |
| 1809 | 1812 | // between slides. This is to help with more optimal kf and gf positioning. |
| 1813 | +static int check_transition_to_still(const FIRST_PASS_INFO *first_pass_info, | |
| 1814 | + int show_idx, int still_interval) { | |
| 1815 | + int j; | |
| 1816 | + int num_frames = fps_get_num_frames(first_pass_info); | |
| 1817 | + if (show_idx + still_interval > num_frames) { | |
| 1818 | + return 0; | |
| 1819 | + } | |
| 1820 | + | |
| 1821 | + // Look ahead a few frames to see if static condition persists... | |
| 1822 | + for (j = 0; j < still_interval; ++j) { | |
| 1823 | + const FIRSTPASS_STATS *stats = | |
| 1824 | + fps_get_frame_stats(first_pass_info, show_idx + j); | |
| 1825 | + if (stats->pcnt_inter - stats->pcnt_motion < 0.999) break; | |
| 1826 | + } | |
| 1827 | + | |
| 1828 | + // Only if it does do we signal a transition to still. | |
| 1829 | + return j == still_interval; | |
| 1830 | +} | |
| 1831 | + | |
| 1810 | 1832 | static int detect_transition_to_still(VP9_COMP *cpi, int frame_interval, |
| 1811 | 1833 | int still_interval, |
| 1812 | 1834 | double loop_decay_rate, |
| 1813 | 1835 | double last_decay_rate) { |
| 1814 | − TWO_PASS *const twopass = &cpi->twopass; | |
| 1836 | + const TWO_PASS *const twopass = &cpi->twopass; | |
| 1815 | 1837 | RATE_CONTROL *const rc = &cpi->rc; |
| 1838 | + int show_idx = get_show_idx(twopass); | |
| 1816 | 1839 | |
| 1817 | 1840 | // Break clause to detect very still sections after motion |
| 1818 | 1841 | // For example a static image after a fade or other transition |
| 1819 | 1842 | // instead of a clean scene cut. |
| 1820 | 1843 | if (frame_interval > rc->min_gf_interval && loop_decay_rate >= 0.999 && |
| 1821 | 1844 | last_decay_rate < 0.9) { |
| 1822 | − int j; | |
| 1823 | − | |
| 1824 | − // Look ahead a few frames to see if static condition persists... | |
| 1825 | − for (j = 0; j < still_interval; ++j) { | |
| 1826 | − const FIRSTPASS_STATS *stats = &twopass->stats_in[j]; | |
| 1827 | − if (stats >= twopass->stats_in_end) break; | |
| 1828 | − | |
| 1829 | − if (stats->pcnt_inter - stats->pcnt_motion < 0.999) break; | |
| 1830 | − } | |
| 1831 | − | |
| 1832 | − // Only if it does do we signal a transition to still. | |
| 1833 | − return j == still_interval; | |
| 1845 | + return check_transition_to_still(&twopass->first_pass_info, show_idx, | |
| 1846 | + still_interval); | |
| 1834 | 1847 | } |
| 1835 | 1848 | |
| 1836 | 1849 | return 0; |
| @@ -2058,7 +2071,7 @@ static int calc_arf_boost(VP9_COMP *cpi, int f_frames, int b_frames) { · 221 unmodified lines | ||
| 2058 | 2071 | const FRAME_INFO *frame_info = &cpi->frame_info; |
| 2059 | 2072 | TWO_PASS *const twopass = &cpi->twopass; |
| 2060 | 2073 | const int avg_inter_frame_qindex = cpi->rc.avg_frame_qindex[INTER_FRAME]; |
| 2061 | − int arf_show_idx = (int)(twopass->stats_in - twopass->stats_in_start); | |
| 2074 | + int arf_show_idx = get_show_idx(twopass); | |
| 2062 | 2075 | return compute_arf_boost(frame_info, &twopass->first_pass_info, arf_show_idx, |
| 2063 | 2076 | f_frames, b_frames, avg_inter_frame_qindex); |
| 2064 | 2077 | } |
| @@ -2608,10 +2621,14 @@ static void define_gf_group(VP9_COMP *cpi, int gf_start_show_idx) { · 543 unmodified lines | ||
| 2608 | 2621 | |
| 2609 | 2622 | // Break clause to detect very still sections after motion. For example, |
| 2610 | 2623 | // a static image after a fade or other transition. |
| 2611 | − if (detect_transition_to_still(cpi, i, 5, loop_decay_rate, | |
| 2612 | − last_loop_decay_rate)) { | |
| 2613 | − allow_alt_ref = 0; | |
| 2614 | − break; | |
| 2624 | + if (i > rc->min_gf_interval && loop_decay_rate >= 0.999 && | |
| 2625 | + last_loop_decay_rate < 0.9) { | |
| 2626 | + int still_interval = 5; | |
| 2627 | + if (check_transition_to_still(first_pass_info, gf_start_show_idx + i, | |
| 2628 | + still_interval)) { | |
| 2629 | + allow_alt_ref = 0; | |
| 2630 | + break; | |
| 2631 | + } | |
| 2615 | 2632 | } |
| 2616 | 2633 | |
| 2617 | 2634 | // Update the accumulator for second ref error difference. |
| @@ -2666,7 +2683,7 @@ static void define_gf_group(VP9_COMP *cpi, int gf_start_show_idx) { · 48 unmodified lines | ||
| 2666 | 2683 | const int avg_inter_frame_qindex = rc->avg_frame_qindex[INTER_FRAME]; |
| 2667 | 2684 | // TODO(angiebird): figure out why arf's location is assigned this way |
| 2668 | 2685 | const int arf_show_idx = |
| 2669 | − VPXMIN(gf_start_show_idx + i + 1, first_pass_info->num_frames); | |
| 2686 | + VPXMIN(gf_start_show_idx + i + 1, fps_get_num_frames(first_pass_info)); | |
| 2670 | 2687 | |
| 2671 | 2688 | // Calculate the boost for alt ref. |
| 2672 | 2689 | rc->gfu_boost = |
| @@ -158,6 +158,10 @@ static INLINE void fps_init_first_pass_info(FIRST_PASS_INFO *first_pass_info, · 157 unmodified lines | ||
| 158 | 158 | first_pass_info->num_frames = num_frames; |
| 159 | 159 | } |
| 160 | 160 | |
| 161 | +static INLINE int fps_get_num_frames(const FIRST_PASS_INFO *first_pass_info) { | |
| 162 | + return first_pass_info->num_frames; | |
| 163 | +} | |
| 164 | + | |
| 161 | 165 | static INLINE const FIRSTPASS_STATS *fps_get_frame_stats( |
| 162 | 166 | const FIRST_PASS_INFO *first_pass_info, int show_idx) { |
| 163 | 167 | if (show_idx >= first_pass_info->num_frames) { |