* changes: Rename num_show_frames by num_coding_frames Use compute_arf_boost() in define_gf_group() Localize av_err mean_mod_score in define_gf_group Move code of deciding gop size into brackets
Unified · Split
| @@ -2496,21 +2496,10 @@ static void define_gf_group(VP9_COMP *cpi, int gf_start_show_idx) { · 2495 unmodified lines | |||
| 2496 | double gf_group_inter = 0.0; | 2496 | double gf_group_inter = 0.0; |
| 2497 | double gf_group_motion = 0.0; | 2497 | double gf_group_motion = 0.0; |
| 2498 | 2498 | ||
| 2499 | double mv_ratio_accumulator = 0.0; | ||
| 2500 | double zero_motion_accumulator = 1.0; | 2499 | double zero_motion_accumulator = 1.0; |
| 2501 | double loop_decay_rate = 1.00; | ||
| 2502 | 2500 | ||
| 2503 | double this_frame_mv_in_out = 0.0; | ||
| 2504 | double mv_in_out_accumulator = 0.0; | ||
| 2505 | double abs_mv_in_out_accumulator = 0.0; | ||
| 2506 | double mv_ratio_accumulator_thresh; | ||
| 2507 | double abs_mv_in_out_thresh; | ||
| 2508 | double sr_accumulator = 0.0; | ||
| 2509 | const double av_err = get_distribution_av_err(cpi, twopass); | ||
| 2510 | const double mean_mod_score = twopass->mean_mod_score; | ||
| 2511 | unsigned int allow_alt_ref = is_altref_enabled(cpi); | 2501 | unsigned int allow_alt_ref = is_altref_enabled(cpi); |
| 2512 | 2502 | ||
| 2513 | int flash_detected; | ||
| 2514 | int active_max_gf_interval; | 2503 | int active_max_gf_interval; |
| 2515 | int active_min_gf_interval; | 2504 | int active_min_gf_interval; |
| 2516 | int64_t gf_group_bits; | 2505 | int64_t gf_group_bits; |
| @@ -2532,11 +2521,6 @@ static void define_gf_group(VP9_COMP *cpi, int gf_start_show_idx) { · 15 unmodified lines | |||
| 2532 | 2521 | ||
| 2533 | vpx_clear_system_state(); | 2522 | vpx_clear_system_state(); |
| 2534 | 2523 | ||
| 2535 | // Motion breakout threshold for loop below depends on image size. | ||
| 2536 | mv_ratio_accumulator_thresh = | ||
| 2537 | (cpi->initial_height + cpi->initial_width) / 4.0; | ||
| 2538 | abs_mv_in_out_thresh = ARF_ABS_ZOOM_THRESH; | ||
| 2539 | |||
| 2540 | // Set a maximum and minimum interval for the GF group. | 2524 | // Set a maximum and minimum interval for the GF group. |
| 2541 | // If the image appears almost completely static we can extend beyond this. | 2525 | // If the image appears almost completely static we can extend beyond this. |
| 2542 | { | 2526 | { |
| @@ -2590,87 +2574,101 @@ static void define_gf_group(VP9_COMP *cpi, int gf_start_show_idx) { · 47 unmodified lines | |||
| 2590 | } | 2574 | } |
| 2591 | 2575 | ||
| 2592 | i = 0; | 2576 | i = 0; |
| 2593 | while (i < rc->static_scene_max_gf_interval && i < rc->frames_to_key) { | 2577 | { |
| 2594 | const FIRSTPASS_STATS *next_next_frame; | 2578 | double loop_decay_rate = 1.00; |
| 2595 | const FIRSTPASS_STATS *next_frame; | 2579 | double mv_ratio_accumulator = 0.0; |
| 2596 | ++i; | 2580 | double this_frame_mv_in_out = 0.0; |
| 2581 | double mv_in_out_accumulator = 0.0; | ||
| 2582 | double abs_mv_in_out_accumulator = 0.0; | ||
| 2583 | double sr_accumulator = 0.0; | ||
| 2584 | // Motion breakout threshold for loop below depends on image size. | ||
| 2585 | double mv_ratio_accumulator_thresh = | ||
| 2586 | (cpi->initial_height + cpi->initial_width) / 4.0; | ||
| 2587 | |||
| 2588 | while (i < rc->static_scene_max_gf_interval && i < rc->frames_to_key) { | ||
| 2589 | const FIRSTPASS_STATS *next_next_frame; | ||
| 2590 | const FIRSTPASS_STATS *next_frame; | ||
| 2591 | int flash_detected; | ||
| 2592 | ++i; | ||
| 2593 | |||
| 2594 | next_frame = fps_get_frame_stats(first_pass_info, gf_start_show_idx + i); | ||
| 2595 | if (next_frame == NULL) { | ||
| 2596 | break; | ||
| 2597 | } | ||
| 2597 | 2598 | ||
| 2598 | next_frame = fps_get_frame_stats(first_pass_info, gf_start_show_idx + i); | 2599 | // Test for the case where there is a brief flash but the prediction |
| 2599 | if (next_frame == NULL) { | 2600 | // quality back to an earlier frame is then restored. |
| 2600 | break; | 2601 | next_next_frame = |
| 2601 | } | 2602 | fps_get_frame_stats(first_pass_info, gf_start_show_idx + i + 1); |
| 2603 | flash_detected = detect_flash_from_frame_stats(next_next_frame); | ||
| 2602 | 2604 | ||
| 2603 | // Test for the case where there is a brief flash but the prediction | 2605 | // Update the motion related elements to the boost calculation. |
| 2604 | // quality back to an earlier frame is then restored. | 2606 | accumulate_frame_motion_stats( |
| 2605 | next_next_frame = | 2607 | next_frame, &this_frame_mv_in_out, &mv_in_out_accumulator, |
| 2606 | fps_get_frame_stats(first_pass_info, gf_start_show_idx + i + 1); | 2608 | &abs_mv_in_out_accumulator, &mv_ratio_accumulator); |
| 2607 | flash_detected = detect_flash_from_frame_stats(next_next_frame); | ||
| 2608 | 2609 | ||
| 2609 | // Update the motion related elements to the boost calculation. | 2610 | // Monitor for static sections. |
| 2610 | accumulate_frame_motion_stats( | 2611 | if ((rc->frames_since_key + i - 1) > 1) { |
| 2611 | next_frame, &this_frame_mv_in_out, &mv_in_out_accumulator, | 2612 | zero_motion_accumulator = |
| 2612 | &abs_mv_in_out_accumulator, &mv_ratio_accumulator); | 2613 | VPXMIN(zero_motion_accumulator, |
| 2614 | get_zero_motion_factor(frame_info, next_frame)); | ||
| 2615 | } | ||
| 2613 | 2616 | ||
| 2614 | // Monitor for static sections. | 2617 | // Accumulate the effect of prediction quality decay. |
| 2615 | if ((rc->frames_since_key + i - 1) > 1) { | 2618 | if (!flash_detected) { |
| 2616 | zero_motion_accumulator = | 2619 | double last_loop_decay_rate = loop_decay_rate; |
| 2617 | VPXMIN(zero_motion_accumulator, | 2620 | loop_decay_rate = get_prediction_decay_rate(frame_info, next_frame); |
| 2618 | get_zero_motion_factor(frame_info, next_frame)); | 2621 | |
| 2619 | } | 2622 | // Break clause to detect very still sections after motion. For example, |
| 2623 | // a static image after a fade or other transition. | ||
| 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 | } | ||
| 2632 | } | ||
| 2620 | 2633 | ||
| 2621 | // Accumulate the effect of prediction quality decay. | 2634 | // Update the accumulator for second ref error difference. |
| 2622 | if (!flash_detected) { | 2635 | // This is intended to give an indication of how much the coded error is |
| 2623 | double last_loop_decay_rate = loop_decay_rate; | 2636 | // increasing over time. |
| 2624 | loop_decay_rate = get_prediction_decay_rate(frame_info, next_frame); | 2637 | if (i == 1) { |
| 2625 | 2638 | sr_accumulator += next_frame->coded_error; | |
| 2626 | // Break clause to detect very still sections after motion. For example, | 2639 | } else { |
| 2627 | // a static image after a fade or other transition. | 2640 | sr_accumulator += |
| 2628 | if (i > rc->min_gf_interval && loop_decay_rate >= 0.999 && | 2641 | (next_frame->sr_coded_error - next_frame->coded_error); |
| 2629 | last_loop_decay_rate < 0.9) { | ||
| 2630 | int still_interval = 5; | ||
| 2631 | if (check_transition_to_still(first_pass_info, gf_start_show_idx + i, | ||
| 2632 | still_interval)) { | ||
| 2633 | allow_alt_ref = 0; | ||
| 2634 | break; | ||
| 2635 | } | 2642 | } |
| 2636 | } | 2643 | } |
| 2637 | 2644 | ||
| 2638 | // Update the accumulator for second ref error difference. | 2645 | // Break out conditions. |
| 2639 | // This is intended to give an indication of how much the coded error is | 2646 | // Break at maximum of active_max_gf_interval unless almost totally |
| 2640 | // increasing over time. | 2647 | // static. |
| 2641 | if (i == 1) { | 2648 | // |
| 2642 | sr_accumulator += next_frame->coded_error; | 2649 | // Note that the addition of a test of rc->source_alt_ref_active is |
| 2643 | } else { | 2650 | // deliberate. The effect of this is that after a normal altref group even |
| 2644 | sr_accumulator += | 2651 | // if the material is static there will be one normal length GF group |
| 2645 | (next_frame->sr_coded_error - next_frame->coded_error); | 2652 | // before allowing longer GF groups. The reason for this is that in cases |
| 2653 | // such as slide shows where slides are separated by a complex transition | ||
| 2654 | // such as a fade, the arf group spanning the transition may not be coded | ||
| 2655 | // at a very high quality and hence this frame (with its overlay) is a | ||
| 2656 | // poor golden frame to use for an extended group. | ||
| 2657 | if ((i >= active_max_gf_interval) && | ||
| 2658 | ((zero_motion_accumulator < 0.995) || (rc->source_alt_ref_active))) { | ||
| 2659 | break; | ||
| 2660 | } | ||
| 2661 | if ( | ||
| 2662 | // Don't break out with a very short interval. | ||
| 2663 | (i >= active_min_gf_interval) && | ||
| 2664 | // If possible dont break very close to a kf | ||
| 2665 | ((rc->frames_to_key - i) >= rc->min_gf_interval) && (i & 0x01) && | ||
| 2666 | (!flash_detected) && | ||
| 2667 | ((mv_ratio_accumulator > mv_ratio_accumulator_thresh) || | ||
| 2668 | (abs_mv_in_out_accumulator > ARF_ABS_ZOOM_THRESH) || | ||
| 2669 | (sr_accumulator > gop_intra_factor * next_frame->intra_error))) { | ||
| 2670 | break; | ||
| 2646 | } | 2671 | } |
| 2647 | } | ||
| 2648 | |||
| 2649 | // Break out conditions. | ||
| 2650 | // Break at maximum of active_max_gf_interval unless almost totally static. | ||
| 2651 | // | ||
| 2652 | // Note that the addition of a test of rc->source_alt_ref_active is | ||
| 2653 | // deliberate. The effect of this is that after a normal altref group even | ||
| 2654 | // if the material is static there will be one normal length GF group | ||
| 2655 | // before allowing longer GF groups. The reason for this is that in cases | ||
| 2656 | // such as slide shows where slides are separated by a complex transition | ||
| 2657 | // such as a fade, the arf group spanning the transition may not be coded | ||
| 2658 | // at a very high quality and hence this frame (with its overlay) is a | ||
| 2659 | // poor golden frame to use for an extended group. | ||
| 2660 | if ((i >= active_max_gf_interval) && | ||
| 2661 | ((zero_motion_accumulator < 0.995) || (rc->source_alt_ref_active))) { | ||
| 2662 | break; | ||
| 2663 | } | ||
| 2664 | if ( | ||
| 2665 | // Don't break out with a very short interval. | ||
| 2666 | (i >= active_min_gf_interval) && | ||
| 2667 | // If possible dont break very close to a kf | ||
| 2668 | ((rc->frames_to_key - i) >= rc->min_gf_interval) && (i & 0x01) && | ||
| 2669 | (!flash_detected) && | ||
| 2670 | ((mv_ratio_accumulator > mv_ratio_accumulator_thresh) || | ||
| 2671 | (abs_mv_in_out_accumulator > abs_mv_in_out_thresh) || | ||
| 2672 | (sr_accumulator > gop_intra_factor * next_frame->intra_error))) { | ||
| 2673 | break; | ||
| 2674 | } | 2672 | } |
| 2675 | } | 2673 | } |
| 2676 | 2674 | ||
| @@ -2696,8 +2694,16 @@ static void define_gf_group(VP9_COMP *cpi, int gf_start_show_idx) { · 19 unmodified lines | |||
| 2696 | b_frames, avg_inter_frame_qindex); | 2694 | b_frames, avg_inter_frame_qindex); |
| 2697 | rc->source_alt_ref_pending = 1; | 2695 | rc->source_alt_ref_pending = 1; |
| 2698 | } else { | 2696 | } else { |
| 2699 | reset_fpf_position(twopass, start_pos); | 2697 | const int f_frames = i - 1; |
| 2700 | rc->gfu_boost = VPXMIN(MAX_GF_BOOST, calc_arf_boost(cpi, (i - 1), 0)); | 2698 | const int b_frames = 0; |
| 2699 | const int avg_inter_frame_qindex = rc->avg_frame_qindex[INTER_FRAME]; | ||
| 2700 | // TODO(angiebird): figure out why arf's location is assigned this way | ||
| 2701 | const int gld_show_idx = | ||
| 2702 | VPXMIN(gf_start_show_idx + 1, fps_get_num_frames(first_pass_info)); | ||
| 2703 | const int arf_boost = | ||
| 2704 | compute_arf_boost(frame_info, first_pass_info, gld_show_idx, f_frames, | ||
| 2705 | b_frames, avg_inter_frame_qindex); | ||
| 2706 | rc->gfu_boost = VPXMIN(MAX_GF_BOOST, arf_boost); | ||
| 2701 | rc->source_alt_ref_pending = 0; | 2707 | rc->source_alt_ref_pending = 0; |
| 2702 | } | 2708 | } |
| 2703 | 2709 | ||
| @@ -2742,18 +2748,17 @@ static void define_gf_group(VP9_COMP *cpi, int gf_start_show_idx) { · 38 unmodified lines | |||
| 2742 | 2748 | ||
| 2743 | rc->baseline_gf_interval = i - rc->source_alt_ref_pending; | 2749 | rc->baseline_gf_interval = i - rc->source_alt_ref_pending; |
| 2744 | 2750 | ||
| 2745 | // Reset the file position. | ||
| 2746 | reset_fpf_position(twopass, start_pos); | ||
| 2747 | |||
| 2748 | if (rc->source_alt_ref_pending) | 2751 | if (rc->source_alt_ref_pending) |
| 2749 | is_alt_ref_flash = detect_flash(twopass, rc->baseline_gf_interval); | 2752 | is_alt_ref_flash = detect_flash(twopass, rc->baseline_gf_interval); |
| 2750 | 2753 | ||
| 2751 | { | 2754 | { |
| 2755 | const double av_err = get_distribution_av_err(cpi, twopass); | ||
| 2756 | const double mean_mod_score = twopass->mean_mod_score; | ||
| 2752 | // If the first frame is a key frame or the overlay from a previous arf then | 2757 | // If the first frame is a key frame or the overlay from a previous arf then |
| 2753 | // the error score / cost of this frame has already been accounted for. | 2758 | // the error score / cost of this frame has already been accounted for. |
| 2754 | int start_idx = arf_active_or_kf ? 1 : 0; | 2759 | int start_idx = arf_active_or_kf ? 1 : 0; |
| 2755 | int num_show_frames = i; | 2760 | int num_coding_frames = i; |
| 2756 | for (j = start_idx; j < num_show_frames; ++j) { | 2761 | for (j = start_idx; j < num_coding_frames; ++j) { |
| 2757 | int show_idx = gf_start_show_idx + j; | 2762 | int show_idx = gf_start_show_idx + j; |
| 2758 | const FIRSTPASS_STATS *frame_stats = | 2763 | const FIRSTPASS_STATS *frame_stats = |
| 2759 | fps_get_frame_stats(first_pass_info, show_idx); | 2764 | fps_get_frame_stats(first_pass_info, show_idx); |