After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 786320 - vaapih264enc: disable periodic keyframe
vaapih264enc: disable periodic keyframe
Status: RESOLVED FIXED
Product: GStreamer
Classification: Platform
Component: gstreamer-vaapi
git master
Other Linux
: Normal enhancement
: 1.13.90
Assigned To: GStreamer Maintainers
GStreamer Maintainers
Depends on:
Blocks:
 
 
Reported: 2017-08-15 13:37 UTC by Matteo Valdina
Modified: 2018-02-19 21:39 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
patch to increase max period_keyframe (1.09 KB, patch)
2017-08-15 13:37 UTC, Matteo Valdina
needs-work Details | Review
Patch for extend max value for periodic key frame. (3.31 KB, patch)
2017-12-13 14:26 UTC, Matteo Valdina
none Details | Review
Patch for extend max value for periodic key frame (G_MAXUINT32). (5.72 KB, patch)
2018-02-15 21:14 UTC, Matteo Valdina
none Details | Review
Patch for extend max value for periodic key frame (G_MAXUINT32 cleanup). (5.39 KB, patch)
2018-02-16 13:15 UTC, Matteo Valdina
committed Details | Review

Description Matteo Valdina 2017-08-15 13:37:41 UTC
Created attachment 357627 [details] [review]
patch to increase max period_keyframe

Current implementation of vaapih264enc enforces a keyframe each 300 frames at maxinum.

This is translated to an IDR each 10 seconds at 30 fps or 5 seconds at 60 fps.

An IDR frame degrade the quality in the case you have a constrained bandwidth (you can see blocks each 5 or 10 seconds).

In order to solve this scenario, I increased the max value of periodic_keyframe to a higher value (MAX_UINT).

THe keyframe is generated only when there is a force_keyframe event inside the encoder pipeline.

I tested with H.264 and I didn't see an issue or artifact appear after awhile.

There is another reason to kept the max value limited to 300? 

I attaching my changes for testing.
Comment 1 Víctor Manuel Jáquez Leal 2017-08-15 15:50:38 UTC
Comment on attachment 357627 [details] [review]
patch to increase max period_keyframe

This is just, as the previous comment states, a testing patch, thus marking it accordingly.
Comment 2 Víctor Manuel Jáquez Leal 2017-08-15 15:53:04 UTC
The issue here is how to solve it and in which cases we should solve this issue. Since there are a ton of other use-cases.
Comment 3 Matteo Valdina 2017-12-08 20:31:55 UTC
Hi,
There is an evolution of this report?

I would like to add that x264enc plugin uses the same approach provided in the patch.
I would like also point that we don't need to change the default value so let the current behavior in force.
Comment 4 Víctor Manuel Jáquez Leal 2017-12-09 17:01:08 UTC
Review of attachment 357627 [details] [review]:

