FFmpeg
Loading...
Searching...
No Matches
itut35.c
Go to the documentation of this file.
1/*
2 * This file is part of FFmpeg.
3 *
4 * FFmpeg is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * FFmpeg is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with FFmpeg; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19#include "libavutil/buffer.h"
20#include "libavutil/frame.h"
22#include "libavutil/internal.h"
23#include "libavutil/mem.h"
24
25#include "avcodec.h"
26#include "atsc_a53.h"
27#include "bytestream.h"
28#include "decode.h"
29#include "dynamic_hdr_vivid.h"
30#include "dovi_rpu.h"
31#include "itut35.h"
32#include "version.h"
33
34int ff_itut_t35_parse_buffer(FFITUTT35 *const itut_t35, const uint8_t *buf,
35 size_t buf_size, int flags) {
37 int provider_code, country_code;
38 unsigned int provider_oriented_code = 0;
39
40 bytestream2_init(&gb, buf, buf_size);
41
43 country_code = itut_t35->country_code;
44 else {
45 country_code = bytestream2_get_byte(&gb);
46 if (country_code == 0xFF) {
47 if (bytestream2_get_bytes_left(&gb) < 1)
49
50 bytestream2_skipu(&gb, 1); // itu_t_t35_country_code_extension_byte
51 }
52 }
53
54 switch (country_code) {
56 if (bytestream2_get_bytes_left(&gb) < 2)
58 provider_code = bytestream2_get_be16u(&gb);
59
60 switch (provider_code) {
62 if (bytestream2_get_bytes_left(&gb) < 4)
64 provider_oriented_code = bytestream2_get_be32u(&gb);
65 switch (provider_oriented_code) {
66 case MKBETAG('D', 'T', 'G', '1'): // afd_data
67 if (bytestream2_get_bytes_left(&gb) < 2)
69 if (!(bytestream2_get_byteu(&gb) & 0x40)) // active_format_flag
70 return 0; //ignore
71 break;
72 case MKBETAG('G', 'A', '9', '4'): // closed captions
73 break;
74 default: // ignore unsupported identifiers
75 return 0;
76 }
77 break;
79 if (bytestream2_get_bytes_left(&gb) < 1)
81
82 provider_oriented_code = bytestream2_get_byteu(&gb);
83 if (provider_oriented_code != 0x0001)
84 return 0; // ignore
85 break;
87 if (bytestream2_get_bytes_left(&gb) < 3)
89 provider_oriented_code = bytestream2_get_be16u(&gb);
90 int application_identifier = bytestream2_get_byteu(&gb);
91
92 if (provider_oriented_code != 1 || application_identifier != 4)
93 return 0; // ignore
94 break;
96 if (bytestream2_get_bytes_left(&gb) < 4)
98 provider_oriented_code = bytestream2_get_be32u(&gb);
99 if (provider_oriented_code != 0x800)
100 return 0; // ignore
101 break;
103 if (bytestream2_get_bytes_left(&gb) < 2)
104 return AVERROR_INVALIDDATA;
105 provider_oriented_code = bytestream2_get_be16u(&gb);
106 if (provider_oriented_code != 1)
107 return 0; // ignore
108 break;
109 default: // ignore unsupported provider codes
110 return 0;
111 }
112 break;
114 if (bytestream2_get_bytes_left(&gb) < 3)
115 return AVERROR_INVALIDDATA;
116
117 bytestream2_skipu(&gb, 1); // t35_uk_country_code_second_octet
118 provider_code = bytestream2_get_be16u(&gb);
119
120 switch (provider_code) {
122 break;
123 default: // ignore unsupported provider codes
124 return 0;
125 }
126 break;
128 if (bytestream2_get_bytes_left(&gb) < 2)
129 return AVERROR_INVALIDDATA;
130 provider_code = bytestream2_get_be16u(&gb);
131
132 switch (provider_code) {
134 if (bytestream2_get_bytes_left(&gb) < 2)
135 return AVERROR_INVALIDDATA;
136
137 provider_oriented_code = bytestream2_get_be16u(&gb);
138 if (provider_oriented_code != 0x0005)
139 return 0; //ignore
140 break;
141 default: // ignore unsupported provider codes
142 return 0;
143 }
144 break;
145
146 default: // ignore unsupported country codes
147 return 0;
148 }
149
151 return AVERROR_INVALIDDATA;
152
153 itut_t35->payload = gb.buffer;
155
156 itut_t35->country_code = country_code;
157 itut_t35->provider_code = provider_code;
158 itut_t35->provider_oriented_code = provider_oriented_code;
159
160 return 1;
161}
162
164 FFITUTT35Meta *metadata, int err_recognition)
165{
166 int ret;
167
168 switch (itut_t35->country_code) {
170 switch (itut_t35->provider_code) {
173 ret = ff_aom_parse_film_grain_sets(&metadata->aom_film_grain,
174 itut_t35->payload, itut_t35->payload_size);
175 if (ret < 0)
176 return ret;
177 break;
179 switch (itut_t35->provider_oriented_code) {
180 case MKBETAG('D', 'T', 'G', '1'): // afd_data
182 metadata->afd = av_buffer_alloc(1);
183 if (!metadata->afd)
184 return AVERROR(ENOMEM);
185
186 *metadata->afd->data = *itut_t35->payload & 0xf;
187
188 break;
189 case MKBETAG('G', 'A', '9', '4'): // closed captions
190 ret = ff_parse_a53_cc(&metadata->a53_cc, itut_t35->payload, itut_t35->payload_size);
191 if (ret < 0)
192 return ret;
193
194 break;
195 default: // ignore unsupported identifiers
196 break;
197 }
198 break;
200 size_t size;
202 if (!hdr_plus)
203 return AVERROR(ENOMEM);
204
205 ret = av_dynamic_hdr_plus_from_t35(hdr_plus, itut_t35->payload,
206 itut_t35->payload_size);
207 if (ret < 0) {
208 av_free(hdr_plus);
209 return ret;
210 }
211
212 av_buffer_unref(&metadata->hdr_plus);
213 metadata->hdr_plus = av_buffer_create((uint8_t *)hdr_plus, size, NULL, NULL, 0);
214 if (!metadata->hdr_plus) {
215 av_free(hdr_plus);
216 return AVERROR(ENOMEM);
217 }
218
219 break;
220 }
222 AVDOVIMetadata *dovi;
223
224 if (!aux || !aux->dovi)
225 return 0; // ignore
226
227 ret = ff_dovi_rpu_parse(aux->dovi, itut_t35->payload, itut_t35->payload_size,
228 err_recognition);
229 if (ret < 0)
230 return 0; // ignore
231
232 ret = ff_dovi_get_metadata(aux->dovi, &dovi);
233 if (ret <= 0)
234 return ret;
235
237 metadata->dovi = av_buffer_create((uint8_t *)dovi, ret, NULL, NULL, 0);
238 if (!metadata->dovi) {
239 av_free(dovi);
240 return AVERROR(ENOMEM);
241 }
242
243 break;
244 }
246 size_t size;
248 if (!hdr_smpte2094_app5)
249 return AVERROR(ENOMEM);
250
251 ret = av_dynamic_hdr_smpte2094_app5_from_t35(hdr_smpte2094_app5, itut_t35->payload,
252 itut_t35->payload_size);
253 if (ret < 0) {
254 av_free(hdr_smpte2094_app5);
255 return ret;
256 }
257
258 av_buffer_unref(&metadata->hdr_smpte2094_app5);
259 metadata->hdr_smpte2094_app5 = av_buffer_create((uint8_t *)hdr_smpte2094_app5, size, NULL, NULL, 0);
260 if (!metadata->hdr_smpte2094_app5) {
261 av_free(hdr_smpte2094_app5);
262 return AVERROR(ENOMEM);
263 }
264
265 break;
266 }
267 default:
268 break;
269 }
270 break;
272 switch (itut_t35->provider_code) {
274 av_buffer_unref(&metadata->lcevc);
275 metadata->lcevc = av_buffer_alloc(itut_t35->payload_size);
276 if (!metadata->lcevc)
277 return AVERROR(ENOMEM);
278
279 memcpy(metadata->lcevc->data, itut_t35->payload, itut_t35->payload_size);
280
281 break;
282 default:
283 break;
284 }
285 break;
287 switch (itut_t35->provider_code) {
289 size_t size;
291 if (!hdr_vivid)
292 return AVERROR(ENOMEM);
293
294 ret = ff_parse_itu_t_t35_to_dynamic_hdr_vivid(hdr_vivid, itut_t35->payload,
295 itut_t35->payload_size);
296 if (ret < 0) {
297 av_free(hdr_vivid);
298 return ret;
299 }
300
301 av_buffer_unref(&metadata->hdr_vivid);
302 metadata->hdr_vivid = av_buffer_create((uint8_t *)hdr_vivid, size, NULL, NULL, 0);
303 if (!metadata->hdr_vivid) {
304 av_free(hdr_vivid);
305 return AVERROR(ENOMEM);
306 }
307 break;
308 }
309 default:
310 break;
311 }
312 break;
313
314 default:
315 // ignore unsupported provider codes
316 break;
317 }
318
319 return 0;
320}
321
323 AVCodecContext *const avctx, AVFrame *const frame)
324{
325 FFITUTT35Meta metadata = { 0 };
326 int ret;
327
328 ret = ff_itut_t35_parse_payload_to_struct(itut_t35, aux, &metadata, avctx->err_recognition);
329 if (ret < 0)
330 return ret;
331
332 if (metadata.afd) {
335 metadata.afd = NULL;
336 }
337
338 if (metadata.a53_cc) {
340 if (ret < 0)
341 return ret;
342 }
343
344 if (metadata.aom_film_grain.enable) {
345 ret = ff_aom_attach_film_grain_sets(&metadata.aom_film_grain, frame);
346 if (ret < 0)
347 return ret;
348 }
349
350 if (metadata.hdr_plus) {
352 &metadata.hdr_plus);
353 if (ret < 0)
354 return ret;
355 }
356
357 if (metadata.dovi) {
359 metadata.dovi);
360 if (!sd) {
362 return AVERROR(ENOMEM);
363 }
364 metadata.dovi = NULL;
365 }
366
367 if (metadata.hdr_smpte2094_app5) {
369 &metadata.hdr_smpte2094_app5);
370 if (ret < 0)
371 return ret;
372 }
373
374 if (metadata.lcevc) {
376 &metadata.lcevc);
377 if (ret < 0)
378 return ret;
379 }
380
381 if (metadata.hdr_vivid) {
383 &metadata.hdr_vivid);
384 if (ret < 0)
385 return ret;
386 }
387
389
390 return 0;
391}
392
394{
397 av_buffer_unref(&metadata->a53_cc);
398 av_buffer_unref(&metadata->hdr_plus);
399 av_buffer_unref(&metadata->hdr_smpte2094_app5);
400 av_buffer_unref(&metadata->lcevc);
402 av_buffer_unref(&metadata->hdr_vivid);
403}
void ff_aom_uninit_film_grain_params(AVFilmGrainAFGS1Params *s)
int ff_aom_parse_film_grain_sets(AVFilmGrainAFGS1Params *s, const uint8_t *payload, int payload_size)
int ff_aom_attach_film_grain_sets(const AVFilmGrainAFGS1Params *s, AVFrame *frame)
int ff_parse_a53_cc(AVBufferRef **pbuf, const uint8_t *data, int size)
Parse a data array for ATSC A53 Part 4 Closed Captions and store them in an AVBufferRef.
Definition atsc_a53.c:69
Libavcodec external API header.
refcounted data buffer API
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
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
Definition bytestream.h:137
static int FUNC metadata(CodedBitstreamContext *ctx, RWContext *rw, APVRawMetadata *current)
#define flags(name, subs,...)
Definition cbs_h264.c:74
#define NULL
Definition coverity.c:32
int ff_frame_new_side_data_from_buf(const AVCodecContext *avctx, AVFrame *frame, enum AVFrameSideDataType type, AVBufferRef **buf)
Similar to ff_frame_new_side_data, but using an existing buffer ref.
Definition decode.c:2222
static AVFrame * frame
int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, size_t rpu_size, int err_recognition)
Parse the contents of a Dolby Vision RPU and update the parsed values in the DOVIContext struct.
int ff_dovi_get_metadata(DOVIContext *s, AVDOVIMetadata **out_metadata)
Get the decoded AVDOVIMetadata.
Definition dovi_rpudec.c:33
int ff_parse_itu_t_t35_to_dynamic_hdr_vivid(AVDynamicHDRVivid *s, const uint8_t *data, int size)
Parse the user data registered ITU-T T.35 to AVbuffer (AVDynamicHDRVivid).
reference-counted frame API
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it.
Definition buffer.c:139
AVBufferRef * av_buffer_alloc(size_t size)
Allocate an AVBuffer of the given size using av_malloc().
Definition buffer.c:77
AVBufferRef * av_buffer_create(uint8_t *data, size_t size, void(*free)(void *opaque, uint8_t *data), void *opaque, int flags)
Create an AVBuffer from an existing array.
Definition buffer.c:55
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition error.h:61
#define AVERROR(e)
Definition error.h:45
AVFrameSideData * av_frame_new_side_data_from_buf(AVFrame *frame, enum AVFrameSideDataType type, AVBufferRef *buf)
Add a new side data to a frame from an existing AVBufferRef.
Definition frame.c:638
@ AV_FRAME_DATA_DOVI_METADATA
Parsed Dolby Vision metadata, suitable for passing to a software implementation.
Definition frame.h:208
@ AV_FRAME_DATA_LCEVC
Raw LCEVC payload data, as a uint8_t array, with NAL emulation bytes intact.
Definition frame.h:236
@ AV_FRAME_DATA_DYNAMIC_HDR_VIVID
HDR Vivid dynamic metadata associated with a video frame.
Definition frame.h:215
@ AV_FRAME_DATA_A53_CC
ATSC A53 Part 4 Closed Captions.
Definition frame.h:59
@ AV_FRAME_DATA_DYNAMIC_HDR_PLUS
HDR dynamic metadata associated with a video frame.
Definition frame.h:159
@ AV_FRAME_DATA_DYNAMIC_HDR_SMPTE_2094_APP5
HDR dynamic metadata associated with a video frame.
Definition frame.h:270
@ AV_FRAME_DATA_AFD
Active Format Description data consisting of a single byte as specified in ETSI TS 101 154 using AVAc...
Definition frame.h:90
AVDynamicHDRPlus * av_dynamic_hdr_plus_alloc(size_t *size)
Allocate an AVDynamicHDRPlus structure and set its fields to default values.
AVDynamicHDRSmpte2094App5 * av_dynamic_hdr_smpte2094_app5_alloc(size_t *size)
Allocate an AVDynamicHDRSmpte2094App5 structure and set its fields to default values.
int av_dynamic_hdr_plus_from_t35(AVDynamicHDRPlus *s, const uint8_t *data, size_t size)
Parse the user data registered ITU-T T.35 to AVbuffer (AVDynamicHDRPlus).
int av_dynamic_hdr_smpte2094_app5_from_t35(AVDynamicHDRSmpte2094App5 *s, const uint8_t *data, size_t size)
Parse the user data formatted as ITU-T T.35 message to AVDynamicHDRSmpte2094App5.
AVDynamicHDRVivid * av_dynamic_hdr_vivid_alloc(size_t *size)
Copyright (c) 2021 Limin Wang <lance.lmwang at gmail.com>
int ff_itut_t35_parse_payload_to_struct(FFITUTT35 *const itut_t35, FFITUTT35Aux *const aux, FFITUTT35Meta *metadata, int err_recognition)
Parse a pre-processed ITU-T T35 payload to fill the metadata struct.
Definition itut35.c:163
int ff_itut_t35_parse_buffer(FFITUTT35 *const itut_t35, const uint8_t *buf, size_t buf_size, int flags)
Parse a raw ITU-T T35 buffer to get the country code, provider code, and set them plus the pointer an...
Definition itut35.c:34
int ff_itut_t35_parse_payload_to_frame(FFITUTT35 *const itut_t35, FFITUTT35Aux *const aux, AVCodecContext *const avctx, AVFrame *const frame)
Parse a pre-processed ITU-T T35 payload to fill a frame's side data.
Definition itut35.c:322
void ff_itut_t35_unref(FFITUTT35Meta *metadata)
Unref all references in metadata.
Definition itut35.c:393
#define ITU_T_T35_PROVIDER_CODE_SMPTE
Definition itut35.h:48
#define FF_ITUT_T35_FLAG_COUNTRY_CODE
country_code is assumed to not be the first byte of the buffer and must be set by the caller beforeha...
Definition itut35.h:83
#define ITU_T_T35_PROVIDER_CODE_HDR_VIVID
Definition itut35.h:39
#define ITU_T_T35_PROVIDER_CODE_VNOVA
Definition itut35.h:42
#define ITU_T_T35_COUNTRY_CODE_CN
Definition itut35.h:30
#define ITU_T_T35_PROVIDER_CODE_DOLBY
Definition itut35.h:45
#define ITU_T_T35_COUNTRY_CODE_US
Definition itut35.h:32
#define ITU_T_T35_PROVIDER_CODE_AOM
Definition itut35.h:46
#define ITU_T_T35_COUNTRY_CODE_UK
Definition itut35.h:31
#define ITU_T_T35_PROVIDER_CODE_ATSC
Definition itut35.h:44
#define ITU_T_T35_PROVIDER_CODE_SAMSUNG
Definition itut35.h:47
Libavcodec version macros.
common internal API header
#define MKBETAG(a, b, c, d)
Definition macros.h:56
Memory handling functions.
main external API structure.
Definition avcodec.h:443
int err_recognition
Error recognition; may misdetect some more or less valid parts as errors.
Definition avcodec.h:1416
Combined struct representing a combination of header, mapping and color metadata, for attaching to fr...
Definition dovi_meta.h:345
This struct represents dynamic metadata for color volume transform - application 4 of SMPTE 2094-40:2...
This struct represents dynamic metadata for color volume transform as specified in the SMPTE 2094-50 ...
This struct represents dynamic metadata for color volume transform - CUVA 005.1:2021 standard.
Structure to hold side data for an AVFrame.
Definition frame.h:327
This structure describes decoded (raw) audio or video data.
Definition frame.h:472
DOVIContext * dovi
A DOVIContext.
Definition itut35.h:76
unsigned int provider_oriented_code
Definition itut35.h:54
const uint8_t * payload
Definition itut35.h:56
int country_code
Definition itut35.h:51
int provider_code
Definition itut35.h:53
size_t payload_size
Definition itut35.h:57
const uint8_t * buffer
Definition bytestream.h:34
#define av_free(p)
int size