diff options
author | Mohammad Izadi <izadi@google.com> | 2020-11-23 13:29:34 -0800 |
---|---|---|
committer | James Almer <jamrial@gmail.com> | 2020-12-05 19:19:54 -0300 |
commit | afbc6852b439005b546d8067f35cf65b1dddb8ac (patch) | |
tree | be1ad56d27344c9546efc91a76cfde58fdb3ff4e /libavcodec/hevc_sei.c | |
parent | 530d1dbcef6b8de4e506e4248a313ba729dfdf4f (diff) | |
download | ffmpeg-afbc6852b439005b546d8067f35cf65b1dddb8ac.tar.gz |
avcodec/hevc_sei: add support for HDR10+ metadata
Signed-off-by: James Almer <jamrial@gmail.com>
Diffstat (limited to 'libavcodec/hevc_sei.c')
-rw-r--r-- | libavcodec/hevc_sei.c | 52 |
1 files changed, 44 insertions, 8 deletions
diff --git a/libavcodec/hevc_sei.c b/libavcodec/hevc_sei.c index 06e7a3a10c..4a0bc538c2 100644 --- a/libavcodec/hevc_sei.c +++ b/libavcodec/hevc_sei.c @@ -23,6 +23,7 @@ */ #include "atsc_a53.h" +#include "dynamic_hdr10_plus.h" #include "golomb.h" #include "hevc_ps.h" #include "hevc_sei.h" @@ -209,8 +210,11 @@ static int decode_nal_sei_user_data_unregistered(HEVCSEIUnregistered *s, GetBitC static int decode_nal_sei_user_data_registered_itu_t_t35(HEVCSEI *s, GetBitContext *gb, int size) { - uint32_t country_code; - uint32_t user_identifier; + const uint8_t usa_country_code = 0xB5; + const uint16_t smpte_provider_code = 0x003C; + + uint8_t country_code = 0; + uint16_t provider_code = 0; if (size < 7) return AVERROR(EINVAL); @@ -222,18 +226,49 @@ static int decode_nal_sei_user_data_registered_itu_t_t35(HEVCSEI *s, GetBitConte size--; } - skip_bits(gb, 8); - skip_bits(gb, 8); - - user_identifier = get_bits_long(gb, 32); + provider_code = get_bits(gb, 16); + + if (country_code == usa_country_code && + provider_code == smpte_provider_code) { + // A/341 Amendment – 2094-40 + const uint16_t smpte2094_40_provider_oriented_code = 0x0001; + const uint8_t smpte2094_40_application_identifier = 0x04; + + uint16_t provider_oriented_code = get_bits(gb, 16); + uint8_t application_identifier = get_bits(gb, 8); + + if (provider_oriented_code == smpte2094_40_provider_oriented_code && + application_identifier == smpte2094_40_application_identifier) { + int err = 0; + size_t meta_size = 0; + AVDynamicHDRPlus *metadata = av_dynamic_hdr_plus_alloc(&meta_size); + if (!metadata) + return AVERROR(ENOMEM); + + err = ff_parse_itu_t_t35_to_dynamic_hdr10_plus(gb, metadata); + if (err < 0) { + av_free(metadata); + return err; + } - switch (user_identifier) { + av_buffer_unref(&s->dynamic_hdr_plus.info); + s->dynamic_hdr_plus.info = av_buffer_create((uint8_t *)metadata, + meta_size, NULL, NULL, 0); + if (!s->dynamic_hdr_plus.info) { + av_free(metadata); + return AVERROR(ENOMEM); + } + } + } else { + uint32_t user_identifier = get_bits_long(gb, 32); + switch (user_identifier) { case MKBETAG('G', 'A', '9', '4'): return decode_registered_user_data_closed_caption(&s->a53_caption, gb, size); default: - skip_bits_long(gb, size * 8); break; + } } + skip_bits_long(gb, size * 8); return 0; } @@ -420,4 +455,5 @@ void ff_hevc_reset_sei(HEVCSEI *s) av_buffer_unref(&s->unregistered.buf_ref[i]); s->unregistered.nb_buf_ref = 0; av_freep(&s->unregistered.buf_ref); + av_buffer_unref(&s->dynamic_hdr_plus.info); } |