diff --git a/libavcodec/libx264.c b/libavcodec/libx264.c index 0f886713e3..507fee39f2 100644 --- a/libavcodec/libx264.c +++ b/libavcodec/libx264.c @@ -32,6 +32,7 @@ #include "internal.h" #include "packet_internal.h" #include "atsc_a53.h" +#include "sei.h" #if defined(_MSC_VER) #define X264_API_IMPORTS 1 @@ -114,6 +115,9 @@ typedef struct X264Context { * encounter a frame with ROI side data. */ int roi_warned; + + void *sei_data; + int sei_data_size; } X264Context; static void X264_log(void *p, int level, const char *fmt, va_list args) @@ -317,6 +321,9 @@ static int X264_frame(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame, x4->pic.img.i_plane = avfmt2_num_planes(ctx->pix_fmt); if (frame) { + x264_sei_t *sei = &x4->pic.extra_sei; + sei->num_payloads = 0; + for (i = 0; i < x4->pic.img.i_plane; i++) { x4->pic.img.plane[i] = frame->data[i]; x4->pic.img.i_stride[i] = frame->linesize[i]; @@ -439,6 +446,27 @@ static int X264_frame(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame, } } } + + for (int j = 0; j < frame->nb_side_data; j++) { + AVFrameSideData *side_data = frame->side_data[j]; + void *tmp; + x264_sei_payload_t *sei_payload; + if (side_data->type != AV_FRAME_DATA_SEI_UNREGISTERED) + continue; + tmp = av_fast_realloc(x4->sei_data, &x4->sei_data_size, (sei->num_payloads + 1) * sizeof(*sei_payload)); + if (!tmp) { + av_freep(&x4->pic.extra_sei.payloads); + av_freep(&x4->pic.prop.quant_offsets); + return AVERROR(ENOMEM); + } + x4->sei_data = tmp; + sei->payloads = x4->sei_data; + sei_payload = &sei->payloads[sei->num_payloads]; + sei_payload->payload = side_data->data; + sei_payload->payload_size = side_data->size; + sei_payload->payload_type = SEI_TYPE_USER_DATA_UNREGISTERED; + sei->num_payloads++; + } } do { @@ -505,6 +533,8 @@ static av_cold int X264_close(AVCodecContext *avctx) x264_param_cleanup(&x4->params); #endif + av_freep(&x4->sei_data); + if (x4->enc) { x264_encoder_close(x4->enc); x4->enc = NULL;