FFmpeg
sei.c
Go to the documentation of this file.
1 /*
2  * HEVC Supplementary Enhancement Information messages
3  *
4  * Copyright (C) 2012 - 2013 Guillaume Martres
5  * Copyright (C) 2012 - 2013 Gildas Cocherel
6  * Copyright (C) 2013 Vittorio Giovara
7  *
8  * This file is part of FFmpeg.
9  *
10  * FFmpeg is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Lesser General Public
12  * License as published by the Free Software Foundation; either
13  * version 2.1 of the License, or (at your option) any later version.
14  *
15  * FFmpeg is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  * Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public
21  * License along with FFmpeg; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23  */
24 
25 #include "bytestream.h"
26 #include "golomb.h"
27 #include "ps.h"
28 #include "sei.h"
29 
31  GetByteContext *gb)
32 {
33  int cIdx;
34  uint8_t hash_type;
35  //uint16_t picture_crc;
36  //uint32_t picture_checksum;
37  hash_type = bytestream2_get_byte(gb);
38 
39  for (cIdx = 0; cIdx < 3/*((s->sps->chroma_format_idc == 0) ? 1 : 3)*/; cIdx++) {
40  if (hash_type == 0) {
41  s->is_md5 = 1;
42  bytestream2_get_buffer(gb, s->md5[cIdx], sizeof(s->md5[cIdx]));
43  } else if (hash_type == 1) {
44  // picture_crc = get_bits(gb, 16);
45  } else if (hash_type == 2) {
46  // picture_checksum = get_bits_long(gb, 32);
47  }
48  }
49  return 0;
50 }
51 
53  const HEVCParamSets *ps, void *logctx)
54 {
55  HEVCSEIPictureTiming *h = &s->picture_timing;
56  const HEVCSPS *sps = ps->sps_list[s->active_seq_parameter_set_id];
57 
58  if (!sps)
59  return AVERROR_INVALIDDATA;
60 
61  if (sps->vui.frame_field_info_present_flag) {
62  int pic_struct = get_bits(gb, 4);
63  h->picture_struct = AV_PICTURE_STRUCTURE_UNKNOWN;
64  if (pic_struct == 2 || pic_struct == 10 || pic_struct == 12) {
65  av_log(logctx, AV_LOG_DEBUG, "BOTTOM Field\n");
66  h->picture_struct = AV_PICTURE_STRUCTURE_BOTTOM_FIELD;
67  } else if (pic_struct == 1 || pic_struct == 9 || pic_struct == 11) {
68  av_log(logctx, AV_LOG_DEBUG, "TOP Field\n");
69  h->picture_struct = AV_PICTURE_STRUCTURE_TOP_FIELD;
70  } else if (pic_struct == 7) {
71  av_log(logctx, AV_LOG_DEBUG, "Frame/Field Doubling\n");
72  h->picture_struct = HEVC_SEI_PIC_STRUCT_FRAME_DOUBLING;
73  } else if (pic_struct == 8) {
74  av_log(logctx, AV_LOG_DEBUG, "Frame/Field Tripling\n");
75  h->picture_struct = HEVC_SEI_PIC_STRUCT_FRAME_TRIPLING;
76  }
77  }
78 
79  return 0;
80 }
81 
83 {
84  int num_sps_ids_minus1;
85  unsigned active_seq_parameter_set_id;
86 
87  get_bits(gb, 4); // active_video_parameter_set_id
88  get_bits(gb, 1); // self_contained_cvs_flag
89  get_bits(gb, 1); // num_sps_ids_minus1
90  num_sps_ids_minus1 = get_ue_golomb_long(gb); // num_sps_ids_minus1
91 
92  if (num_sps_ids_minus1 < 0 || num_sps_ids_minus1 > 15) {
93  av_log(logctx, AV_LOG_ERROR, "num_sps_ids_minus1 %d invalid\n", num_sps_ids_minus1);
94  return AVERROR_INVALIDDATA;
95  }
96 
97  active_seq_parameter_set_id = get_ue_golomb_long(gb);
98  if (active_seq_parameter_set_id >= HEVC_MAX_SPS_COUNT) {
99  av_log(logctx, AV_LOG_ERROR, "active_parameter_set_id %d invalid\n", active_seq_parameter_set_id);
100  return AVERROR_INVALIDDATA;
101  }
102  s->active_seq_parameter_set_id = active_seq_parameter_set_id;
103 
104  return 0;
105 }
106 
108 {
109  s->num_clock_ts = get_bits(gb, 2);
110 
111  for (int i = 0; i < s->num_clock_ts; i++) {
112  s->clock_timestamp_flag[i] = get_bits(gb, 1);
113 
114  if (s->clock_timestamp_flag[i]) {
115  s->units_field_based_flag[i] = get_bits(gb, 1);
116  s->counting_type[i] = get_bits(gb, 5);
117  s->full_timestamp_flag[i] = get_bits(gb, 1);
118  s->discontinuity_flag[i] = get_bits(gb, 1);
119  s->cnt_dropped_flag[i] = get_bits(gb, 1);
120 
121  s->n_frames[i] = get_bits(gb, 9);
122 
123  if (s->full_timestamp_flag[i]) {
124  s->seconds_value[i] = av_clip(get_bits(gb, 6), 0, 59);
125  s->minutes_value[i] = av_clip(get_bits(gb, 6), 0, 59);
126  s->hours_value[i] = av_clip(get_bits(gb, 5), 0, 23);
127  } else {
128  s->seconds_flag[i] = get_bits(gb, 1);
129  if (s->seconds_flag[i]) {
130  s->seconds_value[i] = av_clip(get_bits(gb, 6), 0, 59);
131  s->minutes_flag[i] = get_bits(gb, 1);
132  if (s->minutes_flag[i]) {
133  s->minutes_value[i] = av_clip(get_bits(gb, 6), 0, 59);
134  s->hours_flag[i] = get_bits(gb, 1);
135  if (s->hours_flag[i]) {
136  s->hours_value[i] = av_clip(get_bits(gb, 5), 0, 23);
137  }
138  }
139  }
140  }
141 
142  s->time_offset_length[i] = get_bits(gb, 5);
143  if (s->time_offset_length[i] > 0) {
144  s->time_offset_value[i] = get_bits_long(gb, s->time_offset_length[i]);
145  }
146  }
147  }
148 
149  s->present = 1;
150  return 0;
151 }
152 
154 {
155  s->prec_ref_display_width = get_ue_golomb(gb);
156  if (s->prec_ref_display_width > 31)
157  return AVERROR_INVALIDDATA;
158  s->ref_viewing_distance_flag = get_bits1(gb);
159  if (s->ref_viewing_distance_flag) {
160  s->prec_ref_viewing_dist = get_ue_golomb(gb);
161  if (s->prec_ref_viewing_dist > 31)
162  return AVERROR_INVALIDDATA;
163  }
164  s->num_ref_displays = get_ue_golomb(gb);
165  if (s->num_ref_displays > 31)
166  return AVERROR_INVALIDDATA;
167  s->num_ref_displays += 1;
168 
169  for (int i = 0; i < s->num_ref_displays; i++) {
170  int length;
171  s->left_view_id[i] = get_ue_golomb(gb);
172  s->right_view_id[i] = get_ue_golomb(gb);
173  s->exponent_ref_display_width[i] = get_bits(gb, 6);
174  if (s->exponent_ref_display_width[i] > 62)
175  return AVERROR_INVALIDDATA;
176  else if (!s->exponent_ref_display_width[i])
177  length = FFMAX(0, (int)s->prec_ref_display_width - 30);
178  else
179  length = FFMAX(0, (int)s->exponent_ref_display_width[i] +
180  (int)s->prec_ref_display_width - 31);
181  s->mantissa_ref_display_width[i] = get_bits_long(gb, length);
182  if (s->ref_viewing_distance_flag) {
183  s->exponent_ref_viewing_distance[i] = get_bits(gb, 6);
184  if (s->exponent_ref_viewing_distance[i] > 62)
185  return AVERROR_INVALIDDATA;
186  else if (!s->exponent_ref_viewing_distance[i])
187  length = FFMAX(0, (int)s->prec_ref_viewing_dist - 30);
188  else
189  length = FFMAX(0, (int)s->exponent_ref_viewing_distance[i] +
190  (int)s->prec_ref_viewing_dist - 31);
191  s->mantissa_ref_viewing_distance[i] = get_bits_long(gb, length);
192  }
193  s->additional_shift_present_flag[i] = get_bits1(gb);
194  if (s->additional_shift_present_flag[i]) {
195  s->num_sample_shift[i] = get_bits(gb, 10);
196  if (s->num_sample_shift[i] > 1023)
197  return AVERROR_INVALIDDATA;
198  s->num_sample_shift[i] -= 512;
199  }
200  }
201  s->three_dimensional_reference_displays_extension_flag = get_bits1(gb);
202 
203  return 0;
204 }
205 
207  void *logctx, HEVCSEI *s,
208  const HEVCParamSets *ps, int type)
209 {
210  switch (type) {
211  case 256: // Mismatched value from HM 8.1
212  return decode_nal_sei_decoded_picture_hash(&s->picture_hash, gbyte);
213  case SEI_TYPE_PIC_TIMING:
214  return decode_nal_sei_pic_timing(s, gb, ps, logctx);
216  return decode_nal_sei_active_parameter_sets(s, gb, logctx);
217  case SEI_TYPE_TIME_CODE:
218  return decode_nal_sei_timecode(&s->timecode, gb);
220  return decode_nal_sei_3d_reference_displays_info(&s->tdrdi, gb);
221  default: {
223  gb, gbyte, logctx);
225  av_log(logctx, AV_LOG_DEBUG, "Skipped PREFIX SEI %d\n", type);
226  return ret;
227  }
228  }
229 }
230 
232  void *logctx, HEVCSEI *s, int type)
233 {
234  switch (type) {
236  return decode_nal_sei_decoded_picture_hash(&s->picture_hash, gbyte);
237  default:
238  av_log(logctx, AV_LOG_DEBUG, "Skipped SUFFIX SEI %d\n", type);
239  return 0;
240  }
241 }
242 
243 static int decode_nal_sei_message(GetByteContext *gb, void *logctx, HEVCSEI *s,
244  const HEVCParamSets *ps, int nal_unit_type)
245 {
246  GetByteContext message_gbyte;
247  GetBitContext message_gb;
248  int payload_type = 0;
249  int payload_size = 0;
250  int byte = 0xFF;
251  av_unused int ret;
252  av_log(logctx, AV_LOG_DEBUG, "Decoding SEI\n");
253 
254  while (byte == 0xFF) {
255  if (bytestream2_get_bytes_left(gb) < 2 || payload_type > INT_MAX - 255)
256  return AVERROR_INVALIDDATA;
257  byte = bytestream2_get_byteu(gb);
258  payload_type += byte;
259  }
260  byte = 0xFF;
261  while (byte == 0xFF) {
262  if (bytestream2_get_bytes_left(gb) < 1 + payload_size)
263  return AVERROR_INVALIDDATA;
264  byte = bytestream2_get_byteu(gb);
265  payload_size += byte;
266  }
267  if (bytestream2_get_bytes_left(gb) < payload_size)
268  return AVERROR_INVALIDDATA;
269  bytestream2_init(&message_gbyte, gb->buffer, payload_size);
270  ret = init_get_bits8(&message_gb, gb->buffer, payload_size);
271  av_assert1(ret >= 0);
272  bytestream2_skipu(gb, payload_size);
273  if (nal_unit_type == HEVC_NAL_SEI_PREFIX) {
274  return decode_nal_sei_prefix(&message_gb, &message_gbyte,
275  logctx, s, ps, payload_type);
276  } else { /* nal_unit_type == NAL_SEI_SUFFIX */
277  return decode_nal_sei_suffix(&message_gb, &message_gbyte,
278  logctx, s, payload_type);
279  }
280 }
281 
283  const HEVCParamSets *ps, enum HEVCNALUnitType type)
284 {
285  GetByteContext gbyte;
286  int ret;
287 
288  av_assert1((get_bits_count(gb) % 8) == 0);
289  bytestream2_init(&gbyte, gb->buffer + get_bits_count(gb) / 8,
290  get_bits_left(gb) / 8);
291 
292  do {
293  ret = decode_nal_sei_message(&gbyte, logctx, s, ps, type);
294  if (ret < 0)
295  return ret;
296  } while (bytestream2_get_bytes_left(&gbyte) > 0);
297  return 1;
298 }
av_clip
#define av_clip
Definition: common.h:100
get_bits_left
static int get_bits_left(GetBitContext *gb)
Definition: get_bits.h:695
GetByteContext
Definition: bytestream.h:33
AV_PICTURE_STRUCTURE_UNKNOWN
@ AV_PICTURE_STRUCTURE_UNKNOWN
unknown
Definition: avcodec.h:2742
get_bits_long
static unsigned int get_bits_long(GetBitContext *s, int n)
Read 0-32 bits.
Definition: get_bits.h:421
bytestream2_skipu
static av_always_inline void bytestream2_skipu(GetByteContext *g, unsigned int size)
Definition: bytestream.h:174
decode_nal_sei_suffix
static int decode_nal_sei_suffix(GetBitContext *gb, GetByteContext *gbyte, void *logctx, HEVCSEI *s, int type)
Definition: sei.c:231
get_bits_count
static int get_bits_count(const GetBitContext *s)
Definition: get_bits.h:266
av_unused
#define av_unused
Definition: attributes.h:131
get_ue_golomb
static int get_ue_golomb(GetBitContext *gb)
Read an unsigned Exp-Golomb code in the range 0 to 8190.
Definition: golomb.h:53
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
SEI_TYPE_THREE_DIMENSIONAL_REFERENCE_DISPLAYS_INFO
@ SEI_TYPE_THREE_DIMENSIONAL_REFERENCE_DISPLAYS_INFO
Definition: sei.h:127
ff_h2645_sei_message_decode
int ff_h2645_sei_message_decode(H2645SEI *h, enum SEIType type, enum AVCodecID codec_id, GetBitContext *gb, GetByteContext *gbyte, void *logctx)
Decode a single SEI message.
Definition: h2645_sei.c:485
decode_nal_sei_message
static int decode_nal_sei_message(GetByteContext *gb, void *logctx, HEVCSEI *s, const HEVCParamSets *ps, int nal_unit_type)
Definition: sei.c:243
HEVCSEITimeCode
Definition: sei.h:62
golomb.h
exp golomb vlc stuff
get_bits
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition: get_bits.h:335
HEVC_SEI_PIC_STRUCT_FRAME_TRIPLING
@ HEVC_SEI_PIC_STRUCT_FRAME_TRIPLING
Definition: sei.h:37
GetBitContext
Definition: get_bits.h:108
sei.h
decode_nal_sei_timecode
static int decode_nal_sei_timecode(HEVCSEITimeCode *s, GetBitContext *gb)
Definition: sei.c:107
type
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf type
Definition: writing_filters.txt:86
HEVCParamSets::sps_list
const HEVCSPS * sps_list[HEVC_MAX_SPS_COUNT]
RefStruct references.
Definition: ps.h:510
HEVC_NAL_SEI_PREFIX
@ HEVC_NAL_SEI_PREFIX
Definition: hevc.h:68
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
init_get_bits8
static int init_get_bits8(GetBitContext *s, const uint8_t *buffer, int byte_size)
Initialize GetBitContext.
Definition: get_bits.h:545
s
#define s(width, name)
Definition: cbs_vp9.c:198
HEVCNALUnitType
HEVCNALUnitType
Table 7-1 – NAL unit type codes and NAL unit type classes in T-REC-H.265-201802.
Definition: hevc.h:28
GetByteContext::buffer
const uint8_t * buffer
Definition: bytestream.h:34
HEVCSEI
Definition: sei.h:98
HEVCSEIPictureHash
Definition: sei.h:40
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:201
decode_nal_sei_active_parameter_sets
static int decode_nal_sei_active_parameter_sets(HEVCSEI *s, GetBitContext *gb, void *logctx)
Definition: sei.c:82
AV_PICTURE_STRUCTURE_BOTTOM_FIELD
@ AV_PICTURE_STRUCTURE_BOTTOM_FIELD
coded as bottom field
Definition: avcodec.h:2744
GetBitContext::buffer
const uint8_t * buffer
Definition: get_bits.h:109
SEI_TYPE_TIME_CODE
@ SEI_TYPE_TIME_CODE
Definition: sei.h:95
AV_PICTURE_STRUCTURE_TOP_FIELD
@ AV_PICTURE_STRUCTURE_TOP_FIELD
coded as top field
Definition: avcodec.h:2743
get_bits1
static unsigned int get_bits1(GetBitContext *s)
Definition: get_bits.h:388
bytestream2_get_buffer
static av_always_inline unsigned int bytestream2_get_buffer(GetByteContext *g, uint8_t *dst, unsigned int size)
Definition: bytestream.h:267
bytestream2_get_bytes_left
static av_always_inline int bytestream2_get_bytes_left(GetByteContext *g)
Definition: bytestream.h:158
HEVCSEITDRDI
Definition: sei.h:82
byte
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_WB24 unsigned int_TMPL AV_WB16 unsigned int_TMPL byte
Definition: bytestream.h:99
ps.h
decode_nal_sei_pic_timing
static int decode_nal_sei_pic_timing(HEVCSEI *s, GetBitContext *gb, const HEVCParamSets *ps, void *logctx)
Definition: sei.c:52
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
SEI_TYPE_PIC_TIMING
@ SEI_TYPE_PIC_TIMING
Definition: sei.h:31
av_assert1
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
Definition: avassert.h:56
AV_CODEC_ID_HEVC
@ AV_CODEC_ID_HEVC
Definition: codec_id.h:226
ret
ret
Definition: filter_design.txt:187
HEVC_SEI_PIC_STRUCT_FRAME_DOUBLING
@ HEVC_SEI_PIC_STRUCT_FRAME_DOUBLING
Definition: sei.h:36
sps
static int FUNC() sps(CodedBitstreamContext *ctx, RWContext *rw, H264RawSPS *current)
Definition: cbs_h264_syntax_template.c:260
decode_nal_sei_decoded_picture_hash
static int decode_nal_sei_decoded_picture_hash(HEVCSEIPictureHash *s, GetByteContext *gb)
Definition: sei.c:30
decode_nal_sei_3d_reference_displays_info
static int decode_nal_sei_3d_reference_displays_info(HEVCSEITDRDI *s, GetBitContext *gb)
Definition: sei.c:153
FF_H2645_SEI_MESSAGE_UNHANDLED
@ FF_H2645_SEI_MESSAGE_UNHANDLED
Definition: h2645_sei.h:147
SEI_TYPE_DECODED_PICTURE_HASH
@ SEI_TYPE_DECODED_PICTURE_HASH
Definition: sei.h:91
get_ue_golomb_long
static unsigned get_ue_golomb_long(GetBitContext *gb)
Read an unsigned Exp-Golomb code in the range 0 to UINT32_MAX-1.
Definition: golomb.h:104
HEVCSPS
Definition: ps.h:252
HEVC_MAX_SPS_COUNT
@ HEVC_MAX_SPS_COUNT
Definition: hevc.h:115
bytestream.h
bytestream2_init
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
Definition: bytestream.h:137
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
decode_nal_sei_prefix
static int decode_nal_sei_prefix(GetBitContext *gb, GetByteContext *gbyte, void *logctx, HEVCSEI *s, const HEVCParamSets *ps, int type)
Definition: sei.c:206
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
h
h
Definition: vp9dsp_template.c:2070
HEVCSEIPictureTiming
Definition: sei.h:53
SEI_TYPE_ACTIVE_PARAMETER_SETS
@ SEI_TYPE_ACTIVE_PARAMETER_SETS
Definition: sei.h:87
ff_hevc_decode_nal_sei
int ff_hevc_decode_nal_sei(GetBitContext *gb, void *logctx, HEVCSEI *s, const HEVCParamSets *ps, enum HEVCNALUnitType type)
Definition: sei.c:282
HEVCParamSets
Definition: ps.h:508