On Tuesday, 25 May 2021 9:16:35 PM AEST Brad Hards wrote: > Signed-off-by: Brad Hards <br...@frogmouth.net> > --- > libavcodec/nvenc.c | 71 +++++++++++++++++++++++++++++++++++++--------- > libavcodec/nvenc.h | 2 ++ > 2 files changed, 60 insertions(+), 13 deletions(-) > > diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c > index 0dcd93a99c..8ca5cab4c8 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,22 @@ 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, > + ++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-1].payloadSize = > (uint32_t)a53_size; + > ctx->sei_data[sei_count-1].payloadType = 4; > + ctx->sei_data[sei_count-1].payload = > (uint8_t*)a53_data; + } > } > } > > 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 +2264,49 @@ 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 * > 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-1].payloadSize = > (uint32_t)tc_size; + > ctx->sei_data[sei_count-1].payloadType = SEI_TYPE_TIME_CODE; + > ctx->sei_data[sei_count-1].payload = (uint8_t*)tc_data; + > } > + } > + } > + > + 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 +2318,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; Anything more on this version?
Brad _______________________________________________ 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".