diff mbox series

[FFmpeg-devel,v6] avcodec/nvenc: write out user data unregistered SEI

Message ID 20210525101157.21519-2-bradh@frogmouth.net
State Superseded
Headers show
Series [FFmpeg-devel,v6] avcodec/nvenc: write out user data unregistered SEI | expand

Checks

Context Check Description
andriy/x86_make success Make finished
andriy/x86_make_fate success Make fate finished
andriy/PPC64_make success Make finished
andriy/PPC64_make_fate success Make fate finished

Commit Message

Brad Hards May 25, 2021, 10:11 a.m. UTC
Signed-off-by: Brad Hards <bradh@frogmouth.net>
---
 libavcodec/nvenc.c | 73 +++++++++++++++++++++++++++++++++++++---------
 libavcodec/nvenc.h |  2 ++
 2 files changed, 62 insertions(+), 13 deletions(-)

Comments

Timo Rothenpieler May 25, 2021, 11:03 a.m. UTC | #1
On 25/05/2021 12:11, Brad Hards wrote:
> Signed-off-by: Brad Hards <bradh@frogmouth.net>
> ---
>   libavcodec/nvenc.c | 73 +++++++++++++++++++++++++++++++++++++---------
>   libavcodec/nvenc.h |  2 ++
>   2 files changed, 62 insertions(+), 13 deletions(-)
> 
> diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c
> index 0dcd93a99c..9c2664a99e 100644
> --- a/libavcodec/nvenc.c
> +++ b/libavcodec/nvenc.c
> @@ -1610,6 +1610,8 @@ av_cold int ff_nvenc_encode_close(AVCodecContext *avctx)
>   
>       av_frame_free(&ctx->frame);
>   
> +    av_freep(&ctx->sei_data);
> +
>       if (ctx->nvencoder) {
>           p_nvenc->nvEncDestroyEncoder(ctx->nvencoder);
>   
> @@ -2170,9 +2172,9 @@ static int nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame)
>       NVENCSTATUS nv_status;
>       NvencSurface *tmp_out_surf, *in_surf;
>       int res, res2;
> -    NV_ENC_SEI_PAYLOAD sei_data[8];
>       int sei_count = 0;
>       int i;
> +    int total_unregistered_sei = 0;
>   
>       NvencContext *ctx = avctx->priv_data;
>       NvencDynLoadFunctions *dl_fn = &ctx->nvenc_dload_funcs;
> @@ -2185,6 +2187,8 @@ static int nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame)
>           return AVERROR(EINVAL);
>   
>       if (frame && frame->buf[0]) {
> +        void *a53_data = NULL;
> +        void *tc_data = NULL;
>           in_surf = get_free_frame(ctx);
>           if (!in_surf)
>               return AVERROR(EAGAIN);
> @@ -2230,7 +2234,6 @@ static int nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame)
>           pic_params.inputTimeStamp = frame->pts;
>   
>           if (ctx->a53_cc && av_frame_get_side_data(frame, AV_FRAME_DATA_A53_CC)) {
> -            void *a53_data = NULL;
>               size_t a53_size = 0;
>   
>               if (ff_alloc_a53_sei(frame, 0, (void**)&a53_data, &a53_size) < 0) {
> @@ -2238,15 +2241,23 @@ static int nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame)
>               }
>   
>               if (a53_data) {
> -                sei_data[sei_count].payloadSize = (uint32_t)a53_size;
> -                sei_data[sei_count].payloadType = 4;
> -                sei_data[sei_count].payload = (uint8_t*)a53_data;
> -                sei_count ++;
> +                void *tmp = av_fast_realloc(ctx->sei_data,
> +                                            &(ctx->sei_data_size),

The braces are unneccesary and I think against style guidelines as well.

> +                                            sizeof(NV_ENC_SEI_PAYLOAD));

I'd just pull the sei_count++ in there, and then use the same style 
fast_realloc in every block.
As in: ++sei_count * sizeof(NV_ENC_SEI_PAYLOAD)

> +                if (!tmp) {
> +                    av_free(a53_data);
> +                    return AVERROR(ENOMEM);
> +                } else {
> +                    ctx->sei_data = tmp;
> +                    ctx->sei_data[sei_count].payloadSize = (uint32_t)a53_size;
> +                    ctx->sei_data[sei_count].payloadType = 4;
> +                    ctx->sei_data[sei_count].payload = (uint8_t*)a53_data;
> +                    sei_count ++;
> +                }
>               }
>           }
>   
>           if (ctx->s12m_tc && av_frame_get_side_data(frame, AV_FRAME_DATA_S12M_TIMECODE)) {
> -            void *tc_data = NULL;
>               size_t tc_size = 0;
>   
>               if (ff_alloc_timecode_sei(frame, avctx->framerate, 0, (void**)&tc_data, &tc_size) < 0) {
> @@ -2254,14 +2265,50 @@ static int nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame)
>               }
>   
>               if (tc_data) {
> -                sei_data[sei_count].payloadSize = (uint32_t)tc_size;
> -                sei_data[sei_count].payloadType = SEI_TYPE_TIME_CODE;
> -                sei_data[sei_count].payload = (uint8_t*)tc_data;
> -                sei_count ++;
> +                 void *tmp = av_fast_realloc(ctx->sei_data,
> +                                             &(ctx->sei_data_size),
> +                                             (sei_count + 1) * sizeof(NV_ENC_SEI_PAYLOAD));

This seems to be indented one space too deep.

> +                if (!tmp) {
> +                    av_free(a53_data);
> +                    av_free(tc_data);
> +                    return AVERROR(ENOMEM);
> +                } else {
> +                    ctx->sei_data = tmp;
> +                    ctx->sei_data[sei_count].payloadSize = (uint32_t)tc_size;
> +                    ctx->sei_data[sei_count].payloadType = SEI_TYPE_TIME_CODE;
> +                    ctx->sei_data[sei_count].payload = (uint8_t*)tc_data;
> +                    sei_count ++;
> +                }
> +            }
> +        }
> +
> +        for (int j = 0; j < frame->nb_side_data; j++)
> +            if (frame->side_data[j]->type == AV_FRAME_DATA_SEI_UNREGISTERED)
> +                total_unregistered_sei++;
> +        if (total_unregistered_sei > 0) {
> +            void *tmp = av_fast_realloc(ctx->sei_data,
> +                                        &(ctx->sei_data_size),
> +                                        (sei_count + total_unregistered_sei) * sizeof(NV_ENC_SEI_PAYLOAD));
> +            if (!tmp) {
> +                av_free(a53_data);
> +                av_free(tc_data);
> +                return AVERROR(ENOMEM);
> +            } else {
> +                ctx->sei_data = tmp;
> +                for (int j = 0; j < frame->nb_side_data; j++) {
> +                    AVFrameSideData *side_data = frame->side_data[j];
> +                    if (side_data->type == AV_FRAME_DATA_SEI_UNREGISTERED) {
> +                        ctx->sei_data[sei_count].payloadSize = side_data->size;
> +                        ctx->sei_data[sei_count].payloadType = SEI_TYPE_USER_DATA_UNREGISTERED;
> +                        ctx->sei_data[sei_count].payload = av_memdup(side_data->data, side_data->size);
> +                        if (ctx->sei_data[sei_count].payload)
> +                            sei_count ++;
> +                    }
> +                }
>               }
>           }
>   
> -        nvenc_codec_specific_pic_params(avctx, &pic_params, sei_data, sei_count);
> +        nvenc_codec_specific_pic_params(avctx, &pic_params, ctx->sei_data, sei_count);
>       } else {
>           pic_params.encodePicFlags = NV_ENC_PIC_FLAG_EOS;
>       }
> @@ -2273,7 +2320,7 @@ static int nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame)
>       nv_status = p_nvenc->nvEncEncodePicture(ctx->nvencoder, &pic_params);
>   
>       for ( i = 0; i < sei_count; i++)
> -        av_freep(&sei_data[i].payload);
> +        av_freep(&(ctx->sei_data[i].payload));

