If a sequence display extension is read with colour_description equal to zero, but a user wants to add one or more of the colour_description elements, then the colour_description elements the user did not explicitly request to be set are set to zero and not to the value equal to unknown/unspecified (namely 2). A value of zero is not only inappropriate, but explicitly forbidden. This is fixed by inferring the right default values during the reading process if the elements are absent; moreover, changing any of the colour_description elements to zero is now no longer possible. Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>tags/n4.3
| @@ -82,6 +82,10 @@ | |||||
| (get_bits_left(rw) >= width && \ | (get_bits_left(rw) >= width && \ | ||||
| (var = show_bits(rw, width)) == (compare)) | (var = show_bits(rw, width)) == (compare)) | ||||
| #define infer(name, value) do { \ | |||||
| current->name = value; \ | |||||
| } while (0) | |||||
| #include "cbs_mpeg2_syntax_template.c" | #include "cbs_mpeg2_syntax_template.c" | ||||
| #undef READ | #undef READ | ||||
| @@ -91,6 +95,7 @@ | |||||
| #undef xsi | #undef xsi | ||||
| #undef marker_bit | #undef marker_bit | ||||
| #undef nextbits | #undef nextbits | ||||
| #undef infer | |||||
| #define WRITE | #define WRITE | ||||
| @@ -116,6 +121,15 @@ | |||||
| #define nextbits(width, compare, var) (var) | #define nextbits(width, compare, var) (var) | ||||
| #define infer(name, value) do { \ | |||||
| if (current->name != (value)) { \ | |||||
| av_log(ctx->log_ctx, AV_LOG_WARNING, "Warning: " \ | |||||
| "%s does not match inferred value: " \ | |||||
| "%"PRId64", but should be %"PRId64".\n", \ | |||||
| #name, (int64_t)current->name, (int64_t)(value)); \ | |||||
| } \ | |||||
| } while (0) | |||||
| #include "cbs_mpeg2_syntax_template.c" | #include "cbs_mpeg2_syntax_template.c" | ||||
| #undef WRITE | #undef WRITE | ||||
| @@ -125,6 +139,7 @@ | |||||
| #undef xsi | #undef xsi | ||||
| #undef marker_bit | #undef marker_bit | ||||
| #undef nextbits | #undef nextbits | ||||
| #undef infer | |||||
| static void cbs_mpeg2_free_user_data(void *unit, uint8_t *content) | static void cbs_mpeg2_free_user_data(void *unit, uint8_t *content) | ||||
| @@ -144,6 +144,10 @@ static int FUNC(sequence_display_extension)(CodedBitstreamContext *ctx, RWContex | |||||
| uir(8, transfer_characteristics); | uir(8, transfer_characteristics); | ||||
| uir(8, matrix_coefficients); | uir(8, matrix_coefficients); | ||||
| #endif | #endif | ||||
| } else { | |||||
| infer(colour_primaries, 2); | |||||
| infer(transfer_characteristics, 2); | |||||
| infer(matrix_coefficients, 2); | |||||
| } | } | ||||
| ui(14, display_horizontal_size); | ui(14, display_horizontal_size); | ||||
| @@ -213,6 +213,18 @@ static int mpeg2_metadata_init(AVBSFContext *bsf) | |||||
| CodedBitstreamFragment *frag = &ctx->fragment; | CodedBitstreamFragment *frag = &ctx->fragment; | ||||
| int err; | int err; | ||||
| #define VALIDITY_CHECK(name) do { \ | |||||
| if (!ctx->name) { \ | |||||
| av_log(bsf, AV_LOG_ERROR, "The value 0 for %s is " \ | |||||
| "forbidden.\n", #name); \ | |||||
| return AVERROR(EINVAL); \ | |||||
| } \ | |||||
| } while (0) | |||||
| VALIDITY_CHECK(colour_primaries); | |||||
| VALIDITY_CHECK(transfer_characteristics); | |||||
| VALIDITY_CHECK(matrix_coefficients); | |||||
| #undef VALIDITY_CHECK | |||||
| err = ff_cbs_init(&ctx->cbc, AV_CODEC_ID_MPEG2VIDEO, bsf); | err = ff_cbs_init(&ctx->cbc, AV_CODEC_ID_MPEG2VIDEO, bsf); | ||||
| if (err < 0) | if (err < 0) | ||||
| return err; | return err; | ||||