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 |
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 |
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.
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 --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;
Signed-off-by: Brad Hards <bradh@frogmouth.net> --- libavcodec/nvenc.c | 73 +++++++++++++++++++++++++++++++++++++--------- libavcodec/nvenc.h | 2 ++ 2 files changed, 62 insertions(+), 13 deletions(-)