Skip to content

Reuse counterparts in partition search - #5524

Merged
urvangjoshi merged 1 commit into
AOMediaCodec:av2-encfrom
chengchen-google:s9-A-v3
Oct 16, 2026
Merged

urvangjoshi merged 1 commit into
AOMediaCodec:av2-encfrom
chengchen-google:s9-A-v3

Conversation

@chengchen-google

@chengchen-google chengchen-google commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

Extend av2_look_for_counterpart_block() to reuse evaluated
PARTITION_SPLIT quadrants (Q01, Q10, Q11) during HORZ -> VERT
sub-partition search when all preceding quadrants in raster order
match in partitioning and RD cost, and prefer valid (non-aborted)
candidates in counterpart_from_different_partition().

Performance on RA CTC, Class A1 (4K, 17 frames) + Class A2 (1080p,
33 frames), Anchor: 14fde9b

  Speed  Class   PSNR-Y   PSNR-YUV  VMAF-NEG  EncTime
    1     A1     -0.02%    -0.01%    -0.00%   -1.24%
    1     A2     -0.00%    -0.01%    +0.00%   -1.54%
    1     All    -0.01%    -0.01%    +0.00%   -1.45%

    2     A1     +0.01%    -0.02%    +0.20%   -0.08%
    2     A2     -0.03%    -0.02%    -0.12%   -0.18%
    2     All    -0.02%    -0.02%    -0.02%   -0.15%

    3     A1     +0.04%    +0.05%    +0.11%   -0.18%
    3     A2     -0.01%    -0.01%    -0.00%   +0.58%
    3     All    +0.00%    +0.01%    +0.03%   +0.35%

    4     A1     +0.08%    +0.09%    +0.07%   -0.43%
    4     A2     +0.03%    +0.02%    +0.13%   +0.01%
    4     All    +0.05%    +0.04%    +0.11%   -0.12%

    5     A1     -0.02%    -0.04%    +0.00%   +0.63%
    5     A2     +0.02%    +0.01%    -0.03%   -0.16%
    5     All    +0.01%    -0.01%    -0.02%   +0.08%

    6     A1     -0.00%    -0.03%    +0.09%   -1.78%
    6     A2     -0.04%    -0.03%    -0.05%   -0.40%
    6     All    -0.03%    -0.03%    -0.01%   -0.81%

STATS_CHANGED

@chengchen-google
chengchen-google force-pushed the s9-A-v3 branch 2 times, most recently from 2cd2bdf to 80dc5f1 Compare October 13, 2026 16:39
@urvangjoshi

Copy link
Copy Markdown
Contributor

@chengchen-google : from the title "redundant partition search and dry-run evaluations", my first impression was that we are removing redundant computations without changing output.
But looks like there is some loss as well.

Can you clarify if any of the 3 changes listed are neutral / near-neutral? And which changes actually result in a loss?

Then, perhaps I can review carefully to see if there are improvements possible?

@urvangjoshi
urvangjoshi self-requested a review October 13, 2026 18:19
@chengchen-google

Copy link
Copy Markdown
Contributor Author

@chengchen-google : from the title "redundant partition search and dry-run evaluations", my first impression was that we are removing redundant computations without changing output. But looks like there is some loss as well.

Can you clarify if any of the 3 changes listed are neutral / near-neutral? And which changes actually result in a loss?

Then, perhaps I can review carefully to see if there are improvements possible?

Stats change is expected. The change aims to reuse the same partition decisions for the block that its counterpart is previously searched. For example:

SPLIT
+---+---+
|   |   |
+---+---+
|   |   |
+---+---+

+------+------+
|  Q00 | Q01  |
+------+------+
|  Q10 | Q11  |
+------+------+

HORZ
+-------+------+
|  Q00  | Q01  |
+-------+------+
|              |
+-------+------+

If SPLIT has been searched, later in the HORZ --> VERT search, qudrants Q00 and Q01 could reuse the same decision from SPLIT. So, it is a fast method, not identical.
Before the change, Q00 will be reused, but Q01 will not. This change extends that.

