-
Notifications
You must be signed in to change notification settings - Fork 254
Clean up encoder settings update during encoding #1070
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Clean up encoder settings update during encoding #1070
Conversation
d22bfd2 to
6976e49
Compare
|
@tongyuantongyu Yuan, please review. Thanks. I reviewed your recent changes carefully and made these adjustments. |
Clean up the changes made in the following two pull requests to support updating encoder settings during encoding: AOMediaCodec#1033 AOMediaCodec#1058 In particular, restore the aomCodecEncodeImage() function in src/codec_aom.c to its original structure, plus a new block of code to handle encoder changes. Rename some functions and data members. Edit some comments and messages. In the avifEncoderChange enum, left-shift the unsigned int constant 1u because if we left-shift the signed int constant 1 by 31 bits, it will be shifted into the sign bit. Other miscellaneous cosmetic changes. AOMediaCodec#761
6976e49 to
404ab2f
Compare
wantehchang
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yuan: I annotated some changes in this pull request.
| int speed; | ||
| // changeable encoder settings. | ||
| int keyframeInterval; // How many frames between automatic forced keyframes; 0 to disable (default). | ||
| uint64_t timescale; // timescale of the media (Hz) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Commonly used members are listed before rarely used members.
| AVIF_ENCODER_CHANGE_TILE_ROWS_LOG2 = (1 << 4), | ||
| AVIF_ENCODER_CHANGE_TILE_COLS_LOG2 = (1 << 5), | ||
|
|
||
| AVIF_ENCODER_CHANGE_CODEC_SPECIFIC = (1 << 31) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Google's internal ClangTidy check warns that 1 << 31 shifts the 1 to the sign bit of a signed int.
| unsigned int aomUsage = AOM_USAGE_GOOD_QUALITY; | ||
| int aomCpuUsed = -1; | ||
| avifBool lossless = AVIF_FALSE; | ||
| avifBool quantizerUpdated = AVIF_FALSE; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I restored this function to its original structure. There is only one if (!codec->internal->encoderInitialized) block now (at line 537).
| } | ||
| codec->internal->encoderInitialized = AVIF_TRUE; | ||
| } else if (encoderChanges) { | ||
| } else { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This else block handles the "update config" case after the encoder has been initialized.
Please review this else block carefully.
| aom_codec_error_detail(&codec->internal->encoder)); | ||
| return AVIF_RESULT_UNKNOWN_ERROR; | ||
| } | ||
| codec->internal->encoderInitialized = AVIF_TRUE; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that we must set codec->internal->encoderInitialized to true immediately after a successful aom_codec_enc_init() call, because we also check codec->internal->encoderInitialized to determine if aom_codec_destroy(codec->internal->encoder) should be called:
#if defined(AVIF_CODEC_AOM_ENCODE)
if (codec->internal->encoderInitialized) {
aom_codec_destroy(&codec->internal->encoder);
}
#endif
Perhaps this should be documented better.
| static avifBool avifEncoderSettingsChanged(const avifEncoder * encoder, avifEncoderChanges * encoderChanges) | ||
| // This function detects changes made on avifEncoder. It returns true on success (i.e., if every | ||
| // change is valid), or false on failure (i.e., if any setting that can't change was changed). It | ||
| // reports detected changes in encoderChanges. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I edited this comment. Please check if the comment is accurate.
|
|
||
| avifEncoderChanges encoderChanges = 0; | ||
| if (!avifEncoderSettingsChanged(encoder, &encoderChanges)) { | ||
| avifEncoderChanges encoderChanges; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that I removed the initialization of this variable, to test that the avifEncoderDetectChanges() call below sets its output parameter properly.
| avifROData* out) { | ||
| auto reader = reinterpret_cast<AvifIOLimitedReader*>(io); | ||
|
|
||
| if (offset > UINT64_MAX - size) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This check detects overflow of the addition offset + size at line 226.
| ((cfg->rc_min_quantizer == AVIF_QUANTIZER_LOSSLESS) && (cfg->rc_max_quantizer == AVIF_QUANTIZER_LOSSLESS)); | ||
| aom_codec_control(&codec->internal->encoder, AV1E_SET_LOSSLESS, lossless); | ||
| } | ||
| if (quantizerUpdated || dimensionsChanged) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For now using quantizerUpdated here is fine, but if more options are added, we may need a dedicated cfgUpdated here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right. The quantizerUpdated || dimensionsChanged condition here detects whether any fields (currently g_w, g_h, rc_min_quantizer, and rc_max_quantizer) in cfg are updated. We can replace it with a dedicated cfgUpdated boolean flag. Note that we still need quantizerUpdated for the code at lines 808-819 below.
|
LGTM. Thanks for the update. |
wantehchang
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yuan: Thank you for the review. I am wondering if you can approve this pull request using the GitHub UI.
If you select the "Files changed" tab when viewing this PR, do you see a green "Review changes" or "Finish your review" drop-down menu on the right?
In that menu, you can check the "Approve" radio button and hit the "Submit review" button.
| ((cfg->rc_min_quantizer == AVIF_QUANTIZER_LOSSLESS) && (cfg->rc_max_quantizer == AVIF_QUANTIZER_LOSSLESS)); | ||
| aom_codec_control(&codec->internal->encoder, AV1E_SET_LOSSLESS, lossless); | ||
| } | ||
| if (quantizerUpdated || dimensionsChanged) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right. The quantizerUpdated || dimensionsChanged condition here detects whether any fields (currently g_w, g_h, rc_min_quantizer, and rc_max_quantizer) in cfg are updated. We can replace it with a dedicated cfgUpdated boolean flag. Note that we still need quantizerUpdated for the code at lines 808-819 below.
tongyuantongyu
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am wondering if you can approve this pull request using the GitHub UI.
Got it.
Clean up the changes made in the following two pull requests to support
updating encoder settings during encoding:
#1033
#1058
In particular, restore the aomCodecEncodeImage() function in
src/codec_aom.c to its original structure, plus a new block of code to
handle encoder changes.
Rename some functions and data members. Edit some comments and messages.
In the avifEncoderChange enum, left-shift the unsigned int constant 1u
because if we left-shift the signed int constant 1 by 31 bits, it will
be shifted into the sign bit.
Other miscellaneous cosmetic changes.
#761