avcodec/libx26[45]: add udu_sei option to import user data unregistered SEIs

Most of user data unregistered SEIs are privated data which defined by user/
encoder. currently, the user data unregistered SEIs found in input are forwarded
as side-data to encoders directly, it'll cause the reencoded output including some
useless UDU SEIs.

I prefer to add one option to enable/disable it and default is off after I saw
the patch by Andreas Rheinhardt:

https://patchwork.ffmpeg.org/project/ffmpeg/patch/AM7PR03MB66607C2DB65E1AD49D975CF18F7B9@AM7PR03MB6660.eurprd03.prod.outlook.com/

How to test by cli:
ffmpeg -y -f lavfi -i testsrc -c:v libx264 -frames:v 1 a.ts
ffmpeg -y -i a.ts -c:v libx264 -udu_sei 1 b.ts
ffmpeg -y -i a.ts -c:v libx264 -udu_sei 0 c.ts

# check the user data unregistered SEIs, you'll see two UDU SEIs for b.ts.
# and mediainfo will show with wrong encoding setting info
ffmpeg -i b.ts -vf showinfo -f null -
ffmpeg -i c.ts -vf showinfo -f null -

This fixes tickets #9500 and #9557.

Reviewed-by: "zhilizhao(赵志立)" <quinkblack@foxmail.com>
Signed-off-by: Limin Wang <lance.lmwang@gmail.com>
This commit is contained in:
Limin Wang
2021-12-25 22:21:03 +08:00
parent 617452ce2c
commit 7dfc3cc713
4 changed files with 15 additions and 2 deletions

View File

@@ -2660,6 +2660,9 @@ ffmpeg -i foo.mpg -c:v libx264 -x264opts keyint=123:min-keyint=20 -an out.mkv
Import closed captions (which must be ATSC compatible format) into output. Import closed captions (which must be ATSC compatible format) into output.
Only the mpeg2 and h264 decoders provide these. Default is 1 (on). Only the mpeg2 and h264 decoders provide these. Default is 1 (on).
@item udu_sei @var{boolean}
Import user data unregistered SEI if available into output. Default is 0 (off).
@item x264-params (N.A.) @item x264-params (N.A.)
Override the x264 configuration using a :-separated list of key=value Override the x264 configuration using a :-separated list of key=value
parameters. parameters.
@@ -2741,6 +2744,9 @@ Quantizer curve compression factor
Normally, when forcing a I-frame type, the encoder can select any type Normally, when forcing a I-frame type, the encoder can select any type
of I-frame. This option forces it to choose an IDR-frame. of I-frame. This option forces it to choose an IDR-frame.
@item udu_sei @var{boolean}
Import user data unregistered SEI if available into output. Default is 0 (off).
@item x265-params @item x265-params
Set x265 options using a list of @var{key}=@var{value} couples separated Set x265 options using a list of @var{key}=@var{value} couples separated
by ":". See @command{x265 --help} for a list of options. by ":". See @command{x265 --help} for a list of options.

View File