@chengchen-google chengchen-google changed the title Reduce redundant partition search and dry-run evaluations Reduce repeated partition search and dry-run evaluations Oct 13, 2026
@chengchen-google
chengchen-google force-pushed the s9-A-v3 branch 3 times, most recently from 4039bcc to 73b4279 Compare October 13, 2026 22:12
@urvangjoshi

Copy link
Copy Markdown
Contributor

@chengchen-google : as discussed offline, it will be good to know a breakdown results of different parts in this PR -- to see how much speed-up / loss each part has. Thanks!

@chengchen-google

Copy link
Copy Markdown
Contributor Author

@chengchen-google : as discussed offline, it will be good to know a breakdown results of different parts in this PR -- to see how much speed-up / loss each part has. Thanks!

Hi @urvangjoshi , as discussed offline, the PR consists of two parts.
Part_1: reuse the counter part when it is previously searched.
Part_2: pruning in the rectangular partition search using depth information from previously searched subblocks.
I measured the PR and Part 1 and 2 on top of the most recent anchor 14fde9b.
The tradeoff is shown below:

```
  Speed  Bar  Part_1            Part_2           Total      Ratio  Decision
            (bd-rate/speedup) 
      1   35  -0.01%/-1.45%  +0.16%/-4.46%  +0.15%/-5.84%   38.9  on
      2   30  -0.02%/-0.15%  +0.13%/-3.40%  +0.11%/-3.55%   32.3  on
      3   25  +0.01%/+0.35%  +0.08%/-1.82%  +0.09%/-1.48%   16.4  off
      4   20  +0.04%/-0.12%  +0.18%/-0.83%  +0.22%/-0.95%    4.3  off
      5   15  -0.01%/+0.08%  +0.14%/-3.53%  +0.13%/-3.45%   26.5  on
      6   10  -0.03%/-0.81%  +0.16%/-1.52%  +0.13%/-2.32%   17.8  on
```

The numbers have changed significantly as compared to the initial submission when the anchor is 24ff468.
Speed 3 and 4 no longer satisfy the tradeoff bar. So I added a speed feature part_sf->reduce_redundant_partition_search to guard the new feature. Based on the test results, it is turned on for speed 1, 2, 5, 6.
With the speed feature, it is easy for us to turn on/off the feature completely. Good for future tuning.

In addition, we discussed offline that "skip the non-root DRY_RUN_NORMAL pass on the last sub-block (except for LUMA_PART in inter-frame INTRA_REGION) right before context restoration" seems unnecessary. I agree that this part is not critical for speed, but could be misleading. I deleted this part in the updated version.

@chengchen-google chengchen-google changed the title Reduce repeated partition search and dry-run evaluations Faster partition: reuse counterparts and terminate early with subblock info Oct 15, 2026
@urvangjoshi

Copy link
Copy Markdown
Contributor

@chengchen-google : as discussed offline, it will be good to know a breakdown results of different parts in this PR -- to see how much speed-up / loss each part has. Thanks!

Hi @urvangjoshi , as discussed offline, the PR consists of two parts. Part_1: reuse the counter part when it is previously searched. Part_2: pruning in the rectangular partition search using depth information from previously searched subblocks. I measured the PR and Part 1 and 2 on top of the most recent anchor 14fde9b. The tradeoff is shown below:

Speed Bar Part_1 Part_2 Total Ratio Decision
(bd-rate/speedup)
1 35 -0.01%/-1.45% +0.16%/-4.46% +0.15%/-5.84% 38.9 on
2 30 -0.02%/-0.15% +0.13%/-3.40% +0.11%/-3.55% 32.3 on
3 25 +0.01%/+0.35% +0.08%/-1.82% +0.09%/-1.48% 16.4 off
4 20 +0.04%/-0.12% +0.18%/-0.83% +0.22%/-0.95% 4.3 off
5 15 -0.01%/+0.08% +0.14%/-3.53% +0.13%/-3.45% 26.5 on
6 10 -0.03%/-0.81% +0.16%/-1.52% +0.13%/-2.32% 17.8 on

