Message ID | 972cf19a-70be-42d3-60f7-617975e0dde2@jkqxz.net |
---|---|
State | New |
Headers | show |
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 --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));