@@ -104,6 +104,7 @@ typedef struct X264Context {
int chroma_offset; int chroma_offset;
int scenechange_threshold; int scenechange_threshold;
int noise_reduction; int noise_reduction;
int udu_sei;
AVDictionary *x264_params; AVDictionary *x264_params;
@@ -464,6 +465,7 @@ static int X264_frame(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame,
} }
} }
if (x4->udu_sei) {
for (int j = 0; j < frame->nb_side_data; j++) { for (int j = 0; j < frame->nb_side_data; j++) {
AVFrameSideData *side_data = frame->side_data[j]; AVFrameSideData *side_data = frame->side_data[j];
void *tmp; void *tmp;
@@ -487,6 +489,7 @@ static int X264_frame(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame,
sei_payload->payload_type = SEI_TYPE_USER_DATA_UNREGISTERED; sei_payload->payload_type = SEI_TYPE_USER_DATA_UNREGISTERED;
sei->num_payloads++; sei->num_payloads++;
} }
}
} }
do { do {
@@ -1168,7 +1171,7 @@ static const AVOption options[] = {
{ "chromaoffset", "QP difference between chroma and luma", OFFSET(chroma_offset), AV_OPT_TYPE_INT, { .i64 = 0 }, INT_MIN, INT_MAX, VE }, { "chromaoffset", "QP difference between chroma and luma", OFFSET(chroma_offset), AV_OPT_TYPE_INT, { .i64 = 0 }, INT_MIN, INT_MAX, VE },
{ "sc_threshold", "Scene change threshold", OFFSET(scenechange_threshold), AV_OPT_TYPE_INT, { .i64 = -1 }, INT_MIN, INT_MAX, VE }, { "sc_threshold", "Scene change threshold", OFFSET(scenechange_threshold), AV_OPT_TYPE_INT, { .i64 = -1 }, INT_MIN, INT_MAX, VE },
{ "noise_reduction", "Noise reduction", OFFSET(noise_reduction), AV_OPT_TYPE_INT, { .i64 = -1 }, INT_MIN, INT_MAX, VE }, { "noise_reduction", "Noise reduction", OFFSET(noise_reduction), AV_OPT_TYPE_INT, { .i64 = -1 }, INT_MIN, INT_MAX, VE },
{ "udu_sei", "Use user data unregistered SEI if available", OFFSET(udu_sei), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
{ "x264-params", "Override the x264 configuration using a :-separated list of key=value parameters", OFFSET(x264_params), AV_OPT_TYPE_DICT, { 0 }, 0, 0, VE }, { "x264-params", "Override the x264 configuration using a :-separated list of key=value parameters", OFFSET(x264_params), AV_OPT_TYPE_DICT, { 0 }, 0, 0, VE },
{ NULL }, { NULL },
}; };

View File

@@ -54,6 +54,7 @@ typedef struct libx265Context {
void *sei_data; void *sei_data;
int sei_data_size; int sei_data_size;
int udu_sei;
/** /**
* If the encoder does not support ROI then warn the first time we * If the encoder does not support ROI then warn the first time we
@@ -543,6 +544,7 @@ static int libx265_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
memcpy(x265pic.userData, &pic->reordered_opaque, sizeof(pic->reordered_opaque)); memcpy(x265pic.userData, &pic->reordered_opaque, sizeof(pic->reordered_opaque));
} }
if (ctx->udu_sei) {
for (i = 0; i < pic->nb_side_data; i++) { for (i = 0; i < pic->nb_side_data; i++) {
AVFrameSideData *side_data = pic->side_data[i]; AVFrameSideData *side_data = pic->side_data[i];
void *tmp; void *tmp;
@@ -568,6 +570,7 @@ static int libx265_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
sei_payload->payloadType = SEI_TYPE_USER_DATA_UNREGISTERED; sei_payload->payloadType = SEI_TYPE_USER_DATA_UNREGISTERED;
sei->numPayloads++; sei->numPayloads++;
} }
}
} }
ret = ctx->api->encoder_encode(ctx->encoder, &nal, &nnal, ret = ctx->api->encoder_encode(ctx->encoder, &nal, &nnal,
@@ -708,6 +711,7 @@ static const AVOption options[] = {
{ "preset", "set the x265 preset", OFFSET(preset), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE }, { "preset", "set the x265 preset", OFFSET(preset), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE },
{ "tune", "set the x265 tune parameter", OFFSET(tune), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE }, { "tune", "set the x265 tune parameter", OFFSET(tune), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE },
{ "profile", "set the x265 profile", OFFSET(profile), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE }, { "profile", "set the x265 profile", OFFSET(profile), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE },
{ "udu_sei", "Use user data unregistered SEI if available", OFFSET(udu_sei), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
{ "x265-params", "set the x265 configuration using a :-separated list of key=value parameters", OFFSET(x265_opts), AV_OPT_TYPE_DICT, { 0 }, 0, 0, VE }, { "x265-params", "set the x265 configuration using a :-separated list of key=value parameters", OFFSET(x265_opts), AV_OPT_TYPE_DICT, { 0 }, 0, 0, VE },
{ NULL } { NULL }
}; };

View File

@@ -29,7 +29,7 @@
#define LIBAVCODEC_VERSION_MAJOR 59 #define LIBAVCODEC_VERSION_MAJOR 59
#define LIBAVCODEC_VERSION_MINOR 15 #define LIBAVCODEC_VERSION_MINOR 15
#define LIBAVCODEC_VERSION_MICRO 101 #define LIBAVCODEC_VERSION_MICRO 102
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
LIBAVCODEC_VERSION_MINOR, \ LIBAVCODEC_VERSION_MINOR, \