Message ID | 20230712183252.302971-2-jeebjp@gmail.com |
---|---|
State | New |
Headers | show |
Series | avcodec: move HDR10 (MDCV/CLL) SEI handling to h2645_sei | expand |
Context | Check | Description |
---|---|---|
yinshiyou/make_loongarch64 | success | Make finished |
yinshiyou/make_fate_loongarch64 | success | Make fate finished |
andriy/make_x86 | success | Make finished |
andriy/make_fate_x86 | success | Make fate finished |
On 7/12/23 14:32, Jan Ekström wrote: > This allows this common H.274 SEI to be parsed from both H.264 > as well as HEVC, as well as probably from VVC in the future. > > Generally attempts to keep the original code as similar as possible. > > FATE test refererence changes only change the order of side data > export within a single frame. Nothing else seems to have changed. > --- > libavcodec/h2645_sei.c | 79 +++++++++++++++++++++++++ > libavcodec/h2645_sei.h | 9 +++ > libavcodec/h264_slice.c | 1 + > libavcodec/hevc_sei.c | 31 ---------- > libavcodec/hevc_sei.h | 9 --- > libavcodec/hevcdec.c | 50 +--------------- > tests/ref/fate/hevc-hdr-vivid-metadata | 16 ++--- > tests/ref/fate/hevc-hdr10-plus-metadata | 10 ++-- > 8 files changed, 105 insertions(+), 100 deletions(-) > > diff --git a/libavcodec/h2645_sei.c b/libavcodec/h2645_sei.c > index 63ab711bc9..ea01e75405 100644 > --- a/libavcodec/h2645_sei.c > +++ b/libavcodec/h2645_sei.c > @@ -26,6 +26,7 @@ > #include "config_components.h" > > #include "libavutil/ambient_viewing_environment.h" > +#include "libavutil/mastering_display_metadata.h" Nitpick: This isn't alphabetized. > #include "libavutil/display.h" > #include "libavutil/hdr_dynamic_metadata.h" > #include "libavutil/film_grain_params.h" > @@ -392,6 +393,35 @@ static int decode_film_grain_characteristics(H2645SEIFilmGrainCharacteristics *h > return 0; > } > > +static int decode_nal_sei_mastering_display_info(H2645SEIMasteringDisplay *s, > + GetByteContext *gb) > +{ > + int i; It seems a bit clearer to me if you inline the declaration into the for loop, the only place it's used. > + > + if (bytestream2_get_bytes_left(gb) < 24) > + return AVERROR_INVALIDDATA; > + > + // Mastering primaries > + for (i = 0; i < 3; i++) { > + s->display_primaries[i][0] = bytestream2_get_be16u(gb); > + s->display_primaries[i][1] = bytestream2_get_be16u(gb); > + } > + // White point (x, y) > + s->white_point[0] = bytestream2_get_be16u(gb); > + s->white_point[1] = bytestream2_get_be16u(gb); > + > + // Max and min luminance of mastering display > + s->max_luminance = bytestream2_get_be32u(gb); > + s->min_luminance = bytestream2_get_be32u(gb); > + > + // As this SEI message comes before the first frame that references it, > + // initialize the flag to 2 and decrement on IRAP access unit so it > + // persists for the coded video sequence (e.g., between two IRAPs) > + s->present = 2; > + > + return 0; > +} > + > int ff_h2645_sei_message_decode(H2645SEI *h, enum SEIType type, > enum AVCodecID codec_id, GetBitContext *gb, > GetByteContext *gbyte, void *logctx) > @@ -412,6 +442,9 @@ int ff_h2645_sei_message_decode(H2645SEI *h, enum SEIType type, > case SEI_TYPE_AMBIENT_VIEWING_ENVIRONMENT: > return decode_ambient_viewing_environment(&h->ambient_viewing_environment, > gbyte); > + case SEI_TYPE_MASTERING_DISPLAY_COLOUR_VOLUME: > + return decode_nal_sei_mastering_display_info(&h->mastering_display, > + gbyte); > default: > return FF_H2645_SEI_MESSAGE_UNHANDLED; > } > @@ -652,6 +685,51 @@ int ff_h2645_sei_to_frame(AVFrame *frame, H2645SEI *sei, > dst_env->ambient_light_y = av_make_q(env->ambient_light_y, 50000); > } > > + if (sei->mastering_display.present) { > + // HEVC uses a g,b,r ordering, which we convert to a more natural r,g,b > + const int mapping[3] = {2, 0, 1}; > + const int chroma_den = 50000; > + const int luma_den = 10000; > + int i; > + AVMasteringDisplayMetadata *metadata = > + av_mastering_display_metadata_create_side_data(frame); > + if (!metadata) > + return AVERROR(ENOMEM); > + > + for (i = 0; i < 3; i++) { > + const int j = mapping[i]; > + metadata->display_primaries[i][0].num = sei->mastering_display.display_primaries[j][0]; > + metadata->display_primaries[i][0].den = chroma_den; > + metadata->display_primaries[i][1].num = sei->mastering_display.display_primaries[j][1]; > + metadata->display_primaries[i][1].den = chroma_den; > + } > + metadata->white_point[0].num = sei->mastering_display.white_point[0]; > + metadata->white_point[0].den = chroma_den; > + metadata->white_point[1].num = sei->mastering_display.white_point[1]; > + metadata->white_point[1].den = chroma_den; > + > + metadata->max_luminance.num = sei->mastering_display.max_luminance; > + metadata->max_luminance.den = luma_den; > + metadata->min_luminance.num = sei->mastering_display.min_luminance; > + metadata->min_luminance.den = luma_den; > + metadata->has_luminance = 1; > + metadata->has_primaries = 1; > + > + av_log(avctx, AV_LOG_DEBUG, "Mastering Display Metadata:\n"); > + av_log(avctx, AV_LOG_DEBUG, > + "r(%5.4f,%5.4f) g(%5.4f,%5.4f) b(%5.4f %5.4f) wp(%5.4f, %5.4f)\n", > + av_q2d(metadata->display_primaries[0][0]), > + av_q2d(metadata->display_primaries[0][1]), > + av_q2d(metadata->display_primaries[1][0]), > + av_q2d(metadata->display_primaries[1][1]), > + av_q2d(metadata->display_primaries[2][0]), > + av_q2d(metadata->display_primaries[2][1]), > + av_q2d(metadata->white_point[0]), av_q2d(metadata->white_point[1])); > + av_log(avctx, AV_LOG_DEBUG, > + "min_luminance=%f, max_luminance=%f\n", > + av_q2d(metadata->min_luminance), av_q2d(metadata->max_luminance)); Is there any particular reason these are %f but the ones above are %5.4f? Not a big deal, just curious. > + } > + > return 0; > } > > @@ -667,4 +745,5 @@ void ff_h2645_sei_reset(H2645SEI *s) > av_buffer_unref(&s->dynamic_hdr_vivid.info); > > s->ambient_viewing_environment.present = 0; > + s->mastering_display.present = 0; > } > diff --git a/libavcodec/h2645_sei.h b/libavcodec/h2645_sei.h > index e07ae10376..83e1b2ec16 100644 > --- a/libavcodec/h2645_sei.h > +++ b/libavcodec/h2645_sei.h > @@ -105,6 +105,14 @@ typedef struct H2645SEIFilmGrainCharacteristics { > int persistence_flag; //< HEVC only > } H2645SEIFilmGrainCharacteristics; > > +typedef struct H2645SEIMasteringDisplay { > + int present; > + uint16_t display_primaries[3][2]; > + uint16_t white_point[2]; > + uint32_t max_luminance; > + uint32_t min_luminance; > +} H2645SEIMasteringDisplay; > + > typedef struct H2645SEI { > H2645SEIA53Caption a53_caption; > H2645SEIAFD afd; > @@ -116,6 +124,7 @@ typedef struct H2645SEI { > H2645SEIAlternativeTransfer alternative_transfer; > H2645SEIFilmGrainCharacteristics film_grain_characteristics; > H2645SEIAmbientViewingEnvironment ambient_viewing_environment; > + H2645SEIMasteringDisplay mastering_display; > } H2645SEI; > > enum { > diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c > index 41bf30eefc..586ce20bba 100644 > --- a/libavcodec/h264_slice.c > +++ b/libavcodec/h264_slice.c > @@ -439,6 +439,7 @@ int ff_h264_update_thread_context(AVCodecContext *dst, > return ret; > > h->sei.common.unregistered.x264_build = h1->sei.common.unregistered.x264_build; > + h->sei.common.mastering_display = h1->sei.common.mastering_display; > > if (!h->cur_pic_ptr) > return 0; > diff --git a/libavcodec/hevc_sei.c b/libavcodec/hevc_sei.c > index 3c6bde1b62..b7b77d4d0c 100644 > --- a/libavcodec/hevc_sei.c > +++ b/libavcodec/hevc_sei.c > @@ -49,35 +49,6 @@ static int decode_nal_sei_decoded_picture_hash(HEVCSEIPictureHash *s, > return 0; > } > > -static int decode_nal_sei_mastering_display_info(HEVCSEIMasteringDisplay *s, > - GetByteContext *gb) > -{ > - int i; > - > - if (bytestream2_get_bytes_left(gb) < 24) > - return AVERROR_INVALIDDATA; > - > - // Mastering primaries > - for (i = 0; i < 3; i++) { > - s->display_primaries[i][0] = bytestream2_get_be16u(gb); > - s->display_primaries[i][1] = bytestream2_get_be16u(gb); > - } > - // White point (x, y) > - s->white_point[0] = bytestream2_get_be16u(gb); > - s->white_point[1] = bytestream2_get_be16u(gb); > - > - // Max and min luminance of mastering display > - s->max_luminance = bytestream2_get_be32u(gb); > - s->min_luminance = bytestream2_get_be32u(gb); > - > - // As this SEI message comes before the first frame that references it, > - // initialize the flag to 2 and decrement on IRAP access unit so it > - // persists for the coded video sequence (e.g., between two IRAPs) > - s->present = 2; > - > - return 0; > -} > - > static int decode_nal_sei_content_light_info(HEVCSEIContentLight *s, > GetByteContext *gb) > { > @@ -206,8 +177,6 @@ static int decode_nal_sei_prefix(GetBitContext *gb, GetByteContext *gbyte, > return decode_nal_sei_decoded_picture_hash(&s->picture_hash, gbyte); > case SEI_TYPE_PIC_TIMING: > return decode_nal_sei_pic_timing(s, gb, ps, logctx); > - case SEI_TYPE_MASTERING_DISPLAY_COLOUR_VOLUME: > - return decode_nal_sei_mastering_display_info(&s->mastering_display, gbyte); > case SEI_TYPE_CONTENT_LIGHT_LEVEL_INFO: > return decode_nal_sei_content_light_info(&s->content_light, gbyte); > case SEI_TYPE_ACTIVE_PARAMETER_SETS: > diff --git a/libavcodec/hevc_sei.h b/libavcodec/hevc_sei.h > index 4189f5e6f7..077abdc74a 100644 > --- a/libavcodec/hevc_sei.h > +++ b/libavcodec/hevc_sei.h > @@ -53,14 +53,6 @@ typedef struct HEVCSEIPictureTiming { > int picture_struct; > } HEVCSEIPictureTiming; > > -typedef struct HEVCSEIMasteringDisplay { > - int present; > - uint16_t display_primaries[3][2]; > - uint16_t white_point[2]; > - uint32_t max_luminance; > - uint32_t min_luminance; > -} HEVCSEIMasteringDisplay; > - > typedef struct HEVCSEIContentLight { > int present; > uint16_t max_content_light_level; > @@ -96,7 +88,6 @@ typedef struct HEVCSEI { > H2645SEI common; > HEVCSEIPictureHash picture_hash; > HEVCSEIPictureTiming picture_timing; > - HEVCSEIMasteringDisplay mastering_display; > HEVCSEIContentLight content_light; > int active_seq_parameter_set_id; > HEVCSEITimeCode timecode; > diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c > index fcf19b4eb6..434750965b 100644 > --- a/libavcodec/hevcdec.c > +++ b/libavcodec/hevcdec.c > @@ -2763,53 +2763,9 @@ static int set_side_data(HEVCContext *s) > > // Decrement the mastering display flag when IRAP frame has no_rasl_output_flag=1 > // so the side data persists for the entire coded video sequence. > - if (s->sei.mastering_display.present > 0 && > + if (s->sei.common.mastering_display.present > 0 && > IS_IRAP(s) && s->no_rasl_output_flag) { > - s->sei.mastering_display.present--; > - } > - if (s->sei.mastering_display.present) { > - // HEVC uses a g,b,r ordering, which we convert to a more natural r,g,b > - const int mapping[3] = {2, 0, 1}; > - const int chroma_den = 50000; > - const int luma_den = 10000; > - int i; > - AVMasteringDisplayMetadata *metadata = > - av_mastering_display_metadata_create_side_data(out); > - if (!metadata) > - return AVERROR(ENOMEM); > - > - for (i = 0; i < 3; i++) { > - const int j = mapping[i]; > - metadata->display_primaries[i][0].num = s->sei.mastering_display.display_primaries[j][0]; > - metadata->display_primaries[i][0].den = chroma_den; > - metadata->display_primaries[i][1].num = s->sei.mastering_display.display_primaries[j][1]; > - metadata->display_primaries[i][1].den = chroma_den; > - } > - metadata->white_point[0].num = s->sei.mastering_display.white_point[0]; > - metadata->white_point[0].den = chroma_den; > - metadata->white_point[1].num = s->sei.mastering_display.white_point[1]; > - metadata->white_point[1].den = chroma_den; > - > - metadata->max_luminance.num = s->sei.mastering_display.max_luminance; > - metadata->max_luminance.den = luma_den; > - metadata->min_luminance.num = s->sei.mastering_display.min_luminance; > - metadata->min_luminance.den = luma_den; > - metadata->has_luminance = 1; > - metadata->has_primaries = 1; > - > - av_log(s->avctx, AV_LOG_DEBUG, "Mastering Display Metadata:\n"); > - av_log(s->avctx, AV_LOG_DEBUG, > - "r(%5.4f,%5.4f) g(%5.4f,%5.4f) b(%5.4f %5.4f) wp(%5.4f, %5.4f)\n", > - av_q2d(metadata->display_primaries[0][0]), > - av_q2d(metadata->display_primaries[0][1]), > - av_q2d(metadata->display_primaries[1][0]), > - av_q2d(metadata->display_primaries[1][1]), > - av_q2d(metadata->display_primaries[2][0]), > - av_q2d(metadata->display_primaries[2][1]), > - av_q2d(metadata->white_point[0]), av_q2d(metadata->white_point[1])); > - av_log(s->avctx, AV_LOG_DEBUG, > - "min_luminance=%f, max_luminance=%f\n", > - av_q2d(metadata->min_luminance), av_q2d(metadata->max_luminance)); > + s->sei.common.mastering_display.present--; > } > // Decrement the mastering display flag when IRAP frame has no_rasl_output_flag=1 > // so the side data persists for the entire coded video sequence. > @@ -3667,7 +3623,7 @@ static int hevc_update_thread_context(AVCodecContext *dst, > s->sei.common.frame_packing = s0->sei.common.frame_packing; > s->sei.common.display_orientation = s0->sei.common.display_orientation; > s->sei.common.alternative_transfer = s0->sei.common.alternative_transfer; > - s->sei.mastering_display = s0->sei.mastering_display; > + s->sei.common.mastering_display = s0->sei.common.mastering_display; > s->sei.content_light = s0->sei.content_light; > > ret = export_stream_params_from_sei(s); > diff --git a/tests/ref/fate/hevc-hdr-vivid-metadata b/tests/ref/fate/hevc-hdr-vivid-metadata > index 5f69973098..cb5db4557f 100644 > --- a/tests/ref/fate/hevc-hdr-vivid-metadata > +++ b/tests/ref/fate/hevc-hdr-vivid-metadata > @@ -1,5 +1,13 @@ > [FRAME] > [SIDE_DATA] > +side_data_type=Content light level metadata > +max_content=0 > +max_average=0 > +[/SIDE_DATA] > +[SIDE_DATA] > +side_data_type=H.26[45] User Data Unregistered SEI message > +[/SIDE_DATA] > +[SIDE_DATA] > side_data_type=Mastering display metadata > red_x=34000/50000 > red_y=16000/50000 > @@ -13,14 +21,6 @@ min_luminance=50/10000 > max_luminance=40000000/10000 > [/SIDE_DATA] > [SIDE_DATA] > -side_data_type=Content light level metadata > -max_content=0 > -max_average=0 > -[/SIDE_DATA] > -[SIDE_DATA] > -side_data_type=H.26[45] User Data Unregistered SEI message > -[/SIDE_DATA] > -[SIDE_DATA] > side_data_type=HDR Dynamic Metadata CUVA 005.1 2021 (Vivid) > system_start_code=1 > num_windows=1 > diff --git a/tests/ref/fate/hevc-hdr10-plus-metadata b/tests/ref/fate/hevc-hdr10-plus-metadata > index f226cd8c7b..cdf308b96a 100644 > --- a/tests/ref/fate/hevc-hdr10-plus-metadata > +++ b/tests/ref/fate/hevc-hdr10-plus-metadata > @@ -1,5 +1,10 @@ > [FRAME] > [SIDE_DATA] > +side_data_type=Content light level metadata > +max_content=1000 > +max_average=200 > +[/SIDE_DATA] > +[SIDE_DATA] > side_data_type=Mastering display metadata > red_x=13250/50000 > red_y=34500/50000 > @@ -13,11 +18,6 @@ min_luminance=50/10000 > max_luminance=10000000/10000 > [/SIDE_DATA] > [SIDE_DATA] > -side_data_type=Content light level metadata > -max_content=1000 > -max_average=200 > -[/SIDE_DATA] > -[SIDE_DATA] > side_data_type=HDR Dynamic Metadata SMPTE2094-40 (HDR10+) > application version=1 > num_windows=1
diff --git a/libavcodec/h2645_sei.c b/libavcodec/h2645_sei.c index 63ab711bc9..ea01e75405 100644 --- a/libavcodec/h2645_sei.c +++ b/libavcodec/h2645_sei.c @@ -26,6 +26,7 @@ #include "config_components.h" #include "libavutil/ambient_viewing_environment.h" +#include "libavutil/mastering_display_metadata.h" #include "libavutil/display.h" #include "libavutil/hdr_dynamic_metadata.h" #include "libavutil/film_grain_params.h" @@ -392,6 +393,35 @@ static int decode_film_grain_characteristics(H2645SEIFilmGrainCharacteristics *h return 0; } +static int decode_nal_sei_mastering_display_info(H2645SEIMasteringDisplay *s, + GetByteContext *gb) +{ + int i; + + if (bytestream2_get_bytes_left(gb) < 24) + return AVERROR_INVALIDDATA; + + // Mastering primaries + for (i = 0; i < 3; i++) { + s->display_primaries[i][0] = bytestream2_get_be16u(gb); + s->display_primaries[i][1] = bytestream2_get_be16u(gb); + } + // White point (x, y) + s->white_point[0] = bytestream2_get_be16u(gb); + s->white_point[1] = bytestream2_get_be16u(gb); + + // Max and min luminance of mastering display + s->max_luminance = bytestream2_get_be32u(gb); + s->min_luminance = bytestream2_get_be32u(gb); + + // As this SEI message comes before the first frame that references it, + // initialize the flag to 2 and decrement on IRAP access unit so it + // persists for the coded video sequence (e.g., between two IRAPs) + s->present = 2; + + return 0; +} + int ff_h2645_sei_message_decode(H2645SEI *h, enum SEIType type, enum AVCodecID codec_id, GetBitContext *gb, GetByteContext *gbyte, void *logctx) @@ -412,6 +442,9 @@ int ff_h2645_sei_message_decode(H2645SEI *h, enum SEIType type, case SEI_TYPE_AMBIENT_VIEWING_ENVIRONMENT: return decode_ambient_viewing_environment(&h->ambient_viewing_environment, gbyte); + case SEI_TYPE_MASTERING_DISPLAY_COLOUR_VOLUME: + return decode_nal_sei_mastering_display_info(&h->mastering_display, + gbyte); default: return FF_H2645_SEI_MESSAGE_UNHANDLED; } @@ -652,6 +685,51 @@ int ff_h2645_sei_to_frame(AVFrame *frame, H2645SEI *sei, dst_env->ambient_light_y = av_make_q(env->ambient_light_y, 50000); } + if (sei->mastering_display.present) { + // HEVC uses a g,b,r ordering, which we convert to a more natural r,g,b + const int mapping[3] = {2, 0, 1}; + const int chroma_den = 50000; + const int luma_den = 10000; + int i; + AVMasteringDisplayMetadata *metadata = + av_mastering_display_metadata_create_side_data(frame); + if (!metadata) + return AVERROR(ENOMEM); + + for (i = 0; i < 3; i++) { + const int j = mapping[i]; + metadata->display_primaries[i][0].num = sei->mastering_display.display_primaries[j][0]; + metadata->display_primaries[i][0].den = chroma_den; + metadata->display_primaries[i][1].num = sei->mastering_display.display_primaries[j][1]; + metadata->display_primaries[i][1].den = chroma_den; + } + metadata->white_point[0].num = sei->mastering_display.white_point[0]; + metadata->white_point[0].den = chroma_den; + metadata->white_point[1].num = sei->mastering_display.white_point[1]; + metadata->white_point[1].den = chroma_den; + + metadata->max_luminance.num = sei->mastering_display.max_luminance; + metadata->max_luminance.den = luma_den; + metadata->min_luminance.num = sei->mastering_display.min_luminance; + metadata->min_luminance.den = luma_den; + metadata->has_luminance = 1; + metadata->has_primaries = 1; + + av_log(avctx, AV_LOG_DEBUG, "Mastering Display Metadata:\n"); + av_log(avctx, AV_LOG_DEBUG, + "r(%5.4f,%5.4f) g(%5.4f,%5.4f) b(%5.4f %5.4f) wp(%5.4f, %5.4f)\n", + av_q2d(metadata->display_primaries[0][0]), + av_q2d(metadata->display_primaries[0][1]), + av_q2d(metadata->display_primaries[1][0]), + av_q2d(metadata->display_primaries[1][1]), + av_q2d(metadata->display_primaries[2][0]), + av_q2d(metadata->display_primaries[2][1]), + av_q2d(metadata->white_point[0]), av_q2d(metadata->white_point[1])); + av_log(avctx, AV_LOG_DEBUG, + "min_luminance=%f, max_luminance=%f\n", + av_q2d(metadata->min_luminance), av_q2d(metadata->max_luminance)); + } + return 0; } @@ -667,4 +745,5 @@ void ff_h2645_sei_reset(H2645SEI *s) av_buffer_unref(&s->dynamic_hdr_vivid.info); s->ambient_viewing_environment.present = 0; + s->mastering_display.present = 0; } diff --git a/libavcodec/h2645_sei.h b/libavcodec/h2645_sei.h index e07ae10376..83e1b2ec16 100644 --- a/libavcodec/h2645_sei.h +++ b/libavcodec/h2645_sei.h @@ -105,6 +105,14 @@ typedef struct H2645SEIFilmGrainCharacteristics { int persistence_flag; //< HEVC only } H2645SEIFilmGrainCharacteristics; +typedef struct H2645SEIMasteringDisplay { + int present; + uint16_t display_primaries[3][2]; + uint16_t white_point[2]; + uint32_t max_luminance; + uint32_t min_luminance; +} H2645SEIMasteringDisplay; + typedef struct H2645SEI { H2645SEIA53Caption a53_caption; H2645SEIAFD afd; @@ -116,6 +124,7 @@ typedef struct H2645SEI { H2645SEIAlternativeTransfer alternative_transfer; H2645SEIFilmGrainCharacteristics film_grain_characteristics; H2645SEIAmbientViewingEnvironment ambient_viewing_environment; + H2645SEIMasteringDisplay mastering_display; } H2645SEI; enum { diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c index 41bf30eefc..586ce20bba 100644 --- a/libavcodec/h264_slice.c +++ b/libavcodec/h264_slice.c @@ -439,6 +439,7 @@ int ff_h264_update_thread_context(AVCodecContext *dst, return ret; h->sei.common.unregistered.x264_build = h1->sei.common.unregistered.x264_build; + h->sei.common.mastering_display = h1->sei.common.mastering_display; if (!h->cur_pic_ptr) return 0; diff --git a/libavcodec/hevc_sei.c b/libavcodec/hevc_sei.c index 3c6bde1b62..b7b77d4d0c 100644 --- a/libavcodec/hevc_sei.c +++ b/libavcodec/hevc_sei.c @@ -49,35 +49,6 @@ static int decode_nal_sei_decoded_picture_hash(HEVCSEIPictureHash *s, return 0; } -static int decode_nal_sei_mastering_display_info(HEVCSEIMasteringDisplay *s, - GetByteContext *gb) -{ - int i; - - if (bytestream2_get_bytes_left(gb) < 24) - return AVERROR_INVALIDDATA; - - // Mastering primaries - for (i = 0; i < 3; i++) { - s->display_primaries[i][0] = bytestream2_get_be16u(gb); - s->display_primaries[i][1] = bytestream2_get_be16u(gb); - } - // White point (x, y) - s->white_point[0] = bytestream2_get_be16u(gb); - s->white_point[1] = bytestream2_get_be16u(gb); - - // Max and min luminance of mastering display - s->max_luminance = bytestream2_get_be32u(gb); - s->min_luminance = bytestream2_get_be32u(gb); - - // As this SEI message comes before the first frame that references it, - // initialize the flag to 2 and decrement on IRAP access unit so it - // persists for the coded video sequence (e.g., between two IRAPs) - s->present = 2; - - return 0; -} - static int decode_nal_sei_content_light_info(HEVCSEIContentLight *s, GetByteContext *gb) { @@ -206,8 +177,6 @@ static int decode_nal_sei_prefix(GetBitContext *gb, GetByteContext *gbyte, return decode_nal_sei_decoded_picture_hash(&s->picture_hash, gbyte); case SEI_TYPE_PIC_TIMING: return decode_nal_sei_pic_timing(s, gb, ps, logctx); - case SEI_TYPE_MASTERING_DISPLAY_COLOUR_VOLUME: - return decode_nal_sei_mastering_display_info(&s->mastering_display, gbyte); case SEI_TYPE_CONTENT_LIGHT_LEVEL_INFO: return decode_nal_sei_content_light_info(&s->content_light, gbyte); case SEI_TYPE_ACTIVE_PARAMETER_SETS: diff --git a/libavcodec/hevc_sei.h b/libavcodec/hevc_sei.h index 4189f5e6f7..077abdc74a 100644 --- a/libavcodec/hevc_sei.h +++ b/libavcodec/hevc_sei.h @@ -53,14 +53,6 @@ typedef struct HEVCSEIPictureTiming { int picture_struct; } HEVCSEIPictureTiming; -typedef struct HEVCSEIMasteringDisplay { - int present; - uint16_t display_primaries[3][2]; - uint16_t white_point[2]; - uint32_t max_luminance; - uint32_t min_luminance; -} HEVCSEIMasteringDisplay; - typedef struct HEVCSEIContentLight { int present; uint16_t max_content_light_level; @@ -96,7 +88,6 @@ typedef struct HEVCSEI { H2645SEI common; HEVCSEIPictureHash picture_hash; HEVCSEIPictureTiming picture_timing; - HEVCSEIMasteringDisplay mastering_display; HEVCSEIContentLight content_light; int active_seq_parameter_set_id; HEVCSEITimeCode timecode; diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c index fcf19b4eb6..434750965b 100644 --- a/libavcodec/hevcdec.c +++ b/libavcodec/hevcdec.c @@ -2763,53 +2763,9 @@ static int set_side_data(HEVCContext *s) // Decrement the mastering display flag when IRAP frame has no_rasl_output_flag=1 // so the side data persists for the entire coded video sequence. - if (s->sei.mastering_display.present > 0 && + if (s->sei.common.mastering_display.present > 0 && IS_IRAP(s) && s->no_rasl_output_flag) { - s->sei.mastering_display.present--; - } - if (s->sei.mastering_display.present) { - // HEVC uses a g,b,r ordering, which we convert to a more natural r,g,b - const int mapping[3] = {2, 0, 1}; - const int chroma_den = 50000; - const int luma_den = 10000; - int i; - AVMasteringDisplayMetadata *metadata = - av_mastering_display_metadata_create_side_data(out); - if (!metadata) - return AVERROR(ENOMEM); - - for (i = 0; i < 3; i++) { - const int j = mapping[i]; - metadata->display_primaries[i][0].num = s->sei.mastering_display.display_primaries[j][0]; - metadata->display_primaries[i][0].den = chroma_den; - metadata->display_primaries[i][1].num = s->sei.mastering_display.display_primaries[j][1]; - metadata->display_primaries[i][1].den = chroma_den; - } - metadata->white_point[0].num = s->sei.mastering_display.white_point[0]; - metadata->white_point[0].den = chroma_den; - metadata->white_point[1].num = s->sei.mastering_display.white_point[1]; - metadata->white_point[1].den = chroma_den; - - metadata->max_luminance.num = s->sei.mastering_display.max_luminance; - metadata->max_luminance.den = luma_den; - metadata->min_luminance.num = s->sei.mastering_display.min_luminance; - metadata->min_luminance.den = luma_den; - metadata->has_luminance = 1; - metadata->has_primaries = 1; - - av_log(s->avctx, AV_LOG_DEBUG, "Mastering Display Metadata:\n"); - av_log(s->avctx, AV_LOG_DEBUG, - "r(%5.4f,%5.4f) g(%5.4f,%5.4f) b(%5.4f %5.4f) wp(%5.4f, %5.4f)\n", - av_q2d(metadata->display_primaries[0][0]), - av_q2d(metadata->display_primaries[0][1]), - av_q2d(metadata->display_primaries[1][0]), - av_q2d(metadata->display_primaries[1][1]), - av_q2d(metadata->display_primaries[2][0]), - av_q2d(metadata->display_primaries[2][1]), - av_q2d(metadata->white_point[0]), av_q2d(metadata->white_point[1])); - av_log(s->avctx, AV_LOG_DEBUG, - "min_luminance=%f, max_luminance=%f\n", - av_q2d(metadata->min_luminance), av_q2d(metadata->max_luminance)); + s->sei.common.mastering_display.present--; } // Decrement the mastering display flag when IRAP frame has no_rasl_output_flag=1 // so the side data persists for the entire coded video sequence. @@ -3667,7 +3623,7 @@ static int hevc_update_thread_context(AVCodecContext *dst, s->sei.common.frame_packing = s0->sei.common.frame_packing; s->sei.common.display_orientation = s0->sei.common.display_orientation; s->sei.common.alternative_transfer = s0->sei.common.alternative_transfer; - s->sei.mastering_display = s0->sei.mastering_display; + s->sei.common.mastering_display = s0->sei.common.mastering_display; s->sei.content_light = s0->sei.content_light; ret = export_stream_params_from_sei(s); diff --git a/tests/ref/fate/hevc-hdr-vivid-metadata b/tests/ref/fate/hevc-hdr-vivid-metadata index 5f69973098..cb5db4557f 100644 --- a/tests/ref/fate/hevc-hdr-vivid-metadata +++ b/tests/ref/fate/hevc-hdr-vivid-metadata @@ -1,5 +1,13 @@ [FRAME] [SIDE_DATA] +side_data_type=Content light level metadata +max_content=0 +max_average=0 +[/SIDE_DATA] +[SIDE_DATA] +side_data_type=H.26[45] User Data Unregistered SEI message +[/SIDE_DATA] +[SIDE_DATA] side_data_type=Mastering display metadata red_x=34000/50000 red_y=16000/50000 @@ -13,14 +21,6 @@ min_luminance=50/10000 max_luminance=40000000/10000 [/SIDE_DATA] [SIDE_DATA] -side_data_type=Content light level metadata -max_content=0 -max_average=0 -[/SIDE_DATA] -[SIDE_DATA] -side_data_type=H.26[45] User Data Unregistered SEI message -[/SIDE_DATA] -[SIDE_DATA] side_data_type=HDR Dynamic Metadata CUVA 005.1 2021 (Vivid) system_start_code=1 num_windows=1 diff --git a/tests/ref/fate/hevc-hdr10-plus-metadata b/tests/ref/fate/hevc-hdr10-plus-metadata index f226cd8c7b..cdf308b96a 100644 --- a/tests/ref/fate/hevc-hdr10-plus-metadata +++ b/tests/ref/fate/hevc-hdr10-plus-metadata @@ -1,5 +1,10 @@ [FRAME] [SIDE_DATA] +side_data_type=Content light level metadata +max_content=1000 +max_average=200 +[/SIDE_DATA] +[SIDE_DATA] side_data_type=Mastering display metadata red_x=13250/50000 red_y=34500/50000 @@ -13,11 +18,6 @@ min_luminance=50/10000 max_luminance=10000000/10000 [/SIDE_DATA] [SIDE_DATA] -side_data_type=Content light level metadata -max_content=1000 -max_average=200 -[/SIDE_DATA] -[SIDE_DATA] side_data_type=HDR Dynamic Metadata SMPTE2094-40 (HDR10+) application version=1 num_windows=1