FFmpeg
Loading...
Searching...
No Matches
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"
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");
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)
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}
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition dsp.h:87
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 sei(CodedBitstreamContext *ctx, RWContext *rw, H264RawSEI *current)
static int FUNC sps(CodedBitstreamContext *ctx, RWContext *rw, H264RawSPS *current)
#define s(width, name)
Definition cbs_vp9.c:198
#define NULL
Definition coverity.c:32
static const uint16_t fc[]
Definition dcaenc.h:43
@ AV_CODEC_ID_VVC
Definition codec_id.h:247
@ 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
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition error.h:61
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition error.h:122
#define AVERROR(e)
Definition error.h:45
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition log.h:231
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition log.h:216
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
void ff_h2645_sei_reset(H2645SEI *s)
Definition h2645_sei.c:703
int ff_h2645_sei_ctx_replace(H2645SEI *dst, const H2645SEI *src)
Definition h2645_sei.c:320
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
unsigned offset
Definition libaomenc.c:763
@ VVC_PREFIX_SEI_NUT
Definition vvc.h:52
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
static void * av_refstruct_allocz(size_t size)
Equivalent to av_refstruct_alloc_ext(size, 0, NULL, NULL)
Definition refstruct.h:105
@ SEI_TYPE_DECODED_PICTURE_HASH
Definition sei.h:91
@ SEI_TYPE_USER_DATA_REGISTERED_ITU_T_T35
Definition sei.h:34
@ SEI_TYPE_DISPLAY_ORIENTATION
Definition sei.h:77
@ SEI_TYPE_FRAME_FIELD_INFO
Definition sei.h:126
@ SEI_TYPE_USER_DATA_UNREGISTERED
Definition sei.h:35
@ SEI_TYPE_FILM_GRAIN_CHARACTERISTICS
Definition sei.h:49
@ SEI_TYPE_CONTENT_LIGHT_LEVEL_INFO
Definition sei.h:103
@ SEI_TYPE_AMBIENT_VIEWING_ENVIRONMENT
Definition sei.h:107
@ SEI_TYPE_MASTERING_DISPLAY_COLOUR_VOLUME
Definition sei.h:96
Definition sei.h:36
Definition ps.h:58
#define av_log(a,...)
#define src
Definition vp8dsp.c:248
static double c[64]
static int decode_ambient_viewing_environment(H2645SEIAmbientViewingEnvironment *h, const SEIRawAmbientViewingEnvironment *s)
Definition sei.c:152
static int decode_display_orientation(H2645SEIDisplayOrientation *h, const SEIRawDisplayOrientation *s)
Definition sei.c:98
static int decode_mastering_display_colour_volume(H2645SEIMasteringDisplay *h, const SEIRawMasteringDisplayColourVolume *s)
Definition sei.c:162
void ff_vvc_sei_reset(VVCSEI *s)
Definition sei.c:279
static int decode_user_data_registered_itu_t_t35(H2645SEI *sei, const SEIRawUserDataRegistered *s, const VVCFrameContext *fc)
Definition sei.c:180
static int decode_user_data_uregistered(H2645SEI *sei, const SEIRawUserDataUnregistered *s, const VVCFrameContext *fc)
Definition sei.c:191
int ff_vvc_sei_decode(VVCSEI *s, const H266RawSEI *sei, const struct VVCFrameContext *fc)
Definition sei.c:201
static int decode_content_light_level_info(H2645SEIContentLight *h, const SEIRawContentLightLevelInfo *s)
Definition sei.c:122
static int decode_frame_field_info(H274SEIFrameFieldInfo *h, const SEIRawFrameFieldInformation *s)
Definition sei.c:131
static int decode_film_grain_characteristics(H2645SEIFilmGrainCharacteristics *h, const SEIRawFilmGrainCharacteristics *s, const VVCFrameContext *fc)
Definition sei.c:28
static int decode_decoded_picture_hash(H274SEIPictureHash *h, const SEIRawDecodedPictureHash *s)
Definition sei.c:84
int ff_vvc_sei_replace(VVCSEI *dst, const VVCSEI *src)
Definition sei.c:272