I'm not 100% sure about these braces, but I think they're unneccesary as 
well.

>       res = nvenc_pop_context(avctx);
>       if (res < 0)
> diff --git a/libavcodec/nvenc.h b/libavcodec/nvenc.h
> index 314c270e74..d28f02b54f 100644
> --- a/libavcodec/nvenc.h
> +++ b/libavcodec/nvenc.h
> @@ -165,6 +165,8 @@ typedef struct NvencContext
>       AVFifoBuffer *output_surface_queue;
>       AVFifoBuffer *output_surface_ready_queue;
>       AVFifoBuffer *timestamp_list;
> +    NV_ENC_SEI_PAYLOAD *sei_data;
> +    int sei_data_size;
>   
>       struct {
>           void *ptr;
> 

Looks good otherwise, I will give it a test soon.
Brad Hards May 25, 2021, 11:19 a.m. UTC | #2
On Tuesday, 25 May 2021 9:03:51 PM AEST Timo Rothenpieler wrote:
> On 25/05/2021 12:11, Brad Hards wrote:
> > Signed-off-by: Brad Hards <bradh@frogmouth.net>
> > ---
> > 
> >   libavcodec/nvenc.c | 73 +++++++++++++++++++++++++++++++++++++---------
> >   libavcodec/nvenc.h |  2 ++
> >   2 files changed, 62 insertions(+), 13 deletions(-)
> > 
> > diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c
> > index 0dcd93a99c..9c2664a99e 100644
> > --- a/libavcodec/nvenc.c
> > +++ b/libavcodec/nvenc.c
> > @@ -1610,6 +1610,8 @@ av_cold int ff_nvenc_encode_close(AVCodecContext
> > *avctx)> 
> >       av_frame_free(&ctx->frame);
> > 
> > +    av_freep(&ctx->sei_data);
> > +
> > 
> >       if (ctx->nvencoder) {
> >       
> >           p_nvenc->nvEncDestroyEncoder(ctx->nvencoder);
> > 
> > @@ -2170,9 +2172,9 @@ static int nvenc_send_frame(AVCodecContext *avctx,
> > const AVFrame *frame)> 
> >       NVENCSTATUS nv_status;
> >       NvencSurface *tmp_out_surf, *in_surf;
> >       int res, res2;
> > 
> > -    NV_ENC_SEI_PAYLOAD sei_data[8];
> > 
> >       int sei_count = 0;
> >       int i;
> > 
> > +    int total_unregistered_sei = 0;
> > 
> >       NvencContext *ctx = avctx->priv_data;
> >       NvencDynLoadFunctions *dl_fn = &ctx->nvenc_dload_funcs;
> > 
> > @@ -2185,6 +2187,8 @@ static int nvenc_send_frame(AVCodecContext *avctx,
> > const AVFrame *frame)> 
> >           return AVERROR(EINVAL);
> >       
> >       if (frame && frame->buf[0]) {
> > 
> > +        void *a53_data = NULL;
> > +        void *tc_data = NULL;
> > 
> >           in_surf = get_free_frame(ctx);
> >           if (!in_surf)
> >           
> >               return AVERROR(EAGAIN);
> > 
> > @@ -2230,7 +2234,6 @@ static int nvenc_send_frame(AVCodecContext *avctx,
> > const AVFrame *frame)> 
> >           pic_params.inputTimeStamp = frame->pts;
> >           
> >           if (ctx->a53_cc && av_frame_get_side_data(frame,
> >           AV_FRAME_DATA_A53_CC)) {
> > 
> > -            void *a53_data = NULL;
> > 
> >               size_t a53_size = 0;
> >               
> >               if (ff_alloc_a53_sei(frame, 0, (void**)&a53_data, &a53_size)
> >               < 0) {
> > 
> > @@ -2238,15 +2241,23 @@ static int nvenc_send_frame(AVCodecContext *avctx,
> > const AVFrame *frame)> 
> >               }
> >               
> >               if (a53_data) {
> > 
> > -                sei_data[sei_count].payloadSize = (uint32_t)a53_size;
> > -                sei_data[sei_count].payloadType = 4;
> > -                sei_data[sei_count].payload = (uint8_t*)a53_data;
> > -                sei_count ++;
> > +                void *tmp = av_fast_realloc(ctx->sei_data,
> > +                                            &(ctx->sei_data_size),
> 
> The braces are unneccesary and I think against style guidelines as well.
Removed in v7

> > +                                            sizeof(NV_ENC_SEI_PAYLOAD));
> 
> I'd just pull the sei_count++ in there, and then use the same style
> fast_realloc in every block.
> As in: ++sei_count * sizeof(NV_ENC_SEI_PAYLOAD)
It doesn't work in the final block, but incorporated for a53 and s12m in v7

> > +                if (!tmp) {
> > +                    av_free(a53_data);
> > +                    return AVERROR(ENOMEM);
> > +                } else {
> > +                    ctx->sei_data = tmp;
> > +                    ctx->sei_data[sei_count].payloadSize =
> > (uint32_t)a53_size; +                   
> > ctx->sei_data[sei_count].payloadType = 4;
> > +                    ctx->sei_data[sei_count].payload =
> > (uint8_t*)a53_data;
> > +                    sei_count ++;
> > +                }
> > 
> >               }
> >           
> >           }
> >           
> >           if (ctx->s12m_tc && av_frame_get_side_data(frame,
> >           AV_FRAME_DATA_S12M_TIMECODE)) {> 
> > -            void *tc_data = NULL;
> > 
> >               size_t tc_size = 0;
> >               
> >               if (ff_alloc_timecode_sei(frame, avctx->framerate, 0,
> >               (void**)&tc_data, &tc_size) < 0) {> 
> > @@ -2254,14 +2265,50 @@ static int nvenc_send_frame(AVCodecContext *avctx,
> > const AVFrame *frame)> 
> >               }
> >               
> >               if (tc_data) {
> > 
> > -                sei_data[sei_count].payloadSize = (uint32_t)tc_size;
> > -                sei_data[sei_count].payloadType = SEI_TYPE_TIME_CODE;
> > -                sei_data[sei_count].payload = (uint8_t*)tc_data;
> > -                sei_count ++;
> > +                 void *tmp = av_fast_realloc(ctx->sei_data,
> > +                                             &(ctx->sei_data_size),
> > +                                             (sei_count + 1) *
> > sizeof(NV_ENC_SEI_PAYLOAD));
> This seems to be indented one space too deep.
Removed in v7

> > +                if (!tmp) {
> > +                    av_free(a53_data);
> > +                    av_free(tc_data);
> > +                    return AVERROR(ENOMEM);
> > +                } else {
> > +                    ctx->sei_data = tmp;
> > +                    ctx->sei_data[sei_count].payloadSize =
> > (uint32_t)tc_size; +                   
> > ctx->sei_data[sei_count].payloadType = SEI_TYPE_TIME_CODE; +             
> >       ctx->sei_data[sei_count].payload = (uint8_t*)tc_data; +            
> >        sei_count ++;
> > +                }
> > +            }
> > +        }
> > +
> > +        for (int j = 0; j < frame->nb_side_data; j++)
> > +            if (frame->side_data[j]->type ==
> > AV_FRAME_DATA_SEI_UNREGISTERED) +               
> > total_unregistered_sei++;
> > +        if (total_unregistered_sei > 0) {
> > +            void *tmp = av_fast_realloc(ctx->sei_data,
> > +                                        &(ctx->sei_data_size),
> > +                                        (sei_count +
> > total_unregistered_sei) * sizeof(NV_ENC_SEI_PAYLOAD)); +            if
> > (!tmp) {
> > +                av_free(a53_data);
> > +                av_free(tc_data);
> > +                return AVERROR(ENOMEM);
> > +            } else {
> > +                ctx->sei_data = tmp;
> > +                for (int j = 0; j < frame->nb_side_data; j++) {
> > +                    AVFrameSideData *side_data = frame->side_data[j];
> > +                    if (side_data->type ==
> > AV_FRAME_DATA_SEI_UNREGISTERED) { +                       
> > ctx->sei_data[sei_count].payloadSize = side_data->size; +                
> >        ctx->sei_data[sei_count].payloadType =
> > SEI_TYPE_USER_DATA_UNREGISTERED; +                       
> > ctx->sei_data[sei_count].payload = av_memdup(side_data->data,
> > side_data->size); +                        if
> > (ctx->sei_data[sei_count].payload)
> > +                            sei_count ++;
> > +                    }
> > +                }
> > 
> >               }
> >           
> >           }
> > 
> > -        nvenc_codec_specific_pic_params(avctx, &pic_params, sei_data,
> > sei_count); +        nvenc_codec_specific_pic_params(avctx, &pic_params,
> > ctx->sei_data, sei_count);> 
> >       } else {
> >       
> >           pic_params.encodePicFlags = NV_ENC_PIC_FLAG_EOS;
> >       
> >       }
> > 
> > @@ -2273,7 +2320,7 @@ static int nvenc_send_frame(AVCodecContext *avctx,
> > const AVFrame *frame)> 
> >       nv_status = p_nvenc->nvEncEncodePicture(ctx->nvencoder,
> >       &pic_params);
> >       
> >       for ( i = 0; i < sei_count; i++)
> > 
> > -        av_freep(&sei_data[i].payload);
> > +        av_freep(&(ctx->sei_data[i].payload));
> 
> I'm not 100% sure about these braces, but I think they're unneccesary as
> well.
Removed in v7

> >       res = nvenc_pop_context(avctx);
> >       if (res < 0)
> > 
> > diff --git a/libavcodec/nvenc.h b/libavcodec/nvenc.h
> > index 314c270e74..d28f02b54f 100644
> > --- a/libavcodec/nvenc.h
> > +++ b/libavcodec/nvenc.h
> > @@ -165,6 +165,8 @@ typedef struct NvencContext
> > 
> >       AVFifoBuffer *output_surface_queue;
> >       AVFifoBuffer *output_surface_ready_queue;
> >       AVFifoBuffer *timestamp_list;
> > 
> > +    NV_ENC_SEI_PAYLOAD *sei_data;
> > +    int sei_data_size;
> > 
> >       struct {
> >       
> >           void *ptr;
> 
> Looks good otherwise, I will give it a test soon.
Thanks.

Brad
diff mbox series

Patch

diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c
index 0dcd93a99c..9c2664a99e 100644
--- a/libavcodec/nvenc.c
+++ b/libavcodec/nvenc.c
@@ -1610,6 +1610,8 @@  av_cold int ff_nvenc_encode_close(AVCodecContext *avctx)
 
     av_frame_free(&ctx->frame);
 
+    av_freep(&ctx->sei_data);
+
     if (ctx->nvencoder) {
         p_nvenc->nvEncDestroyEncoder(ctx->nvencoder);
 
@@ -2170,9 +2172,9 @@  static int nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame)
     NVENCSTATUS nv_status;
     NvencSurface *tmp_out_surf, *in_surf;
     int res, res2;
-    NV_ENC_SEI_PAYLOAD sei_data[8];
     int sei_count = 0;
     int i;
+    int total_unregistered_sei = 0;
 
     NvencContext *ctx = avctx->priv_data;
     NvencDynLoadFunctions *dl_fn = &ctx->nvenc_dload_funcs;
@@ -2185,6 +2187,8 @@  static int nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame)
         return AVERROR(EINVAL);
 
     if (frame && frame->buf[0]) {
+        void *a53_data = NULL;
+        void *tc_data = NULL;
         in_surf = get_free_frame(ctx);
         if (!in_surf)
             return AVERROR(EAGAIN);
@@ -2230,7 +2234,6 @@  static int nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame)
         pic_params.inputTimeStamp = frame->pts;
 
         if (ctx->a53_cc && av_frame_get_side_data(frame, AV_FRAME_DATA_A53_CC)) {
-            void *a53_data = NULL;
             size_t a53_size = 0;
 
             if (ff_alloc_a53_sei(frame, 0, (void**)&a53_data, &a53_size) < 0) {
@@ -2238,15 +2241,23 @@  static int nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame)
             }
 
             if (a53_data) {
-                sei_data[sei_count].payloadSize = (uint32_t)a53_size;
-                sei_data[sei_count].payloadType = 4;
-                sei_data[sei_count].payload = (uint8_t*)a53_data;
-                sei_count ++;
+                void *tmp = av_fast_realloc(ctx->sei_data,
+                                            &(ctx->sei_data_size),
+                                            sizeof(NV_ENC_SEI_PAYLOAD));
+                if (!tmp) {
+                    av_free(a53_data);
+                    return AVERROR(ENOMEM);
+                } else {
+                    ctx->sei_data = tmp;
+                    ctx->sei_data[sei_count].payloadSize = (uint32_t)a53_size;
+                    ctx->sei_data[sei_count].payloadType = 4;
+                    ctx->sei_data[sei_count].payload = (uint8_t*)a53_data;
+                    sei_count ++;
+                }
             }
         }
 
         if (ctx->s12m_tc && av_frame_get_side_data(frame, AV_FRAME_DATA_S12M_TIMECODE)) {
-            void *tc_data = NULL;
             size_t tc_size = 0;
 
             if (ff_alloc_timecode_sei(frame, avctx->framerate, 0, (void**)&tc_data, &tc_size) < 0) {
@@ -2254,14 +2265,50 @@  static int nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame)
             }
 
             if (tc_data) {
-                sei_data[sei_count].payloadSize = (uint32_t)tc_size;
-                sei_data[sei_count].payloadType = SEI_TYPE_TIME_CODE;
-                sei_data[sei_count].payload = (uint8_t*)tc_data;
-                sei_count ++;
+                 void *tmp = av_fast_realloc(ctx->sei_data,
+                                             &(ctx->sei_data_size),
+                                             (sei_count + 1) * sizeof(NV_ENC_SEI_PAYLOAD));
+                if (!tmp) {
+                    av_free(a53_data);
+                    av_free(tc_data);
+                    return AVERROR(ENOMEM);
+                } else {
+                    ctx->sei_data = tmp;
+                    ctx->sei_data[sei_count].payloadSize = (uint32_t)tc_size;
+                    ctx->sei_data[sei_count].payloadType = SEI_TYPE_TIME_CODE;
+                    ctx->sei_data[sei_count].payload = (uint8_t*)tc_data;
+                    sei_count ++;
+                }
+            }
+        }
+
+        for (int j = 0; j < frame->nb_side_data; j++)
+            if (frame->side_data[j]->type == AV_FRAME_DATA_SEI_UNREGISTERED)
+                total_unregistered_sei++;
+        if (total_unregistered_sei > 0) {
+            void *tmp = av_fast_realloc(ctx->sei_data,
+                                        &(ctx->sei_data_size),
+                                        (sei_count + total_unregistered_sei) * sizeof(NV_ENC_SEI_PAYLOAD));
+            if (!tmp) {
+                av_free(a53_data);
+                av_free(tc_data);
+                return AVERROR(ENOMEM);
+            } else {
+                ctx->sei_data = tmp;
+                for (int j = 0; j < frame->nb_side_data; j++) {
+                    AVFrameSideData *side_data = frame->side_data[j];
+                    if (side_data->type == AV_FRAME_DATA_SEI_UNREGISTERED) {
+                        ctx->sei_data[sei_count].payloadSize = side_data->size;
+                        ctx->sei_data[sei_count].payloadType = SEI_TYPE_USER_DATA_UNREGISTERED;
+                        ctx->sei_data[sei_count].payload = av_memdup(side_data->data, side_data->size);
+                        if (ctx->sei_data[sei_count].payload)
+                            sei_count ++;
+                    }
+                }
             }
         }
 
