Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -2788,6 +2788,36 @@ editing the `conf` file in a text editor. Use the examples as reference.
</tr>
</table>

### amd_max_au_size

<table>
<tr>
<td>Description</td>
<td colspan="2">
Maximum encoded frame size (Access Unit) in bytes. When set to a non-zero value, the
encoder will cap the maximum frame size. This prevents oversized frames from exceeding
FEC shard limits (DATA_SHARDS_MAX=255), which otherwise causes FEC to be skipped for
those frames. This is especially important for Wi-Fi streaming where packet loss on
large unprotected frames leads to dropped frames and stuttering.
@note{This option only applies when using amdvce [encoder](#encoder).}
@note{Works with all rate control modes (CQP, CBR, VBR). Most beneficial with CQP
where frame sizes are otherwise unbounded.}
</td>
</tr>
<tr>
<td>Default</td>
<td colspan="2">@code{}

@endcode</td>
</tr>
<tr>
<td>Example</td>
<td colspan="2">@code{}
Copy link

Copilot AI Mar 29, 2026

Choose a reason for hiding this comment

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

This section documents the cap in bytes and implies it applies to all AMF codecs, but in FFmpeg the exposed "max_au_size" AVOption is for h264_amf/hevc_amf (in bits) and av1_amf doesn’t expose an equivalent option. Please update the docs to match the actual supported codecs and units, and clarify the default/disable behavior (e.g., unset vs 0 vs -1).

Suggested change
Maximum encoded frame size (Access Unit) in bytes. When set to a non-zero value, the
encoder will cap the maximum frame size. This prevents oversized frames from exceeding
FEC shard limits (DATA_SHARDS_MAX=255), which otherwise causes FEC to be skipped for
those frames. This is especially important for Wi-Fi streaming where packet loss on
large unprotected frames leads to dropped frames and stuttering.
@note{This option only applies when using amdvce [encoder](#encoder).}
@note{Works with all rate control modes (CQP, CBR, VBR). Most beneficial with CQP
where frame sizes are otherwise unbounded.}
</td>
</tr>
<tr>
<td>Default</td>
<td colspan="2">@code{}
@endcode</td>
</tr>
<tr>
<td>Example</td>
<td colspan="2">@code{}
Maximum encoded frame size (Access Unit) in <strong>bits</strong>. When set to a
positive, non-zero value, Sunshine configures the AMF encoder to cap the maximum frame
size. This prevents oversized frames from exceeding FEC shard limits
(DATA_SHARDS_MAX=255), which otherwise causes FEC to be skipped for those frames. This
is especially important for Wi-Fi streaming where packet loss on large unprotected
frames leads to dropped frames and stuttering.
@note{This option is forwarded to FFmpeg's @code{max_au_size} AVOption and only
applies when using the amdvce [encoder](#encoder) with H.264 or HEVC
(@code{h264_amf}/@code{hevc_amf}). It is not available for AV1 (@code{av1_amf}).}
@note{Leave this option unset to use the encoder default (no explicit cap). Non-positive
values are treated as "no limit" and should normally be avoided in favor of leaving the
option unset.}
@note{Works with all rate control modes (CQP, CBR, VBR). Most beneficial with CQP where
frame sizes are otherwise unbounded.}
</td>
</tr>
<tr>
<td>Default</td>
<td colspan="2">@code{}
# unset: do not configure max_au_size, use encoder default (no explicit cap)
# amd_max_au_size is disabled unless you set a positive value
@endcode</td>
</tr>
<tr>
<td>Example</td>
<td colspan="2">@code{}
# limit access unit size to 800000 bits

Copilot uses AI. Check for mistakes.
amd_max_au_size = 800000
@endcode</td>
</tr>
</table>

## VideoToolbox Encoder

### vt_coder
Expand Down
2 changes: 2 additions & 0 deletions src/config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,7 @@ namespace config {
(int) amd::quality_av1_e::balanced, // quality (av1)
0, // preanalysis
1, // vbaq
{}, // max_au_size (disabled by default)
(int) amd::coder_e::_auto, // coder
}, // amd

Expand Down Expand Up @@ -1129,6 +1130,7 @@ namespace config {
bool_f(vars, "amd_preanalysis", (bool &) video.amd.amd_preanalysis);
bool_f(vars, "amd_vbaq", (bool &) video.amd.amd_vbaq);
bool_f(vars, "amd_enforce_hrd", (bool &) video.amd.amd_enforce_hrd);
int_f(vars, "amd_max_au_size", video.amd.amd_max_au_size);
Copy link

Copilot AI Mar 29, 2026

Choose a reason for hiding this comment

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

This parses amd_max_au_size as an optional int but does not enforce non-negative values, and it will treat an explicit "0" as a configured value (so it will still be passed through to FFmpeg). If the intent is “0/empty disables”, consider normalizing values <= 0 to nullopt here (or validating a non-negative range) so downstream option application can skip setting the codec option entirely.

Suggested change
int_f(vars, "amd_max_au_size", video.amd.amd_max_au_size);
int_f(vars, "amd_max_au_size", video.amd.amd_max_au_size);
if (video.amd.amd_max_au_size && *video.amd.amd_max_au_size <= 0) {
video.amd.amd_max_au_size.reset();
}

Copilot uses AI. Check for mistakes.

int_f(vars, "vt_coder", video.vt.vt_coder, vt::coder_from_view);
int_f(vars, "vt_software", video.vt.vt_allow_sw, vt::allow_software_from_view);
Expand Down
1 change: 1 addition & 0 deletions src/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ namespace config {
std::optional<int> amd_quality_av1;
std::optional<int> amd_preanalysis;
std::optional<int> amd_vbaq;
std::optional<int> amd_max_au_size;
int amd_coder;
} amd;

Expand Down
3 changes: 3 additions & 0 deletions src/video.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -749,6 +749,7 @@ namespace video {
{"rc"s, &config::video.amd.amd_rc_av1},
{"usage"s, &config::video.amd.amd_usage_av1},
{"enforce_hrd"s, &config::video.amd.amd_enforce_hrd},
{"max_au_size"s, &config::video.amd.amd_max_au_size},
Copy link

Copilot AI Mar 29, 2026

Choose a reason for hiding this comment

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

FFmpeg’s av1_amf encoder does not expose an AVOption named "max_au_size" (unlike h264_amf/hevc_amf). Adding this option here means the cap won’t work for AV1 and may cause avcodec_open2 to fail with an unknown option when the setting is configured. Consider removing this option from the av1_amf option set (or gating it so it’s only applied for codecs that support it) and updating the UI/docs accordingly.

Suggested change
{"max_au_size"s, &config::video.amd.amd_max_au_size},

Copilot uses AI. Check for mistakes.
},
{}, // SDR-specific options
{}, // HDR-specific options
Expand Down Expand Up @@ -776,6 +777,7 @@ namespace video {
{"usage"s, &config::video.amd.amd_usage_hevc},
{"vbaq"s, &config::video.amd.amd_vbaq},
{"enforce_hrd"s, &config::video.amd.amd_enforce_hrd},
{"max_au_size"s, &config::video.amd.amd_max_au_size},
Copy link

Copilot AI Mar 29, 2026

Choose a reason for hiding this comment

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

The AMF "max_au_size" AVOption in FFmpeg for h264_amf/hevc_amf is specified in bits (and FFmpeg commonly uses -1 as the disable sentinel). The UI/docs describe this value as bytes and recommend 800000, which will be interpreted as ~100KB if passed through unchanged. Either convert bytes->bits before setting the codec option, or update the config/UI/docs to clearly use bits (and document the disable behavior).

Suggested change
{"max_au_size"s, &config::video.amd.amd_max_au_size},
{"max_au_size"s, []() {
// Config/UI use bytes; FFmpeg AMF option expects bits. Negative disables (maps to -1).
const int value_bytes = config::video.amd.amd_max_au_size;
if (value_bytes < 0) {
return -1;
}
return value_bytes * 8;
}},

Copilot uses AI. Check for mistakes.
{"level"s, [](const config_t &cfg) {
auto size = cfg.width * cfg.height;
// For 4K and below, try to use level 5.1 or 5.2 if possible
Expand Down Expand Up @@ -813,6 +815,7 @@ namespace video {
{"usage"s, &config::video.amd.amd_usage_h264},
{"vbaq"s, &config::video.amd.amd_vbaq},
{"enforce_hrd"s, &config::video.amd.amd_enforce_hrd},
{"max_au_size"s, &config::video.amd.amd_max_au_size},
Copy link

Copilot AI Mar 29, 2026

Choose a reason for hiding this comment

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

Same as above: the FFmpeg "max_au_size" option is in bits. Passing the config value through as-is while documenting bytes will lead to an incorrect cap. Consider converting bytes->bits (and treating 0/empty as unset) before setting this option.

Suggested change
{"max_au_size"s, &config::video.amd.amd_max_au_size},
{"max_au_size"s, []() {
const auto bytes = config::video.amd.amd_max_au_size;
if (bytes <= 0) {
return 0;
}
return bytes * 8;
}},

Copilot uses AI. Check for mistakes.
},
{}, // SDR-specific options
{}, // HDR-specific options
Expand Down
1 change: 1 addition & 0 deletions src_assets/common/assets/web/config.html
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,7 @@ <h1 class="my-4">{{ $t('config.configuration') }}</h1>
"amd_preanalysis": "disabled",
"amd_vbaq": "enabled",
"amd_coder": "auto",
"amd_max_au_size": "",
},
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,14 @@ const config = ref(props.config)
v-model="config.amd_enforce_hrd"
default="false"
></Checkbox>

<!-- AMF Max AU Size -->
<div class="mb-3">
<label for="amd_max_au_size" class="form-label">{{ $t('config.amd_max_au_size') }}</label>
<input type="number" class="form-control" id="amd_max_au_size"
placeholder="0" min="0" v-model="config.amd_max_au_size" />
<div class="form-text">{{ $t('config.amd_max_au_size_desc') }}</div>
</div>
</div>
</div>
</div>
Expand Down
2 changes: 2 additions & 0 deletions src_assets/common/assets/web/public/assets/locale/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,8 @@
"amd_coder_desc": "Allows you to select the entropy encoding to prioritize quality or encoding speed. H.264 only.",
"amd_enforce_hrd": "AMF Hypothetical Reference Decoder (HRD) Enforcement",
"amd_enforce_hrd_desc": "Increases the constraints on rate control to meet HRD model requirements. This greatly reduces bitrate overflows, but may cause encoding artifacts or reduced quality on certain cards.",
"amd_max_au_size": "AMF Max AU Size",
"amd_max_au_size_desc": "Maximum encoded frame size in bytes (0 or empty = disabled). Caps the largest frame the encoder can produce, preventing oversized frames from exceeding FEC limits. Recommended value: 800000 for Wi-Fi streaming with CQP mode.",
Copy link

Copilot AI Mar 29, 2026

Choose a reason for hiding this comment

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

The description says the value is in bytes and recommends 800000, but FFmpeg’s AMF "max_au_size" option for h264_amf/hevc_amf is in bits (and av1_amf doesn’t support this option at all). Please align the UI text with the actual behavior (units, recommended value, and which codecs it applies to) to avoid users configuring an ineffective or failing setting.

Suggested change
"amd_max_au_size_desc": "Maximum encoded frame size in bytes (0 or empty = disabled). Caps the largest frame the encoder can produce, preventing oversized frames from exceeding FEC limits. Recommended value: 800000 for Wi-Fi streaming with CQP mode.",
"amd_max_au_size_desc": "Maximum encoded frame size in bits for H.264/HEVC AMF encoders (0 or empty = disabled). Caps the largest frame the encoder can produce, preventing oversized frames from exceeding FEC limits. Recommended value: 6400000 bits (equivalent to 800000 bytes) for Wi-Fi streaming with CQP mode.",

Copilot uses AI. Check for mistakes.
"amd_preanalysis": "AMF Preanalysis",
"amd_preanalysis_desc": "This enables rate-control preanalysis, which may increase quality at the expense of increased encoding latency.",
"amd_quality": "AMF Quality",
Expand Down
Loading