Skip to content

Add frame level on/off bawp - #5156

Open
jianle973 wants to merge 2 commits into
AOMediaCodec:av2-encfrom
jianle973:fast-bawp
Open

Add frame level on/off bawp#5156
jianle973 wants to merge 2 commits into
AOMediaCodec:av2-encfrom
jianle973:fast-bawp

Conversation

@jianle973

@jianle973 jianle973 commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Enable frame level bawp based on histogram.

33 frame RA results (speed 1) on v15: +0.01% bit rate with 98.5% encoding time.

+---------+--------+-------+-------+-------+----------+----------+
| Summary | Y | U | V | YUV | Enc-time | Dec-time |
+---------+--------+-------+-------+-------+----------+----------+
| A1 | +0.01% | +0.02% | +0.02% | +0.02% | 99.42% | 100.70% |
| A2 | +0.01% | -0.02% | +0.13% | +0.02% | 99.34% | 99.96% |

+---------+--------+-------+-------+-------+----------+----------+

enable frame level bwap based on histogram
Comment thread cmake/avm_config_defaults.cmake Outdated
Comment thread av2/av2_cx_iface.c Outdated
Comment thread av2/encoder/encoder.h Outdated

#if CONFIG_FAST_BAWP
// Indicates whenter frame level on/off fast bawp is used.
int enable_fast_bawp;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment: It is better to add enable_fast_bawp as a new speed feature, instead of setting it in oxcf.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, thanks!

Comment thread av2/encoder/encodeframe.c Outdated
int numValues = 1 << cm->seq_params.bit_depth;

int32_t *curr_hist = (int32_t *)avm_calloc(numValues, sizeof(int32_t));
int32_t *ref_hist = (int32_t *)avm_calloc(numValues, sizeof(int32_t));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Should we check whether the malloc succeeded, using CHECK_MEM_ERROR?
  2. Also, even though this is a frame-level allocation/free, should we instead allocate and free it when the encoder is created and released? That would avoid the alloc/free on every frame and every pass.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Added CHECK_MEM_ERROR.
  2. Since the memory size is small, I still keep it as frame level operation.

Comment thread av2/encoder/encodeframe.c Outdated
}

#if CONFIG_FAST_BAWP
void get_histogram(int32_t *hist, const YV12_BUFFER_CONFIG *buf, int width,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we declare it as static if it's only used in this source file?

@jianle973 jianle973 Jul 25, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, static is added.

Comment thread av2/encoder/encodeframe.c
}

if (diffHist > hist_diff_thres) {
enable_curr_pic_bawp = 1;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Once if (diffHist > hist_diff_thres) is satisfied, should we return here directly, to save the cost of the further histogram computation and checks? Based on the logic, in any case where diffHist > hist_diff_thres, enable_curr_pic_bawp would always be true, right? If yes, then we do not need enable_curr_pic_bawp

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, we should return immediately once (diffHist > hist_diff_thres) meets. In the code, this logic is fulfilled by

    if (diff_hist > hist_diff_thres) {
      enable_curr_pic_bawp = 1;
      **break;**
    }

Comment thread av2/encoder/encodeframe.c Outdated
const RefCntBuffer *ref_buf = get_ref_frame_buf(cm, rf);
if (ref_buf != NULL) {
int ref_width = ref_buf->mi_cols * 4;
int ref_height = ref_buf->mi_rows * 4;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For resolutions whose dimensions aren't multiples of 4, would the pixel values outside the frame (I can't recall whether the area outside the frame is padded or not) producing a wrong histogram and leading to a wrong decision?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my understanding, the pixels outside the input frames boundary are padded, and the reference also stored in the padded size. The padded areas also need to be encoded. It might be more accurate to also count them.

Comment thread av2/encoder/encodeframe.c Outdated

int width = source->y_width;
int height = source->y_height;
int num_samples = width * height;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use const if the variable's value won't be changed. Same comment for other variables inside this function.

Comment thread av2/encoder/encodeframe.c Outdated
int ref_height = ref_buf->mi_rows * 4;

if (width == ref_width && height == ref_height) {
memset(ref_hist, 0, sizeof(int32_t) * numValues);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's use the AVM coding style for numValues and diffHist.

Comment thread av2/encoder/encodeframe.c Outdated
}
}

int av2_set_on_bawp_picture_level(AV2_COMP *cpi) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change it from AV2_COMP *cpi to const AV2_COMP *const cpi, since we don't need to modify its members?

@jianle973

Copy link
Copy Markdown
Contributor Author

Thanks @yeqing-wu for reviewing the PR. I have tried to address all the comments in the new commit.

@yeqing-wu yeqing-wu left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

It is required to provide the anchor commit number and the A1/A2 results in the commit message. I think you can put this info in the PR conversation message. To prevent GitHub from messing up your table, you can wrap it with ``` before and after, like:

+---------+--------+-------+-------+-------+----------+----------+
| Summary |   Y    |   U   |   V   |  YUV  | Enc-time | Dec-time |
+---------+--------+-------+-------+-------+----------+----------+
| A1      | -0.02% | 0.24% | 0.21% | 0.00% | 97.8%    | 100.5%   |
| A2      | 0.10%  | 0.15% | 0.03% | 0.09% | 95.8%    | 99.8%    |
+---------+--------+-------+-------+-------+----------+----------+

@leolzhao

Copy link
Copy Markdown
Contributor

Please add the separate class A1 and A2 results in the MR message? @jianle973

@jianle973

Copy link
Copy Markdown
Contributor Author

33 frames results (speed 1) as follows:

+---------+--------+-------+-------+-------+----------+----------+
| Summary | Y | U | V | YUV | Enc-time | Dec-time |
+---------+--------+-------+-------+-------+----------+----------+
| A1 | +0.01% | +0.02% | +0.02% | +0.02% | 99.42% | 100.70% |
| A2 | +0.01% | -0.02% | +0.13% | +0.02% | 99.34% | 99.96% |

+---------+--------+-------+-------+-------+----------+----------+

@yeqing-wu

yeqing-wu commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Since it doesn’t meet the acceptance criteria for speed 1, should we move it to speed 4? And what is the commit ID of the anchor?

@leolzhao

Copy link
Copy Markdown
Contributor

Since it doesn’t meet the acceptance criteria for speed 1, should we move it to speed 4?

Yes, we can enable it for speed 4 if the resutls with cpu-used = 4 is similar or better.

@jianle973

Copy link
Copy Markdown
Contributor Author

Since it doesn’t meet the acceptance criteria for speed 1, should we move it to speed 4?

Yes, we can enable it for speed 4 if the resutls with cpu-used = 4 is similar or better.

It was 98.5% encoding time when I tested it on top v15. Not sure what's the problem. The running time deviation on our cluster could be the reason.

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.

5 participants