diff mbox

[FFmpeg-devel] vaapi_h264: Add workaround for bad SEI in old Intel drivers

Message ID 972cf19a-70be-42d3-60f7-617975e0dde2@jkqxz.net
State New
Headers show

Commit Message

Mark Thompson Oct. 24, 2017, 11:32 p.m. UTC
With pre-2.0 Intel drivers in CBR mode, if an explicit SEI message with
the old (now deprecated) type is not included, the driver generates and
inserts some timing SEI which is almost certainly invlaid.  Before
7a4fac5e91789b73e07bd4ad20493cfde028df76 we always inserted our own SEI
so this would not be visible, but since then it has been possible to
disable that.  We would also like to avoid using the deprecated type,
and using the new type, while working in old drivers, does not suppress
the spurious message like the old type does.

Therefore, suppress the bad SEI insertion by providing a zero-length
buffer with the old type, which the driver can insert harmlessly.
---
 libavcodec/vaapi_encode_h264.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

Comments

Mark Thompson Oct. 24, 2017, 11:38 p.m. UTC | #1
On 25/10/17 00:32, Mark Thompson wrote:
> With pre-2.0 Intel drivers in CBR mode, if an explicit SEI message with
> the old (now deprecated) type is not included, the driver generates and
> inserts some timing SEI which is almost certainly invlaid.  Before
> 7a4fac5e91789b73e07bd4ad20493cfde028df76 we always inserted our own SEI

* 2e29ca2a9f19ba9a5b189f322f38497d2e2e3db0

> so this would not be visible, but since then it has been possible to
> disable that.  We would also like to avoid using the deprecated type,
> and using the new type, while working in old drivers, does not suppress
> the spurious message like the old type does.
> 
> Therefore, suppress the bad SEI insertion by providing a zero-length
> buffer with the old type, which the driver can insert harmlessly.
> ---
>  libavcodec/vaapi_encode_h264.c | 18 ++++++++++++++++++
>  1 file changed, 18 insertions(+)
> 
> diff --git a/libavcodec/vaapi_encode_h264.c b/libavcodec/vaapi_encode_h264.c
> index 1d43e934ef..5fd0bf7796 100644
> --- a/libavcodec/vaapi_encode_h264.c
> +++ b/libavcodec/vaapi_encode_h264.c
> @@ -82,6 +82,7 @@ typedef struct VAAPIEncodeH264Context {
>      CodedBitstreamFragment current_access_unit;
>      int aud_needed;
>      int sei_needed;
> +    int sei_cbr_workaround_needed;
>  } VAAPIEncodeH264Context;
>  
>  typedef struct VAAPIEncodeH264Options {
> @@ -258,6 +259,19 @@ static int vaapi_encode_h264_write_extra_header(AVCodecContext *avctx,
>  
>          *type = VAEncPackedHeaderRawData;
>          return 0;
> +
> +#if !CONFIG_VAAPI_1
> +    } else if (priv->sei_cbr_workaround_needed) {
> +        // Insert a zero-length header using the old SEI type.  This is
> +        // required to avoid triggering broken behaviour on Intel platforms
> +        // in CBR mode where an invalid SEI message is generated by the
> +        // driver and inserted into the stream.
> +        *data_len = 0;
> +        *type = VAEncPackedHeaderH264_SEI;
> +        priv->sei_cbr_workaround_needed = 0;
> +        return 0;
> +#endif
> +
>      } else {
>          return AVERROR_EOF;
>      }
> @@ -614,6 +628,10 @@ static int vaapi_encode_h264_init_picture_params(AVCodecContext *avctx,
>  
>      if (opt->sei & SEI_IDENTIFIER && pic->encode_order == 0)
>          priv->sei_needed = 1;
> +#if !CONFIG_VAAPI_1
> +    if (ctx->va_rc_mode == VA_RC_CBR)
> +        priv->sei_cbr_workaround_needed = 1;
> +#endif
>  
>      if (opt->sei & SEI_TIMING) {
>          memset(&priv->pic_timing, 0, sizeof(priv->pic_timing));
>
diff mbox

Patch

diff --git a/libavcodec/vaapi_encode_h264.c b/libavcodec/vaapi_encode_h264.c
index 1d43e934ef..5fd0bf7796 100644
--- a/libavcodec/vaapi_encode_h264.c
+++ b/libavcodec/vaapi_encode_h264.c
@@ -82,6 +82,7 @@  typedef struct VAAPIEncodeH264Context {
     CodedBitstreamFragment current_access_unit;
     int aud_needed;
     int sei_needed;
+    int sei_cbr_workaround_needed;
 } VAAPIEncodeH264Context;
 
 typedef struct VAAPIEncodeH264Options {
@@ -258,6 +259,19 @@  static int vaapi_encode_h264_write_extra_header(AVCodecContext *avctx,
 
         *type = VAEncPackedHeaderRawData;
         return 0;
+
+#if !CONFIG_VAAPI_1
+    } else if (priv->sei_cbr_workaround_needed) {
+        // Insert a zero-length header using the old SEI type.  This is
+        // required to avoid triggering broken behaviour on Intel platforms
+        // in CBR mode where an invalid SEI message is generated by the
+        // driver and inserted into the stream.
+        *data_len = 0;
+        *type = VAEncPackedHeaderH264_SEI;
+        priv->sei_cbr_workaround_needed = 0;
+        return 0;
+#endif
+
     } else {
         return AVERROR_EOF;
     }
@@ -614,6 +628,10 @@  static int vaapi_encode_h264_init_picture_params(AVCodecContext *avctx,
 
     if (opt->sei & SEI_IDENTIFIER && pic->encode_order == 0)
         priv->sei_needed = 1;
+#if !CONFIG_VAAPI_1
+    if (ctx->va_rc_mode == VA_RC_CBR)
+        priv->sei_cbr_workaround_needed = 1;
+#endif
 
     if (opt->sei & SEI_TIMING) {
         memset(&priv->pic_timing, 0, sizeof(priv->pic_timing));