::: gst-libs/gst/vaapi/gstvaapiencoder.c
@@ +165,3 @@
       g_param_spec_uint ("keyframe-period",
           "Keyframe Period",
+          "Maximal distance between two keyframes (0: auto-calculate)", 1, 4294967295,

Also change this number to G_MAXINT

::: gst-libs/gst/vaapi/gstvaapiutils_h26x_priv.h
@@ +32,2 @@
 /* Define the maximum IDR period */
+#define MAX_IDR_PERIOD 4294967295

Please change to G_MAXINT if that's the value you want, as if ffmpeg
Comment 5 Víctor Manuel Jáquez Leal 2017-12-09 17:01:08 UTC
Review of attachment 357627 [details] [review]:

::: gst-libs/gst/vaapi/gstvaapiencoder.c
@@ +165,3 @@
       g_param_spec_uint ("keyframe-period",
           "Keyframe Period",
+          "Maximal distance between two keyframes (0: auto-calculate)", 1, 4294967295,

Also change this number to G_MAXINT

::: gst-libs/gst/vaapi/gstvaapiutils_h26x_priv.h
@@ +32,2 @@
 /* Define the maximum IDR period */
+#define MAX_IDR_PERIOD 4294967295

Please change to G_MAXINT if that's the value you want, as if ffmpeg
Comment 6 Matteo Valdina 2017-12-11 17:40:56 UTC
Thanks,
I'll do that.
Comment 7 Matteo Valdina 2017-12-13 14:26:27 UTC
Created attachment 365492 [details] [review]
Patch for extend max value for periodic key frame.

Review and updated patch for extending periodic key frame to a higher value.
Comment 8 Matteo Valdina 2017-12-13 14:33:51 UTC
I noted that in the vaapih264 encoder there is a couple of re-defines of MAX_IDR_PERIOD.

I don't know why and if there is a reason for that, so, I changed the values across all occurrences of MAX_IDR_PERIOD instead of removing the re-define.

But I think this multiple defines should be removed and include the header in the implementation file. (this could be part of another bug report)
Comment 9 Matteo Valdina 2018-02-14 14:23:20 UTC
Hi,
Any comment on the latest patch?

Thanks
Matteo
Comment 10 Víctor Manuel Jáquez Leal 2018-02-14 14:59:01 UTC
Review of attachment 365492 [details] [review]:

::: gst-libs/gst/vaapi/gstvaapiencoder.c
@@ +165,3 @@
       g_param_spec_uint ("keyframe-period",
           "Keyframe Period",
+          "Maximal distance between two keyframes (0: auto-calculate)", 1, G_MAXINT,

Reading the libva code, this value boils down to a uint32 variable (https://github.com/intel/libva/blob/master/va/va_enc_h264.h#L171 and https://github.com/intel/libva/blob/master/va/va_enc_hevc.h#L175)

But G_MAXINT is platform specific, so rethinking it again, I would say it is better to set it to G_MAXINT32

Another bug there is that we are saying that 0 is auto-calculate but we are not allowing to set zero, since 1 is the minimal value permitted.

::: gst-libs/gst/vaapi/gstvaapiutils_h26x_priv.h
@@ +32,2 @@
 /* Define the maximum IDR period */
+#define MAX_IDR_PERIOD G_MAXINT

This is as sensible option, but I don't feel comfortable with it. Perhaps it is a better idea to remove that macro and replace its usage with G_MAXINT32, because we would be only hiding the fact that the max keyframe period is only bounded by the int32 max value, not a "magic number" as it was before (512).
Comment 11 Víctor Manuel Jáquez Leal 2018-02-14 15:01:30 UTC
(In reply to Matteo Valdina from comment #8)
> I noted that in the vaapih264 encoder there is a couple of re-defines of
> MAX_IDR_PERIOD.

It is because the support of Flexible Encoding Infrastructure, an experimental feature in VAAPI. Though most probably you will not use it, I will appreciate your patch also update that code. We need to refactor all that code (bug #787118)
Comment 12 Víctor Manuel Jáquez Leal 2018-02-14 15:03:23 UTC
(In reply to Víctor Manuel Jáquez Leal from comment #10)
> Review of attachment 365492 [details] [review] [review]:
> 
> ::: gst-libs/gst/vaapi/gstvaapiencoder.c
> @@ +165,3 @@
>        g_param_spec_uint ("keyframe-period",
>            "Keyframe Period",
> +          "Maximal distance between two keyframes (0: auto-calculate)", 1,
> G_MAXINT,
> 
> Reading the libva code, this value boils down to a uint32 variable
> (https://github.com/intel/libva/blob/master/va/va_enc_h264.h#L171 and
> https://github.com/intel/libva/blob/master/va/va_enc_hevc.h#L175)
> 
> But G_MAXINT is platform specific, so rethinking it again, I would say it is
> better to set it to G_MAXINT32

G_MAXUINT32

> 
> Another bug there is that we are saying that 0 is auto-calculate but we are
> not allowing to set zero, since 1 is the minimal value permitted.
> 
> ::: gst-libs/gst/vaapi/gstvaapiutils_h26x_priv.h
> @@ +32,2 @@
>  /* Define the maximum IDR period */
> +#define MAX_IDR_PERIOD G_MAXINT
> 
> This is as sensible option, but I don't feel comfortable with it. Perhaps it
> is a better idea to remove that macro and replace its usage with G_MAXINT32,
> because we would be only hiding the fact that the max keyframe period is
> only bounded by the int32 max value, not a "magic number" as it was before
> (512).

G_MAXUINT32
Comment 13 Matteo Valdina 2018-02-14 15:07:17 UTC
Thanks for your comments.

About the comment:
"
Another bug there is that we are saying that 0 is auto-calculate but we are not allowing to set zero since 1 is the minimal value permitted.
"

This is another separate pre-existing bug. I can easily update the comment from "Maximal distance between two keyframes (0: auto-calculate)" to "Maximal distance between two keyframes".

I didn't see the code to auto calculate the keyframes distance, so, the zero case looks like is not implemented.

Best
Matteo
Comment 14 Víctor Manuel Jáquez Leal 2018-02-14 15:26:33 UTC
(In reply to Matteo Valdina from comment #13)
> Thanks for your comments.
> 
> About the comment:
> "
> Another bug there is that we are saying that 0 is auto-calculate but we are
> not allowing to set zero since 1 is the minimal value permitted.
> "
> 
> This is another separate pre-existing bug. I can easily update the comment
> from "Maximal distance between two keyframes (0: auto-calculate)" to
> "Maximal distance between two keyframes".
> 
> I didn't see the code to auto calculate the keyframes distance, so, the zero
> case looks like is not implemented.

Yes, indeed.

But a default value is generated  here 

https://cgit.freedesktop.org/gstreamer/gstreamer-vaapi/tree/gst-libs/gst/vaapi/gstvaapiencoder.c#n818

The code is a bit convoluted but it ends up as the default value of the idr_period (1 keyframe per second) if the idr_period is lower than that.

But you are right, leave that for another bug. We shall not mix things.
Comment 15 Matteo Valdina 2018-02-15 21:14:56 UTC
Created attachment 368389 [details] [review]
Patch for extend max value for periodic key frame (G_MAXUINT32).

Hi,
I update the original patch with G_MAXUINT32. 

I saw that the current code will perform something like:

if (encoder->idr_period > G_MAXUINT32)
  encoder->idr_period = G_MAXUINT32;

This if statement is not really needed because idr_period is a guint32 so it cannot be true.
Anyway, I didn't change because idr_period could be changed in the future.

If you want I can remove the unneeded check.
Comment 16 Víctor Manuel Jáquez Leal 2018-02-16 07:59:40 UTC
(In reply to Matteo Valdina from comment #15)
> Created attachment 368389 [details] [review] [review]
> Patch for extend max value for periodic key frame (G_MAXUINT32).
> 
> Hi,
> I update the original patch with G_MAXUINT32. 
> 
> I saw that the current code will perform something like:
> 
> if (encoder->idr_period > G_MAXUINT32)
>   encoder->idr_period = G_MAXUINT32;
> 
> This if statement is not really needed because idr_period is a guint32 so it
> cannot be true.
> Anyway, I didn't change because idr_period could be changed in the future.
> 
> If you want I can remove the unneeded check.

Yes, please remove those lines. Thanks.
Comment 17 Matteo Valdina 2018-02-16 13:15:58 UTC
Created attachment 368420 [details] [review]
Patch for extend max value for periodic key frame (G_MAXUINT32 cleanup).

Removed redundant check.
Comment 18 Víctor Manuel Jáquez Leal 2018-02-19 21:38:50 UTC
Attachment 368420 [details] pushed as 83886ced - libs: encoder: h264,h265: extend max periodic keyframe.

I changed a bit the summary.

Thanks!