-        nvenc_codec_specific_pic_params(avctx, &pic_params, sei_data, sei_count);
+        nvenc_codec_specific_pic_params(avctx, &pic_params, ctx->sei_data, sei_count);
     } else {
         pic_params.encodePicFlags = NV_ENC_PIC_FLAG_EOS;
     }
@@ -2273,7 +2320,7 @@  static int nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame)
     nv_status = p_nvenc->nvEncEncodePicture(ctx->nvencoder, &pic_params);
 
     for ( i = 0; i < sei_count; i++)
-        av_freep(&sei_data[i].payload);
+        av_freep(&(ctx->sei_data[i].payload));
 
     res = nvenc_pop_context(avctx);
     if (res < 0)
diff --git a/libavcodec/nvenc.h b/libavcodec/nvenc.h
index 314c270e74..d28f02b54f 100644
--- a/libavcodec/nvenc.h
+++ b/libavcodec/nvenc.h
@@ -165,6 +165,8 @@  typedef struct NvencContext
     AVFifoBuffer *output_surface_queue;
     AVFifoBuffer *output_surface_ready_queue;
     AVFifoBuffer *timestamp_list;
+    NV_ENC_SEI_PAYLOAD *sei_data;
+    int sei_data_size;
 
     struct {
         void *ptr;