FFmpeg
Loading...
Searching...
No Matches
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
26#include "libavcodec/golomb.h"
27#include "ps.h"
28#include "sei.h"
29
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)
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 HEVCSEIRecoveryPoint *rec = &s->recovery_point;
85 int recovery_poc_cnt = get_se_golomb(gb);
86
87 if (recovery_poc_cnt > INT16_MAX || recovery_poc_cnt < INT16_MIN)
89 rec->recovery_poc_cnt = recovery_poc_cnt;
90 rec->exact_match_flag = get_bits1(gb);
91 rec->broken_link_flag = get_bits1(gb);
92 rec->has_recovery_poc = 1;
93
94 return 0;
95}
96
98{
99 int num_sps_ids_minus1;
100 unsigned active_seq_parameter_set_id;
101
102 get_bits(gb, 4); // active_video_parameter_set_id
103 get_bits(gb, 1); // self_contained_cvs_flag
104 get_bits(gb, 1); // num_sps_ids_minus1
105 num_sps_ids_minus1 = get_ue_golomb_long(gb); // num_sps_ids_minus1
106
107 if (num_sps_ids_minus1 < 0 || num_sps_ids_minus1 > 15) {
108 av_log(logctx, AV_LOG_ERROR, "num_sps_ids_minus1 %d invalid\n", num_sps_ids_minus1);
109 return AVERROR_INVALIDDATA;
110 }
111
112 active_seq_parameter_set_id = get_ue_golomb_long(gb);
113 if (active_seq_parameter_set_id >= HEVC_MAX_SPS_COUNT) {
114 av_log(logctx, AV_LOG_ERROR, "active_parameter_set_id %d invalid\n", active_seq_parameter_set_id);
115 return AVERROR_INVALIDDATA;
116 }
117 s->active_seq_parameter_set_id = active_seq_parameter_set_id;
118
119 return 0;
120}
121
123{
124 s->num_clock_ts = get_bits(gb, 2);
125
126 for (int i = 0; i < s->num_clock_ts; i++) {
127 s->clock_timestamp_flag[i] = get_bits(gb, 1);
128
129 if (s->clock_timestamp_flag[i]) {
130 s->units_field_based_flag[i] = get_bits(gb, 1);
131 s->counting_type[i] = get_bits(gb, 5);
132 s->full_timestamp_flag[i] = get_bits(gb, 1);
133 s->discontinuity_flag[i] = get_bits(gb, 1);
134 s->cnt_dropped_flag[i] = get_bits(gb, 1);
135
136 s->n_frames[i] = get_bits(gb, 9);
137
138 if (s->full_timestamp_flag[i]) {
139 s->seconds_value[i] = av_clip(get_bits(gb, 6), 0, 59);
140 s->minutes_value[i] = av_clip(get_bits(gb, 6), 0, 59);
141 s->hours_value[i] = av_clip(get_bits(gb, 5), 0, 23);
142 } else {
143 s->seconds_flag[i] = get_bits(gb, 1);
144 if (s->seconds_flag[i]) {
145 s->seconds_value[i] = av_clip(get_bits(gb, 6), 0, 59);
146 s->minutes_flag[i] = get_bits(gb, 1);
147 if (s->minutes_flag[i]) {
148 s->minutes_value[i] = av_clip(get_bits(gb, 6), 0, 59);
149 s->hours_flag[i] = get_bits(gb, 1);
150 if (s->hours_flag[i]) {
151 s->hours_value[i] = av_clip(get_bits(gb, 5), 0, 23);
152 }
153 }
154 }
155 }
156
157 s->time_offset_length[i] = get_bits(gb, 5);
158 if (s->time_offset_length[i] > 0) {
159 s->time_offset_value[i] = get_bits_long(gb, s->time_offset_length[i]);
160 }
161 }
162 }
163
164 s->present = 1;
165 return 0;
166}
167
169{
170 unsigned num_ref_displays;
171
172 s->prec_ref_display_width = get_ue_golomb(gb);
173 if (s->prec_ref_display_width > 31)
174 return AVERROR_INVALIDDATA;
175 s->ref_viewing_distance_flag = get_bits1(gb);
176 if (s->ref_viewing_distance_flag) {
177 s->prec_ref_viewing_dist = get_ue_golomb(gb);
178 if (s->prec_ref_viewing_dist > 31)
179 return AVERROR_INVALIDDATA;
180 }
181 num_ref_displays = get_ue_golomb(gb);
182 if (num_ref_displays > 31)
183 return AVERROR_INVALIDDATA;
184 s->num_ref_displays = num_ref_displays + 1;
185
186 for (int i = 0; i < s->num_ref_displays; i++) {
187 int length;
188 s->left_view_id[i] = get_ue_golomb(gb);
189 s->right_view_id[i] = get_ue_golomb(gb);
190 s->exponent_ref_display_width[i] = get_bits(gb, 6);
191 if (s->exponent_ref_display_width[i] > 62)
192 return AVERROR_INVALIDDATA;
193 else if (!s->exponent_ref_display_width[i])
194 length = FFMAX(0, (int)s->prec_ref_display_width - 30);
195 else
196 length = FFMAX(0, (int)s->exponent_ref_display_width[i] +
197 (int)s->prec_ref_display_width - 31);
198 s->mantissa_ref_display_width[i] = get_bits64(gb, length);
199 if (s->ref_viewing_distance_flag) {
200 s->exponent_ref_viewing_distance[i] = get_bits(gb, 6);
201 if (s->exponent_ref_viewing_distance[i] > 62)
202 return AVERROR_INVALIDDATA;
203 else if (!s->exponent_ref_viewing_distance[i])
204 length = FFMAX(0, (int)s->prec_ref_viewing_dist - 30);
205 else
206 length = FFMAX(0, (int)s->exponent_ref_viewing_distance[i] +
207 (int)s->prec_ref_viewing_dist - 31);
208 s->mantissa_ref_viewing_distance[i] = get_bits64(gb, length);
209 }
210 s->additional_shift_present_flag[i] = get_bits1(gb);
211 if (s->additional_shift_present_flag[i]) {
212 s->num_sample_shift[i] = get_bits(gb, 10);
213 if (s->num_sample_shift[i] > 1023)
214 return AVERROR_INVALIDDATA;
215 s->num_sample_shift[i] -= 512;
216 }
217 }
218 s->three_dimensional_reference_displays_extension_flag = get_bits1(gb);
219
220 s->present = 1;
221
222 return 0;
223}
224
226 void *logctx, HEVCSEI *s,
227 const HEVCParamSets *ps, int type)
228{
229 switch (type) {
230 case 256: // Mismatched value from HM 8.1
231 return decode_nal_sei_decoded_picture_hash(&s->picture_hash, gbyte);
233 return decode_nal_sei_pic_timing(s, gb, ps, logctx);
237 return decode_nal_sei_active_parameter_sets(s, gb, logctx);
239 return decode_nal_sei_timecode(&s->timecode, gb);
242 default: {
244 gb, gbyte, logctx);
246 av_log(logctx, AV_LOG_DEBUG, "Skipped PREFIX SEI %d\n", type);
247 return ret;
248 }
249 }
250}
251
253 void *logctx, HEVCSEI *s, int type)
254{
255 switch (type) {
257 return decode_nal_sei_decoded_picture_hash(&s->picture_hash, gbyte);
258 default:
259 av_log(logctx, AV_LOG_DEBUG, "Skipped SUFFIX SEI %d\n", type);
260 return 0;
261 }
262}
263
264static int decode_nal_sei_message(GetByteContext *gb, void *logctx, HEVCSEI *s,
265 const HEVCParamSets *ps, int nal_unit_type)
266{
267 GetByteContext message_gbyte;
268 GetBitContext message_gb;
269 int payload_type = 0;
270 int payload_size = 0;
271 int byte = 0xFF;
272 av_unused int ret;
273 av_log(logctx, AV_LOG_DEBUG, "Decoding SEI\n");
274
275 while (byte == 0xFF) {
276 if (bytestream2_get_bytes_left(gb) < 2 || payload_type > INT_MAX - 255)
277 return AVERROR_INVALIDDATA;
278 byte = bytestream2_get_byteu(gb);
279 payload_type += byte;
280 }
281 byte = 0xFF;
282 while (byte == 0xFF) {
283 if (bytestream2_get_bytes_left(gb) < 1 + payload_size)
284 return AVERROR_INVALIDDATA;
285 byte = bytestream2_get_byteu(gb);
286 payload_size += byte;
287 }
288 if (bytestream2_get_bytes_left(gb) < payload_size)
289 return AVERROR_INVALIDDATA;
290 bytestream2_init(&message_gbyte, gb->buffer, payload_size);
291 ret = init_get_bits8(&message_gb, gb->buffer, payload_size);
292 av_assert1(ret >= 0);
293 bytestream2_skipu(gb, payload_size);
294 if (nal_unit_type == HEVC_NAL_SEI_PREFIX) {
295 return decode_nal_sei_prefix(&message_gb, &message_gbyte,
296 logctx, s, ps, payload_type);
297 } else { /* nal_unit_type == NAL_SEI_SUFFIX */
298 return decode_nal_sei_suffix(&message_gb, &message_gbyte,
299 logctx, s, payload_type);
300 }
301}
302
304 const HEVCParamSets *ps, enum HEVCNALUnitType type)
305{
306 GetByteContext gbyte;
307 int ret;
308
309 av_assert1((get_bits_count(gb) % 8) == 0);
310 bytestream2_init(&gbyte, gb->buffer + get_bits_count(gb) / 8,
311 get_bits_left(gb) / 8);
312
313 do {
314 ret = decode_nal_sei_message(&gbyte, logctx, s, ps, type);
315 if (ret < 0)
316 return ret;
317 } while (bytestream2_get_bytes_left(&gbyte) > 0);
318 return 1;
319}
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
Definition avassert.h:58
static av_always_inline unsigned int bytestream2_get_buffer(GetByteContext *g, uint8_t *dst, unsigned int size)
Definition bytestream.h:267
static av_always_inline void bytestream2_skipu(GetByteContext *g, unsigned int size)
Definition bytestream.h:174
static av_always_inline int bytestream2_get_bytes_left(const GetByteContext *g)
Definition bytestream.h:158
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
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
Definition bytestream.h:137
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
static int FUNC sps(CodedBitstreamContext *ctx, RWContext *rw, H264RawSPS *current)
#define s(width, name)
Definition cbs_vp9.c:198
#define av_clip
Definition common.h:100
static unsigned int get_bits_long(GetBitContext *s, int n)
Read 0-32 bits.
Definition get_bits.h:424
static int get_bits_left(GetBitContext *gb)
Definition get_bits.h:688
static unsigned int get_bits1(GetBitContext *s)
Definition get_bits.h:391
static uint64_t get_bits64(GetBitContext *s, int n)
Read 0-64 bits.
Definition get_bits.h:456
static int init_get_bits8(GetBitContext *s, const uint8_t *buffer, int byte_size)
Initialize GetBitContext.
Definition get_bits.h:544
static int get_bits_count(const GetBitContext *s)
Definition get_bits.h:254
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition get_bits.h:337
exp golomb vlc stuff
static int get_se_golomb(GetBitContext *gb)
read signed exp golomb code.
Definition golomb.h:239
static int get_ue_golomb(GetBitContext *gb)
Read an unsigned Exp-Golomb code in the range 0 to 8190.
Definition golomb.h:53
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
@ AV_CODEC_ID_HEVC
Definition codec_id.h:223
@ AV_PICTURE_STRUCTURE_BOTTOM_FIELD
coded as bottom field
Definition avcodec.h:2613
@ AV_PICTURE_STRUCTURE_TOP_FIELD
coded as top field
Definition avcodec.h:2612
@ AV_PICTURE_STRUCTURE_UNKNOWN
unknown
Definition avcodec.h:2611
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition error.h:61
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition log.h:231
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
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:286
@ FF_H2645_SEI_MESSAGE_UNHANDLED
Definition h2645_sei.h:144
static int decode_nal_sei_decoded_picture_hash(HEVCSEIPictureHash *s, GetByteContext *gb)
Definition sei.c:30
static int decode_nal_sei_suffix(GetBitContext *gb, GetByteContext *gbyte, void *logctx, HEVCSEI *s, int type)
Definition sei.c:252
int ff_hevc_decode_nal_sei(GetBitContext *gb, void *logctx, HEVCSEI *s, const HEVCParamSets *ps, enum HEVCNALUnitType type)
Definition sei.c:303
static int decode_nal_sei_pic_timing(HEVCSEI *s, GetBitContext *gb, const HEVCParamSets *ps, void *logctx)
Definition sei.c:52
static int decode_nal_sei_prefix(GetBitContext *gb, GetByteContext *gbyte, void *logctx, HEVCSEI *s, const HEVCParamSets *ps, int type)
Definition sei.c:225
static int decode_nal_sei_timecode(HEVCSEITimeCode *s, GetBitContext *gb)
Definition sei.c:122
static int decode_nal_sei_message(GetByteContext *gb, void *logctx, HEVCSEI *s, const HEVCParamSets *ps, int nal_unit_type)
Definition sei.c:264
static int decode_nal_sei_3d_reference_displays_info(HEVCSEITDRDI *s, GetBitContext *gb)
Definition sei.c:168
static int decode_nal_sei_active_parameter_sets(HEVCSEI *s, GetBitContext *gb, void *logctx)
Definition sei.c:97
static int decode_nal_sei_recovery_point(HEVCSEI *s, GetBitContext *gb)
Definition sei.c:82
@ HEVC_SEI_PIC_STRUCT_FRAME_DOUBLING
Definition sei.h:36
@ HEVC_SEI_PIC_STRUCT_FRAME_TRIPLING
Definition sei.h:37
cl_device_type type
HEVCNALUnitType
Table 7-1 – NAL unit type codes and NAL unit type classes in T-REC-H.265-201802.
Definition hevc.h:28
@ HEVC_NAL_SEI_PREFIX
Definition hevc.h:68
@ HEVC_MAX_SPS_COUNT
Definition hevc.h:115
#define av_unused
Definition attributes.h:164
#define FFMAX(a, b)
Definition macros.h:47
@ SEI_TYPE_DECODED_PICTURE_HASH
Definition sei.h:91
@ SEI_TYPE_RECOVERY_POINT
Definition sei.h:36
@ SEI_TYPE_PIC_TIMING
Definition sei.h:31
@ SEI_TYPE_ACTIVE_PARAMETER_SETS
Definition sei.h:87
@ SEI_TYPE_THREE_DIMENSIONAL_REFERENCE_DISPLAYS_INFO
Definition sei.h:127
@ SEI_TYPE_TIME_CODE
Definition sei.h:95
const uint8_t * buffer
Definition get_bits.h:110
const uint8_t * buffer
Definition bytestream.h:34
const HEVCSPS * sps_list[HEVC_MAX_SPS_COUNT]
RefStruct references.
Definition ps.h:510
uint8_t has_recovery_poc
Definition sei.h:103
uint8_t broken_link_flag
Definition sei.h:102
int16_t recovery_poc_cnt
Definition sei.h:100
uint8_t exact_match_flag
Definition sei.h:101
Definition sei.h:106
Definition ps.h:252
#define av_log(a,...)