Skip to content

Commit

Permalink
Fix rate control for AMD cards using VAAPI
Browse files Browse the repository at this point in the history
  • Loading branch information
cgutman committed Jul 8, 2024
1 parent 5cea1e1 commit e8f6f7c
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 0 deletions.
9 changes: 9 additions & 0 deletions src/platform/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ struct sockaddr;
struct AVFrame;
struct AVBufferRef;
struct AVHWFramesContext;
struct AVCodecContext;
struct AVDictionary;

// Forward declarations of boost classes to avoid having to include boost headers
// here, which results in issues with Windows.h and WinSock2.h include order.
Expand Down Expand Up @@ -398,6 +400,13 @@ namespace platf {
virtual void
init_hwframes(AVHWFramesContext *frames) {};

/**
* @brief Provides a hook for allow platform-specific code to adjust codec options.
* @note Implementations may set or modify codec options prior to codec initialization.
*/
virtual void
init_codec_options(AVCodecContext *ctx, AVDictionary *options) {};

/**
* @brief Prepare to derive a context.
* @note Implementations may make modifications required before context derivation
Expand Down
10 changes: 10 additions & 0 deletions src/platform/linux/vaapi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,16 @@ namespace va {
return 0;
}

void
init_codec_options(AVCodecContext *ctx, AVDictionary *options) override {

Check warning on line 133 in src/platform/linux/vaapi.cpp

View check run for this annotation

Codecov / codecov/patch

src/platform/linux/vaapi.cpp#L133

Added line #L133 was not covered by tests
// Don't set the RC buffer size when using H.264 on Intel GPUs. It causes
// major encoding quality degradation.
auto vendor = vaQueryVendorString(va_display);

Check warning on line 136 in src/platform/linux/vaapi.cpp

View check run for this annotation

Codecov / codecov/patch

src/platform/linux/vaapi.cpp#L136

Added line #L136 was not covered by tests
if (ctx->codec_id != AV_CODEC_ID_H264 || (vendor && !strstr(vendor, "Intel"))) {
ctx->rc_buffer_size = ctx->bit_rate * ctx->framerate.den / ctx->framerate.num;

Check warning on line 138 in src/platform/linux/vaapi.cpp

View check run for this annotation

Codecov / codecov/patch

src/platform/linux/vaapi.cpp#L138

Added line #L138 was not covered by tests
}
}

int
set_frame(AVFrame *frame, AVBufferRef *hw_frames_ctx_buf) override {
this->hwframe.reset(frame);
Expand Down
4 changes: 4 additions & 0 deletions src/video.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -859,6 +859,7 @@ namespace video {
std::make_optional<encoder_t::option_t>("qp"s, &config::video.qp),
"h264_vaapi"s,
},
// RC buffer size will be set in platform code if supported
LIMITED_GOP_SIZE | PARALLEL_ENCODING | SINGLE_SLICE_ONLY | NO_RC_BUF_LIMIT
};
#endif
Expand Down Expand Up @@ -1610,6 +1611,9 @@ namespace video {
return nullptr;
}

// Allow the encoding device a final opportunity to set/unset or override any options
encode_device->init_codec_options(ctx.get(), options);

if (auto status = avcodec_open2(ctx.get(), codec, &options)) {
char err_str[AV_ERROR_MAX_STRING_SIZE] { 0 };

Expand Down

0 comments on commit e8f6f7c

Please sign in to comment.