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  void *logctx, HEVCSEI *s,
155  const HEVCParamSets *ps, int type)
156 {
157  switch (type) {
158  case 256: // Mismatched value from HM 8.1
159  return decode_nal_sei_decoded_picture_hash(&s->picture_hash, gbyte);
160  case SEI_TYPE_PIC_TIMING:
161  return decode_nal_sei_pic_timing(s, gb, ps, logctx);
163  return decode_nal_sei_active_parameter_sets(s, gb, logctx);
164  case SEI_TYPE_TIME_CODE:
165  return decode_nal_sei_timecode(&s->timecode, gb);
166  default: {
168  gb, gbyte, logctx);
170  av_log(logctx, AV_LOG_DEBUG, "Skipped PREFIX SEI %d\n", type);
171  return ret;
172  }
173  }
174 }
175 
177  void *logctx, HEVCSEI *s, int type)
178 {
179  switch (type) {
181  return decode_nal_sei_decoded_picture_hash(&s->picture_hash, gbyte);
182  default:
183  av_log(logctx, AV_LOG_DEBUG, "Skipped SUFFIX SEI %d\n", type);
184  return 0;
185  }
186 }
187 
188 static int decode_nal_sei_message(GetByteContext *gb, void *logctx, HEVCSEI *s,
189  const HEVCParamSets *ps, int nal_unit_type)
190 {
191  GetByteContext message_gbyte;
192  GetBitContext message_gb;
193  int payload_type = 0;
194  int payload_size = 0;
195  int byte = 0xFF;
196  av_unused int ret;
197  av_log(logctx, AV_LOG_DEBUG, "Decoding SEI\n");
198 
199  while (byte == 0xFF) {
200  if (bytestream2_get_bytes_left(gb) < 2 || payload_type > INT_MAX - 255)
201  return AVERROR_INVALIDDATA;
202  byte = bytestream2_get_byteu(gb);
203  payload_type += byte;
204  }
205  byte = 0xFF;
206  while (byte == 0xFF) {
207  if (bytestream2_get_bytes_left(gb) < 1 + payload_size)
208  return AVERROR_INVALIDDATA;
209  byte = bytestream2_get_byteu(gb);
210  payload_size += byte;
211  }
212  if (bytestream2_get_bytes_left(gb) < payload_size)
213  return AVERROR_INVALIDDATA;
214  bytestream2_init(&message_gbyte, gb->buffer, payload_size);
215  ret = init_get_bits8(&message_gb, gb->buffer, payload_size);
216  av_assert1(ret >= 0);
217  bytestream2_skipu(gb, payload_size);
218  if (nal_unit_type == HEVC_NAL_SEI_PREFIX) {
219  return decode_nal_sei_prefix(&message_gb, &message_gbyte,
220  logctx, s, ps, payload_type);
221  } else { /* nal_unit_type == NAL_SEI_SUFFIX */
222  return decode_nal_sei_suffix(&message_gb, &message_gbyte,
223  logctx, s, payload_type);
224  }
225 }
226 
228  const HEVCParamSets *ps, enum HEVCNALUnitType type)
229 {
230  GetByteContext gbyte;
231  int ret;
232 
233  av_assert1((get_bits_count(gb) % 8) == 0);
234  bytestream2_init(&gbyte, gb->buffer + get_bits_count(gb) / 8,
235  get_bits_left(gb) / 8);
236 
237  do {
238  ret = decode_nal_sei_message(&gbyte, logctx, s, ps, type);
239  if (ret < 0)
240  return ret;
241  } while (bytestream2_get_bytes_left(&gbyte) > 0);
242  return 1;
243 }
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:2706
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:176
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
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:463
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:188
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:448
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
HEVC_MAX_SPS_COUNT
@ HEVC_MAX_SPS_COUNT
Definition: hevc.h:112
GetByteContext::buffer
const uint8_t * buffer
Definition: bytestream.h:34
HEVCSEI
Definition: sei.h:82
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:2708
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:2707
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
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
FF_H2645_SEI_MESSAGE_UNHANDLED
@ FF_H2645_SEI_MESSAGE_UNHANDLED
Definition: h2645_sei.h:142
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
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:190
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:153
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:227
HEVCParamSets
Definition: ps.h:446