On 25/05/2021 12:11, Brad Hards wrote:
Signed-off-by: Brad Hards <br...@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.
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

Reply via email to