FFmpeg
sei.c
Go to the documentation of this file.
1 /*
2  * VVC Supplementary Enhancement Information messages
3  *
4  * copyright (c) 2024 Wu Jianhua <toqsxw@outlook.com>
5  *
6  * This file is part of FFmpeg.
7  *
8  * FFmpeg is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * FFmpeg is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with FFmpeg; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22 
23 #include "sei.h"
24 #include "dec.h"
25 #include "libavcodec/bytestream.h"
26 #include "libavutil/refstruct.h"
27 
29 {
30  const VVCSPS *sps = fc->ps.sps;
31 
32  h->present = !s->fg_characteristics_cancel_flag;
33  if (h->present) {
34  h->model_id = s->fg_model_id;
35  h->separate_colour_description_present_flag = s->fg_separate_colour_description_present_flag;
36  if (h->separate_colour_description_present_flag) {
37  h->bit_depth_luma = s->fg_bit_depth_luma_minus8 + 8;
38  h->bit_depth_chroma = s->fg_bit_depth_chroma_minus8 + 8;
39  h->full_range = s->fg_full_range_flag;
40  h->color_primaries = s->fg_colour_primaries;
41  h->transfer_characteristics = s->fg_transfer_characteristics;
42  h->matrix_coeffs = s->fg_matrix_coeffs;
43  } else {
44  if (!sps) {
45  av_log(fc->log_ctx, AV_LOG_ERROR,
46  "No active SPS for film_grain_characteristics.\n");
47  return AVERROR_INVALIDDATA;
48  }
49  h->bit_depth_luma = sps->bit_depth;
50  h->bit_depth_chroma = sps->bit_depth;
51  h->full_range = sps->r->vui.vui_full_range_flag;
52  h->color_primaries = sps->r->vui.vui_colour_primaries;
53  h->transfer_characteristics = sps->r->vui.vui_transfer_characteristics;
54  h->matrix_coeffs = sps->r->vui.vui_matrix_coeffs ;
55  }
56 
57  h->blending_mode_id = s->fg_blending_mode_id;
58  h->log2_scale_factor = s->fg_log2_scale_factor;
59 
60  for (int c = 0; c < 3; c++) {
61  h->comp_model_present_flag[c] = s->fg_comp_model_present_flag[c];
62  if (h->comp_model_present_flag[c]) {
63  h->num_intensity_intervals[c] = s->fg_num_intensity_intervals_minus1[c] + 1;
64  h->num_model_values[c] = s->fg_num_model_values_minus1[c] + 1;
65 
66  if (h->num_model_values[c] > 6)
67  return AVERROR_INVALIDDATA;
68 
69  for (int i = 0; i < h->num_intensity_intervals[c]; i++) {
70  h->intensity_interval_lower_bound[c][i] = s->fg_intensity_interval_lower_bound[c][i];
71  h->intensity_interval_upper_bound[c][i] = s->fg_intensity_interval_upper_bound[c][i];
72  for (int j = 0; j < h->num_model_values[c]; j++)
73  h->comp_model_value[c][i][j] = s->fg_comp_model_value[c][i][j];
74  }
75  }
76  }
77 
78  h->persistence_flag = s->fg_characteristics_persistence_flag;
79  }
80 
81  return 0;
82 }
83 
85 {
86  h->present = 1;
87  h->hash_type = s->dph_sei_hash_type;
88  if (h->hash_type == 0)
89  memcpy(h->md5, s->dph_sei_picture_md5, sizeof(h->md5));
90  else if (h->hash_type == 1)
91  memcpy(h->crc, s->dph_sei_picture_crc, sizeof(h->crc));
92  else if (h->hash_type == 2)
93  memcpy(h->checksum, s->dph_sei_picture_checksum, sizeof(h->checksum));
94 
95  return 0;
96 }
97 
99 {
100  int degrees[] = { 0, 0x8000, 0x4000, 0xC000 };
101 
102  h->present = !s->display_orientation_cancel_flag;
103  if (h->present) {
104  if (s->display_orientation_transform_type > 7)
105  return AVERROR_INVALIDDATA;
106 
107  h->vflip = 0;
108  if (s->display_orientation_transform_type == 1 ||
109  s->display_orientation_transform_type == 3 ||
110  s->display_orientation_transform_type == 4 ||
111  s->display_orientation_transform_type == 6) {
112  h->hflip = 1;
113  } else {
114  h->hflip = 0;
115  }
116  h->anticlockwise_rotation = degrees[s->display_orientation_transform_type >> 1];
117  }
118 
119  return 0;
120 }
121 
123 {
124  h->present = 1;
125  h->max_content_light_level = s->max_content_light_level;
126  h->max_pic_average_light_level = s->max_pic_average_light_level;
127 
128  return 0;
129 }
130 
132 {
133  if (s->ffi_source_scan_type > 3)
134  return AVERROR_INVALIDDATA;
135 
136  h->present = 1;
137  if (s->ffi_field_pic_flag) {
138  if (s->ffi_bottom_field_flag)
139  h->picture_struct = AV_PICTURE_STRUCTURE_BOTTOM_FIELD;
140  else
141  h->picture_struct = AV_PICTURE_STRUCTURE_TOP_FIELD;
142  } else {
143  h->display_elemental_periods = s->ffi_display_elemental_periods_minus1 + 1;
144  }
145 
146  h->source_scan_type = s->ffi_source_scan_type;
147  h->duplicate_flag = s->ffi_duplicate_flag;
148 
149  return 0;
150 }
151 
153 {
154  h->present = 1;
155  h->ambient_illuminance = s->ambient_illuminance;
156  h->ambient_light_x = s->ambient_light_x;
157  h->ambient_light_y = s->ambient_light_y;
158 
159  return 0;
160 }
161 
163 {
164  h->present = 1;
165 
166  for (int c = 0; c < 3; c++) {
167  h->display_primaries[c][0] = s->display_primaries_x[c];
168  h->display_primaries[c][1] = s->display_primaries_y[c];
169  }
170 
171  h->white_point[0] = s->white_point_x;
172  h->white_point[1] = s->white_point_y;
173 
174  h->max_luminance = s->max_display_mastering_luminance;
175  h->min_luminance = s->min_display_mastering_luminance;
176 
177  return 0;
178 }
179 
181  const VVCFrameContext *fc)
182 {
183  GetByteContext gbc;
184  int offset = (s->itu_t_t35_country_code == 0xff) + 1;
185 
186  bytestream2_init(&gbc, s->data_ref, s->data_length + offset);
188  AV_CODEC_ID_VVC, NULL, &gbc, fc->log_ctx);
189 }
190 
192  const VVCFrameContext *fc)
193 {
194  GetByteContext gbc;
195 
196  bytestream2_init(&gbc, s->data_ref, s->data_length + 16);
198  AV_CODEC_ID_VVC, NULL, &gbc, fc->log_ctx);
199 }
200 
202 {
203  H2645SEI *c = &s->common;
204 
205  if (!sei)
206  return AVERROR_INVALIDDATA;
207 
208  for (int i = 0; i < sei->message_list.nb_messages; i++) {
209  int ret = 0;
210  SEIRawMessage *message = &sei->message_list.messages[i];
211  void *payload = message->payload;
212 
213  switch (message->payload_type) {
215  av_refstruct_unref(&c->film_grain_characteristics);
216  c->film_grain_characteristics = av_refstruct_allocz(sizeof(*c->film_grain_characteristics));
217  if (!c->film_grain_characteristics)
218  return AVERROR(ENOMEM);
219  ret = decode_film_grain_characteristics(c->film_grain_characteristics, payload, fc);
220  break;
221 
223  ret = decode_decoded_picture_hash(&s->picture_hash, payload);
224  break;
225 
227  ret = decode_display_orientation(&s->common.display_orientation, payload);
228  break;
229 
231  ret = decode_content_light_level_info(&s->common.content_light, payload);
232  break;
233 
235  ret = decode_frame_field_info(&s->frame_field_info, payload);
236  break;
237 
239  ret = decode_ambient_viewing_environment(&s->common.ambient_viewing_environment, payload);
240  break;
241 
243  ret = decode_mastering_display_colour_volume(&s->common.mastering_display, payload);
244  break;
245 
247  ret = decode_user_data_registered_itu_t_t35(&s->common, payload, fc);
248  break;
249 
251  ret = decode_user_data_uregistered(&s->common, payload, fc);
252  break;
253 
254  default:
255  av_log(fc->log_ctx, AV_LOG_DEBUG, "Skipped %s SEI %d\n",
256  sei->nal_unit_header.nal_unit_type == VVC_PREFIX_SEI_NUT ?
257  "PREFIX" : "SUFFIX", message->payload_type);
259  }
260 
261  if (ret == AVERROR(ENOMEM))
262  return ret;
263  if (ret < 0)
264  av_log(fc->log_ctx, AV_LOG_WARNING, "Failure to parse %s SEI %d: %s\n",
265  sei->nal_unit_header.nal_unit_type == VVC_PREFIX_SEI_NUT ?
266  "PREFIX" : "SUFFIX", message->payload_type, av_err2str(ret));
267  }
268 
269  return 0;
270 }
271 
273 {
274  dst->picture_hash.present = 0; // drop hash
275  dst->frame_field_info.present = 0; // drop field info
276  return ff_h2645_sei_ctx_replace(&dst->common, &src->common);
277 }
278 
280 {
281  ff_h2645_sei_reset(&s->common);
282  s->picture_hash.present = 0;
283  s->frame_field_info.present = 0;
284 }
VVCSPS
Definition: ps.h:58
decode_user_data_registered_itu_t_t35
static int decode_user_data_registered_itu_t_t35(H2645SEI *sei, const SEIRawUserDataRegistered *s, const VVCFrameContext *fc)
Definition: sei.c:180
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:216
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
SEIRawUserDataRegistered
Definition: cbs_sei.h:33
H274SEIPictureHash
Definition: h274.h:58
SEIRawAmbientViewingEnvironment
Definition: cbs_sei.h:96
ff_vvc_sei_reset
void ff_vvc_sei_reset(VVCSEI *s)
Definition: sei.c:279
message
Definition: api-threadmessage-test.c:47
GetByteContext
Definition: bytestream.h:33
SEIRawFrameFieldInformation
Definition: cbs_sei.h:130
sei.h
SEIRawMessage
Definition: cbs_sei.h:142
H2645SEIMasteringDisplay
Definition: h2645_sei.h:114
decode_decoded_picture_hash
static int decode_decoded_picture_hash(H274SEIPictureHash *h, const SEIRawDecodedPictureHash *s)
Definition: sei.c:84
H2645SEIDisplayOrientation
Definition: h2645_sei.h:74
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:470
SEIRawContentLightLevelInfo
Definition: cbs_sei.h:87
SEIRawUserDataUnregistered
Definition: cbs_sei.h:41
SEI_TYPE_AMBIENT_VIEWING_ENVIRONMENT
@ SEI_TYPE_AMBIENT_VIEWING_ENVIRONMENT
Definition: sei.h:107
decode_film_grain_characteristics
static int decode_film_grain_characteristics(H2645SEIFilmGrainCharacteristics *h, const SEIRawFilmGrainCharacteristics *s, const VVCFrameContext *fc)
Definition: sei.c:28
refstruct.h
av_refstruct_allocz
static void * av_refstruct_allocz(size_t size)
Equivalent to av_refstruct_alloc_ext(size, 0, NULL, NULL)
Definition: refstruct.h:105
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:210
H266RawSEI
Definition: cbs_h266.h:858
s
#define s(width, name)
Definition: cbs_vp9.c:198
fc
#define fc(width, name, range_min, range_max)
Definition: cbs_av1.c:494
H2645SEIAmbientViewingEnvironment
Definition: h2645_sei.h:85
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:231
SEI_TYPE_USER_DATA_REGISTERED_ITU_T_T35
@ SEI_TYPE_USER_DATA_REGISTERED_ITU_T_T35
Definition: sei.h:34
decode_ambient_viewing_environment
static int decode_ambient_viewing_environment(H2645SEIAmbientViewingEnvironment *h, const SEIRawAmbientViewingEnvironment *s)
Definition: sei.c:152
AV_PICTURE_STRUCTURE_BOTTOM_FIELD
@ AV_PICTURE_STRUCTURE_BOTTOM_FIELD
coded as bottom field
Definition: avcodec.h:2585
NULL
#define NULL
Definition: coverity.c:32
FF_H2645_SEI_MESSAGE_UNHANDLED
@ FF_H2645_SEI_MESSAGE_UNHANDLED
Definition: h2645_sei.h:149
AV_PICTURE_STRUCTURE_TOP_FIELD
@ AV_PICTURE_STRUCTURE_TOP_FIELD
coded as top field
Definition: avcodec.h:2584
SEIRawMasteringDisplayColourVolume
Definition: cbs_sei.h:78
VVC_PREFIX_SEI_NUT
@ VVC_PREFIX_SEI_NUT
Definition: vvc.h:52
H2645SEI
Definition: h2645_sei.h:128
decode_content_light_level_info
static int decode_content_light_level_info(H2645SEIContentLight *h, const SEIRawContentLightLevelInfo *s)
Definition: sei.c:122
sei
static int FUNC() sei(CodedBitstreamContext *ctx, RWContext *rw, H264RawSEI *current)
Definition: cbs_h264_syntax_template.c:858
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
VVCSEI
Definition: sei.h:36
dst
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition: dsp.h:87
av_err2str
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition: error.h:122
decode_user_data_uregistered
static int decode_user_data_uregistered(H2645SEI *sei, const SEIRawUserDataUnregistered *s, const VVCFrameContext *fc)
Definition: sei.c:191
SEI_TYPE_MASTERING_DISPLAY_COLOUR_VOLUME
@ SEI_TYPE_MASTERING_DISPLAY_COLOUR_VOLUME
Definition: sei.h:96
ff_h2645_sei_reset
void ff_h2645_sei_reset(H2645SEI *s)
Definition: h2645_sei.c:902
AV_CODEC_ID_VVC
@ AV_CODEC_ID_VVC
Definition: codec_id.h:252
offset
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 offset
Definition: writing_filters.txt:86
av_refstruct_unref
void av_refstruct_unref(void *objp)
Decrement the reference count of the underlying object and automatically free the object if there are...
Definition: refstruct.c:120
ff_vvc_sei_decode
int ff_vvc_sei_decode(VVCSEI *s, const H266RawSEI *sei, const struct VVCFrameContext *fc)
Definition: sei.c:201
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
decode_mastering_display_colour_volume
static int decode_mastering_display_colour_volume(H2645SEIMasteringDisplay *h, const SEIRawMasteringDisplayColourVolume *s)
Definition: sei.c:162
SEI_TYPE_DISPLAY_ORIENTATION
@ SEI_TYPE_DISPLAY_ORIENTATION
Definition: sei.h:77
ret
ret
Definition: filter_design.txt:187
ff_vvc_sei_replace
int ff_vvc_sei_replace(VVCSEI *dst, const VVCSEI *src)
Definition: sei.c:272
sps
static int FUNC() sps(CodedBitstreamContext *ctx, RWContext *rw, H264RawSPS *current)
Definition: cbs_h264_syntax_template.c:260
SEI_TYPE_USER_DATA_UNREGISTERED
@ SEI_TYPE_USER_DATA_UNREGISTERED
Definition: sei.h:35
H274SEIFrameFieldInfo
Definition: h274.h:73
SEIRawDisplayOrientation
Definition: cbs_sei.h:123
SEIRawDecodedPictureHash
Definition: cbs_sei.h:68
decode_display_orientation
static int decode_display_orientation(H2645SEIDisplayOrientation *h, const SEIRawDisplayOrientation *s)
Definition: sei.c:98
SEI_TYPE_DECODED_PICTURE_HASH
@ SEI_TYPE_DECODED_PICTURE_HASH
Definition: sei.h:91
ff_h2645_sei_ctx_replace
int ff_h2645_sei_ctx_replace(H2645SEI *dst, const H2645SEI *src)
Definition: h2645_sei.c:504
decode_frame_field_info
static int decode_frame_field_info(H274SEIFrameFieldInfo *h, const SEIRawFrameFieldInformation *s)
Definition: sei.c:131
VVCFrameContext
Definition: dec.h:122
bytestream.h
bytestream2_init
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
Definition: bytestream.h:137
H2645SEIContentLight
Definition: h2645_sei.h:122
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
SEI_TYPE_FRAME_FIELD_INFO
@ SEI_TYPE_FRAME_FIELD_INFO
Definition: sei.h:126
SEI_TYPE_CONTENT_LIGHT_LEVEL_INFO
@ SEI_TYPE_CONTENT_LIGHT_LEVEL_INFO
Definition: sei.h:103
h
h
Definition: vp9dsp_template.c:2070
SEIRawFilmGrainCharacteristics
Definition: cbs_sei.h:102
SEI_TYPE_FILM_GRAIN_CHARACTERISTICS
@ SEI_TYPE_FILM_GRAIN_CHARACTERISTICS
Definition: sei.h:49
src
#define src
Definition: vp8dsp.c:248
dec.h
H2645SEIFilmGrainCharacteristics
Definition: h2645_sei.h:92