The numbers have changed significantly as compared to the initial submission when the anchor is 24ff468. Speed 3 and 4 no longer satisfy the tradeoff bar. So I added a speed feature part_sf->reduce_redundant_partition_search to guard the new feature. Based on the test results, it is turned on for speed 1, 2, 5, 6. With the speed feature, it is easy for us to turn on/off the feature completely. Good for future tuning.

Thanks for the breakdown numbers!

A few things I noticed:

  • If I compute the ratio for part 2 in isolation, it doesn't seem to meet the bar at any speed (except speed 5 -- which maybe an aberration).
  • We typically enable speed features for speed >= N always, and don't do something like enable for speed <= N and speed >= M -- as such behavior likely means some instability / overfitting.
  • Also, for the combined numbers, for speed 1 and 2, the ratio doesn't meet the bar for some testsets (looking at PR description).

So, I'll suggest trimming the PR down to just part 1, as the idea seems both theoretically sound and practically verified to have minimal loss. (Remove part 2 from this PR).

You can later tune / re-test part 2 in future PRs.

In addition, we discussed offline that "skip the non-root DRY_RUN_NORMAL pass on the last sub-block (except for LUMA_PART in inter-frame INTRA_REGION) right before context restoration" seems unnecessary. I agree that this part is not critical for speed, but could be misleading. I deleted this part in the updated version.

Actually, thought more about this and there maybe something to this idea -- but let's discuss and we can create a PR separately for this part later if it makes sense.

@chengchen-google chengchen-google changed the title Faster partition: reuse counterparts and terminate early with subblock info Reuse counterparts in partition search Oct 16, 2026
@chengchen-google

Copy link
Copy Markdown
Contributor Author

I trimmed the PR to contain the part 1, reusing the counterpart in partition search.

1. Extend av2_look_for_counterpart_block() to reuse evaluated
   PARTITION_SPLIT quadrants (Q01, Q10, Q11) during HORZ -> VERT
   sub-partition search when all preceding quadrants in raster order
   match in partitioning and RD cost, and prefer valid (non-aborted)
   candidates in counterpart_from_different_partition().
2. In av2_rd_pick_partition(), factor counterpart eligibility into
   can_reuse_counterpart_block() and reject counterpart blocks whose RD
   cost exceeds best_rdc before copying the PC_TREE or running
   encode_sb(DRY_RUN_NORMAL).

Performance on RA CTC, Class A1 (4K, 17 frames) + Class A2 (1080p,
33 frames), Anchor: 14fde9b

```
  Speed  Class   PSNR-Y   PSNR-YUV  VMAF-NEG  EncTime
    1     A1     -0.02%    -0.01%    -0.00%   -1.24%
    1     A2     -0.00%    -0.01%    +0.00%   -1.54%
    1     All    -0.01%    -0.01%    +0.00%   -1.45%

    2     A1     +0.01%    -0.02%    +0.20%   -0.08%
    2     A2     -0.03%    -0.02%    -0.12%   -0.18%
    2     All    -0.02%    -0.02%    -0.02%   -0.15%

    3     A1     +0.04%    +0.05%    +0.11%   -0.18%
    3     A2     -0.01%    -0.01%    -0.00%   +0.58%
    3     All    +0.00%    +0.01%    +0.03%   +0.35%

    4     A1     +0.08%    +0.09%    +0.07%   -0.43%
    4     A2     +0.03%    +0.02%    +0.13%   +0.01%
    4     All    +0.05%    +0.04%    +0.11%   -0.12%

    5     A1     -0.02%    -0.04%    +0.00%   +0.63%
    5     A2     +0.02%    +0.01%    -0.03%   -0.16%
    5     All    +0.01%    -0.01%    -0.02%   +0.08%

    6     A1     -0.00%    -0.03%    +0.09%   -1.78%
    6     A2     -0.04%    -0.03%    -0.05%   -0.40%
    6     All    -0.03%    -0.03%    -0.01%   -0.81%
```

STATS_CHANGED

Change-Id: I4853f5b501a06f98446899c2253eb88b7a2acb3f
@urvangjoshi
urvangjoshi merged commit 39258c2 into AOMediaCodec:av2-enc Oct 16, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants