summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Almer <jamrial@gmail.com>2024-06-06 23:04:14 -0300
committerAnton Khirnov <anton@khirnov.net>2024-06-25 18:08:41 +0200
commita096f2382992118377c8b47e17da579cd55c5e74 (patch)
tree8c5e12d90db4a1f0e56196e7519f1048fc077b0e
parent3c1dd5aa4281de385a8cf02eaa8e16e01e186565 (diff)
avcodec/hevc/sei: add support for 3D Reference Displays Information SEI
Signed-off-by: James Almer <jamrial@gmail.com>
-rw-r--r--libavcodec/hevc/sei.c55
-rw-r--r--libavcodec/hevc/sei.h17
2 files changed, 72 insertions, 0 deletions
diff --git a/libavcodec/hevc/sei.c b/libavcodec/hevc/sei.c
index e39ac0c38a..6c2b55b43c 100644
--- a/libavcodec/hevc/sei.c
+++ b/libavcodec/hevc/sei.c
@@ -150,6 +150,59 @@ static int decode_nal_sei_timecode(HEVCSEITimeCode *s, GetBitContext *gb)
return 0;
}
+static int decode_nal_sei_3d_reference_displays_info(HEVCSEITDRDI *s, GetBitContext *gb)
+{
+ s->prec_ref_display_width = get_ue_golomb(gb);
+ if (s->prec_ref_display_width > 31)
+ return AVERROR_INVALIDDATA;
+ s->ref_viewing_distance_flag = get_bits1(gb);
+ if (s->ref_viewing_distance_flag) {
+ s->prec_ref_viewing_dist = get_ue_golomb(gb);
+ if (s->prec_ref_viewing_dist > 31)
+ return AVERROR_INVALIDDATA;
+ }
+ s->num_ref_displays = get_ue_golomb(gb);
+ if (s->num_ref_displays > 31)
+ return AVERROR_INVALIDDATA;
+ s->num_ref_displays += 1;
+
+ for (int i = 0; i < s->num_ref_displays; i++) {
+ int length;
+ s->left_view_id[i] = get_ue_golomb(gb);
+ s->right_view_id[i] = get_ue_golomb(gb);
+ s->exponent_ref_display_width[i] = get_bits(gb, 6);
+ if (s->exponent_ref_display_width[i] > 62)
+ return AVERROR_INVALIDDATA;
+ else if (!s->exponent_ref_display_width[i])
+ length = FFMAX(0, (int)s->prec_ref_display_width - 30);
+ else
+ length = FFMAX(0, (int)s->exponent_ref_display_width[i] +
+ (int)s->prec_ref_display_width - 31);
+ s->mantissa_ref_display_width[i] = get_bits_long(gb, length);
+ if (s->ref_viewing_distance_flag) {
+ s->exponent_ref_viewing_distance[i] = get_bits(gb, 6);
+ if (s->exponent_ref_viewing_distance[i] > 62)
+ return AVERROR_INVALIDDATA;
+ else if (!s->exponent_ref_viewing_distance[i])
+ length = FFMAX(0, (int)s->prec_ref_viewing_dist - 30);
+ else
+ length = FFMAX(0, (int)s->exponent_ref_viewing_distance[i] +
+ (int)s->prec_ref_viewing_dist - 31);
+ s->mantissa_ref_viewing_distance[i] = get_bits_long(gb, length);
+ }
+ s->additional_shift_present_flag[i] = get_bits1(gb);
+ if (s->additional_shift_present_flag[i]) {
+ s->num_sample_shift[i] = get_bits(gb, 10);
+ if (s->num_sample_shift[i] > 1023)
+ return AVERROR_INVALIDDATA;
+ s->num_sample_shift[i] -= 512;
+ }
+ }
+ s->three_dimensional_reference_displays_extension_flag = get_bits1(gb);
+
+ return 0;
+}
+
static int decode_nal_sei_prefix(GetBitContext *gb, GetByteContext *gbyte,
void *logctx, HEVCSEI *s,
const HEVCParamSets *ps, int type)
@@ -163,6 +216,8 @@ static int decode_nal_sei_prefix(GetBitContext *gb, GetByteContext *gbyte,
return decode_nal_sei_active_parameter_sets(s, gb, logctx);
case SEI_TYPE_TIME_CODE:
return decode_nal_sei_timecode(&s->timecode, gb);
+ case SEI_TYPE_THREE_DIMENSIONAL_REFERENCE_DISPLAYS_INFO:
+ return decode_nal_sei_3d_reference_displays_info(&s->tdrdi, gb);
default: {
int ret = ff_h2645_sei_message_decode(&s->common, type, AV_CODEC_ID_HEVC,
gb, gbyte, logctx);
diff --git a/libavcodec/hevc/sei.h b/libavcodec/hevc/sei.h
index c97d22d423..a233d432cc 100644
--- a/libavcodec/hevc/sei.h
+++ b/libavcodec/hevc/sei.h
@@ -79,12 +79,29 @@ typedef struct HEVCSEITimeCode {
int32_t time_offset_value[3];
} HEVCSEITimeCode;
+typedef struct HEVCSEITDRDI {
+ uint8_t prec_ref_display_width;
+ uint8_t ref_viewing_distance_flag;
+ uint8_t prec_ref_viewing_dist;
+ uint8_t num_ref_displays;
+ uint8_t left_view_id[31];
+ uint8_t right_view_id[31];
+ uint8_t exponent_ref_display_width[31];
+ uint8_t mantissa_ref_display_width[31];
+ uint8_t exponent_ref_viewing_distance[31];
+ uint8_t mantissa_ref_viewing_distance[31];
+ uint8_t additional_shift_present_flag[31];
+ int16_t num_sample_shift[31];
+ uint8_t three_dimensional_reference_displays_extension_flag;
+} HEVCSEITDRDI;
+
typedef struct HEVCSEI {
H2645SEI common;
HEVCSEIPictureHash picture_hash;
HEVCSEIPictureTiming picture_timing;
int active_seq_parameter_set_id;
HEVCSEITimeCode timecode;
+ HEVCSEITDRDI tdrdi;
} HEVCSEI;
struct HEVCParamSets;