Project

General

Profile

Bug #5701

Fix for: VAAPI h264 encoding: bad picture quality for a minute

Added by Stefan Dietzel about 1 year ago. Updated about 1 year ago.

Status:
New
Priority:
Normal
Category:
Transcoding
Target version:
-
Start date:
2019-08-06
Due date:
% Done:

0%

Estimated time:
Found in version:
tvheadend_4.3-1804~gebb096804
Affected Versions:

Description

Hi,
I worked through the vaapi code and found a solution for the bad picture quality in h264 and hevc encoding when using vaapi via av-lib.
The following changes needed to be done in /src/transcoding/codec/codecs/libs/vaapi.c :

For H.264:

static int
tvh_codec_profile_vaapi_h264_open(tvh_codec_profile_vaapi_t *self,
                                  AVDictionary **opts)
{
    // bit_rate or qp
    if (self->bit_rate) {
        AV_DICT_SET_BIT_RATE(opts, self->bit_rate);
        AV_DICT_SET_INT(opts, "maxrate", (self->bit_rate) * 1000, AV_DICT_DONT_OVERWRITE);
        AV_DICT_SET_INT(opts, "bufsize", ((self->bit_rate) * 1000) * 2, AV_DICT_DONT_OVERWRITE);
        AV_DICT_SET(opts, "force_key_frames", "expr:gte(t,n_forced*3)", AV_DICT_DONT_OVERWRITE);
    }
    else {
        AV_DICT_SET_QP(opts, self->qp, 20);
    }
    AV_DICT_SET_INT(opts, "quality", self->quality, 0);
    return 0;
}

For HEVC:

static int
tvh_codec_profile_vaapi_hevc_open(tvh_codec_profile_vaapi_t *self,
                                  AVDictionary **opts)
{
    // bit_rate or qp
    if (self->bit_rate) {
        AV_DICT_SET_BIT_RATE(opts, self->bit_rate);
        AV_DICT_SET_INT(opts, "maxrate", (self->bit_rate) * 1000, AV_DICT_DONT_OVERWRITE);
        AV_DICT_SET_INT(opts, "bufsize", ((self->bit_rate) * 1000) * 2, AV_DICT_DONT_OVERWRITE);
        AV_DICT_SET(opts, "force_key_frames", "expr:gte(t,n_forced*3)", AV_DICT_DONT_OVERWRITE);
    }
    else {
        AV_DICT_SET_QP(opts, self->qp, 25);
    }
    // max_b_frames
    // XXX: remove when b-frames handling in vaapi_encode is fixed
    AV_DICT_SET_INT(opts, "bf", 0, 0);

    return 0;
}

In both functions the following lines needed to be added:

        AV_DICT_SET_INT(opts, "maxrate", (self->bit_rate) * 1000, AV_DICT_DONT_OVERWRITE);
        AV_DICT_SET_INT(opts, "bufsize", ((self->bit_rate) * 1000) * 2, AV_DICT_DONT_OVERWRITE);
        AV_DICT_SET(opts, "force_key_frames", "expr:gte(t,n_forced*3)", AV_DICT_DONT_OVERWRITE);

After this change picture quality is very good from the first second on.
Because I an not having a git account I cannot commit those changes. Maybe Jaroslav or someone else can do this.

Best regards
Stefan

History

#1

Updated by Stefan Dietzel about 1 year ago

I manged it to create a pull request on github.
https://github.com/tvheadend/tvheadend/pull/1294

Because this was the first time for me, I hope I did it correct.

#2

Updated by Stefan Dietzel about 1 year ago

I have tested my patch for some days now and found no problems. I guess it can be applied to the project.

#3

Updated by Stefan Dietzel about 1 year ago

@Jaroslav
Can you add my pull request (or the src itself) to the project?

At the moment I have to reimplement this fix for every new version you release.

Thx.

Also available in: Atom PDF