FFmpeg
Loading...
Searching...
No Matches
cbs_apv_syntax_template.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
21{
22 int err;
23
24 ub(8, pbu_type);
25 ub(16, group_id);
26 u(8, reserved_zero_8bits, 0, 0);
27
28 return 0;
29}
30
32{
33 int err;
34
35 while (byte_alignment(rw) != 0)
36 fixed(1, alignment_bit_equal_to_zero, 0);
37
38 return 0;
39}
40
43{
44 int err;
45
46#ifdef READ
47 current->filler_size = 0;
48 while (show_bits(rw, 8) == 0xff) {
49 fixed(8, ff_byte, 0xff);
50 ++current->filler_size;
51 }
52#else
53 {
54 uint32_t i;
55 for (i = 0; i < current->filler_size; i++)
56 fixed(8, ff_byte, 0xff);
57 }
58#endif
59
60 return 0;
61}
62
65{
66 int err;
67
68 ub(8, profile_idc);
69 ub(8, level_idc);
70 ub(3, band_idc);
71
72 u(5, reserved_zero_5bits, 0, 0);
73
74 ub(24, frame_width);
75 ub(24, frame_height);
76
77 u(4, chroma_format_idc, 0, 4);
78 if (current->chroma_format_idc == 1) {
79 av_log(ctx->log_ctx, AV_LOG_ERROR,
80 "chroma_format_idc 1 for 4:2:0 is not allowed in APV.\n");
82 }
83
84 u(4, bit_depth_minus8, 2, 8);
85
86 ub(8, capture_time_distance);
87
88 u(8, reserved_zero_8bits, 0, 0);
89
90 return 0;
91}
92
94 RWContext *rw,
96{
97 const CodedBitstreamAPVContext *priv = ctx->priv_data;
98 int err;
99
100 for (int c = 0; c < priv->num_comp; c++) {
101 for (int y = 0; y < 8; y++) {
102 for (int x = 0; x < 8 ; x++) {
103 us(8, q_matrix[c][x][y], 1, 255, 3, c, x, y);
104 }
105 }
106 }
107
108 return 0;
109}
110
113 const APVRawFrameHeader *fh)
114{
115 CodedBitstreamAPVContext *priv = ctx->priv_data;
116 int frame_width_in_mbs = (fh->frame_info.frame_width + 15) / 16;
117 int frame_height_in_mbs = (fh->frame_info.frame_height + 15) / 16;
118 /* The spec also demands tile_width >= APV_MIN_TILE_WIDTH_IN_MBS (16)
119 * and tile_height >= APV_MIN_TILE_HEIGHT_IN_MBS (8); we deliberately
120 * accept smaller tiles (down to the 20x20 grid cap, which the fixed
121 * arrays rely on) so sub-minimum experimental streams keep working. */
122 uint32_t min_tile_width = (frame_width_in_mbs + APV_MAX_TILE_COLS - 1) /
124 uint32_t min_tile_height = (frame_height_in_mbs + APV_MAX_TILE_ROWS - 1) /
126 int err;
127
128 u(20, tile_width_in_mbs, min_tile_width, MAX_UINT_BITS(20));
129 u(20, tile_height_in_mbs, min_tile_height, MAX_UINT_BITS(20));
130
131 ub(1, tile_size_present_in_fh_flag);
132
134
135 if (current->tile_size_present_in_fh_flag) {
136 for (int t = 0; t < priv->num_tiles; t++) {
137 us(32, tile_size_in_fh[t], 10, MAX_UINT_BITS(32), 1, t);
138 }
139 }
140
141 return 0;
142}
143
146{
147 CodedBitstreamAPVContext *priv = ctx->priv_data;
148 int err;
149
150 CHECK(FUNC(frame_info)(ctx, rw, &current->frame_info));
151
152 u(8, reserved_zero_8bits, 0, 0);
153
154 ub(1, color_description_present_flag);
155 if (current->color_description_present_flag) {
158 ub(8, matrix_coefficients);
159 ub(1, full_range_flag);
160 } else {
163 infer(matrix_coefficients, 2);
164 infer(full_range_flag, 0);
165 }
166
167 priv->bit_depth = current->frame_info.bit_depth_minus8 + 8;
169
170 ub(1, use_q_matrix);
171 if (current->use_q_matrix) {
173 &current->quantization_matrix));
174 } else {
175 for (int c = 0; c < priv->num_comp; c++) {
176 for (int y = 0; y < 8; y++) {
177 for (int x = 0; x < 8 ; x++) {
178 infer(quantization_matrix.q_matrix[c][y][x], 16);
179 }
180 }
181 }
182 }
183
184 CHECK(FUNC(tile_info)(ctx, rw, &current->tile_info, current));
185
186 u(8, reserved_zero_8bits_2, 0, 0);
187
189
190 return 0;
191}
192
195 int tile_idx, uint32_t tile_size)
196{
197 const CodedBitstreamAPVContext *priv = ctx->priv_data;
198 uint16_t expected_tile_header_size;
199 uint32_t tile_size_remaining;
200 uint8_t max_qp;
201 int err;
202
203 expected_tile_header_size = 4 + priv->num_comp * (4 + 1) + 1;
204
205 u(16, tile_header_size,
206 expected_tile_header_size, expected_tile_header_size);
207
208 u(16, tile_index, tile_idx, tile_idx);
209
210 tile_size_remaining = tile_size - current->tile_header_size;
211 for (int c = 0; c < priv->num_comp; c++) {
212 us(32, tile_data_size[c], 1, tile_size_remaining, 1, c);
213 tile_size_remaining -= current->tile_data_size[c];
214 }
215
216 max_qp = 3 + priv->bit_depth * 6;
217 for (int c = 0; c < priv->num_comp; c++) {
218 us(8, tile_qp[c], 0, max_qp, 1, c);
219 }
220
221 u(8, reserved_zero_8bits, 0, 0);
222
223 return 0;
224}
225
228 int tile_idx, uint32_t tile_size)
229{
230 const CodedBitstreamAPVContext *priv = ctx->priv_data;
231 int err;
232
233 CHECK(FUNC(tile_header)(ctx, rw, &current->tile_header,
234 tile_idx, tile_size));
235
236 for (int c = 0; c < priv->num_comp; c++) {
237 uint32_t comp_size = current->tile_header.tile_data_size[c];
238#ifdef READ
239 int pos = get_bits_count(rw);
240 av_assert0(pos % 8 == 0);
241 if (get_bits_left(rw) < 8LL * comp_size)
242 return AVERROR_INVALIDDATA;
243 current->tile_data[c] = (uint8_t*)align_get_bits(rw);
244 skip_bits_long(rw, 8 * comp_size);
245#else
246 if (put_bytes_left(rw, 0) < comp_size)
247 return AVERROR(ENOSPC);
248 ff_copy_bits(rw, current->tile_data[c], comp_size * 8);
249#endif
250 }
251
252 return 0;
253}
254
257{
258 const CodedBitstreamAPVContext *priv = ctx->priv_data;
259 int err;
260
261 HEADER("Frame");
262
263 CHECK(FUNC(pbu_header)(ctx, rw, &current->pbu_header));
264
265 CHECK(FUNC(frame_header)(ctx, rw, &current->frame_header));
266
267 for (int t = 0; t < priv->num_tiles; t++) {
268 us(32, tile_size[t], 10, MAX_INT_BITS(32), 1, t);
269
270 CHECK(FUNC(tile)(ctx, rw, &current->tile[t],
271 t, current->tile_size[t]));
272 }
273
274 CHECK(FUNC(filler)(ctx, rw, &current->filler));
275
276 return 0;
277}
278
281{
282 int err;
283
284 HEADER("Access Unit Information");
285
286 u(16, num_frames, 1, CBS_APV_MAX_AU_FRAMES);
287
288 for (int i = 0; i < current->num_frames; i++) {
289 ubs(8, pbu_type[i], 1, i);
290 ubs(8, group_id[i], 1, i);
291
292 us(8, reserved_zero_8bits[i], 0, 0, 1, i);
293
294 CHECK(FUNC(frame_info)(ctx, rw, &current->frame_info[i]));
295 }
296
297 u(8, reserved_zero_8bits_2, 0, 0);
298
299 return 0;
300}
301
303 RWContext *rw,
305 size_t payload_size)
306{
307 int err;
308 size_t read_size = payload_size - 1;
309
310 HEADER("ITU-T T.35 Metadata");
311
312 ub(8, itu_t_t35_country_code);
313
314 if (current->itu_t_t35_country_code == 0xff) {
315 ub(8, itu_t_t35_country_code_extension);
316 --read_size;
317 }
318
319#ifdef READ
320 current->data_size = read_size;
321 current->data_ref = av_buffer_alloc(current->data_size);
322 if (!current->data_ref)
323 return AVERROR(ENOMEM);
324 current->data = current->data_ref->data;
325#else
326 if (current->data_size != read_size) {
327 av_log(ctx->log_ctx, AV_LOG_ERROR, "Write size mismatch: "
328 "payload %zu but expecting %zu\n",
329 current->data_size, read_size);
330 return AVERROR(EINVAL);
331 }
332#endif
333
334 for (size_t i = 0; i < current->data_size; i++) {
335 xu(8, itu_t_t35_payload[i],
336 current->data[i], 0x00, 0xff, 1, i);
337 }
338
339 return 0;
340}
341
343 RWContext *rw,
345{
346 int err, i;
347
348 HEADER("MDCV Metadata");
349
350 for (i = 0; i < 3; i++) {
351 ubs(16, primary_chromaticity_x[i], 1, i);
352 ubs(16, primary_chromaticity_y[i], 1, i);
353 }
354
355 ub(16, white_point_chromaticity_x);
356 ub(16, white_point_chromaticity_y);
357
358 ub(32, max_mastering_luminance);
359 ub(32, min_mastering_luminance);
360
361 return 0;
362}
363
365 RWContext *rw,
367{
368 int err;
369
370 HEADER("CLL Metadata");
371
372 ub(16, max_cll);
373 ub(16, max_fall);
374
375 return 0;
376}
377
379 RWContext *rw,
381 size_t payload_size)
382{
383 int err;
384
385 HEADER("Filler Metadata");
386
387 for (size_t i = 0; i < payload_size; i++)
388 fixed(8, ff_byte, 0xff);
389
390 return 0;
391}
392
394 RWContext *rw,
396 size_t payload_size)
397{
398 int err;
399
400 HEADER("User-Defined Metadata");
401
402 for (int i = 0; i < 16; i++)
403 ubs(8, uuid[i], 1, i);
404
405#ifdef READ
406 current->data_size = payload_size - 16;
407 current->data_ref = av_buffer_alloc(current->data_size);
408 if (!current->data_ref)
409 return AVERROR(ENOMEM);
410 current->data = current->data_ref->data;
411#else
412 if (current->data_size != payload_size - 16) {
413 av_log(ctx->log_ctx, AV_LOG_ERROR, "Write size mismatch: "
414 "payload %zu but expecting %zu\n",
415 current->data_size, payload_size - 16);
416 return AVERROR(EINVAL);
417 }
418#endif
419
420 for (size_t i = 0; i < current->data_size; i++) {
421 xu(8, user_defined_data_payload[i],
422 current->data[i], 0x00, 0xff, 1, i);
423 }
424
425 return 0;
426}
427
429 RWContext *rw,
431 size_t payload_size)
432{
433 int err;
434
435 HEADER("Undefined Metadata");
436
437#ifdef READ
438 current->data_size = payload_size;
439 current->data_ref = av_buffer_alloc(current->data_size);
440 if (!current->data_ref)
441 return AVERROR(ENOMEM);
442 current->data = current->data_ref->data;
443#else
444 if (current->data_size != payload_size) {
445 av_log(ctx->log_ctx, AV_LOG_ERROR, "Write size mismatch: "
446 "payload %zu but expecting %zu\n",
447 current->data_size, payload_size - 16);
448 return AVERROR(EINVAL);
449 }
450#endif
451
452 for (size_t i = 0; i < current->data_size; i++) {
453 xu(8, undefined_metadata_payload_byte[i],
454 current->data[i], 0x00, 0xff, 1, i);
455 }
456
457 return 0;
458}
459
461 RWContext *rw,
463{
464 int err;
465
466 switch (current->payload_type) {
469 &current->itu_t_t35,
470 current->payload_size));
471 break;
473 CHECK(FUNC(metadata_mdcv)(ctx, rw, &current->mdcv));
474 break;
475 case APV_METADATA_CLL:
476 CHECK(FUNC(metadata_cll)(ctx, rw, &current->cll));
477 break;
480 &current->filler,
481 current->payload_size));
482 break;
485 &current->user_defined,
486 current->payload_size));
487 break;
488 default:
490 &current->undefined,
491 current->payload_size));
492 }
493
494 return 0;
495}
496
499{
500 int err;
501
502#ifdef READ
503 uint32_t metadata_bytes_left;
504#else
505 PutBitContext metadata_start_state;
506 uint32_t metadata_start_position;
507 int trace;
508#endif
509
510 HEADER("Metadata");
511
512 CHECK(FUNC(pbu_header)(ctx, rw, &current->pbu_header));
513
514#ifdef READ
515 ub(32, metadata_size);
516
517 metadata_bytes_left = current->metadata_size;
518
519 for (int p = 0; p < CBS_APV_MAX_METADATA_PAYLOADS; p++) {
520 APVRawMetadataPayload *pl = &current->payloads[p];
521 uint32_t tmp;
522
523 pl->payload_type = 0;
524 while (show_bits(rw, 8) == 0xff) {
525 fixed(8, ff_byte, 0xff);
526 pl->payload_type += 255;
527 --metadata_bytes_left;
528 }
529 xu(8, metadata_payload_type, tmp, 0, 254, 0);
530 pl->payload_type += tmp;
531 --metadata_bytes_left;
532
533 pl->payload_size = 0;
534 while (show_bits(rw, 8) == 0xff) {
535 fixed(8, ff_byte, 0xff);
536 pl->payload_size += 255;
537 --metadata_bytes_left;
538 }
539 xu(8, metadata_payload_size, tmp, 0, 254, 0);
540 pl->payload_size += tmp;
541 --metadata_bytes_left;
542
543 if (pl->payload_size > metadata_bytes_left) {
544 av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid metadata: "
545 "payload_size larger than remaining metadata size "
546 "(%"PRIu32" bytes).\n", pl->payload_size);
547 return AVERROR_INVALIDDATA;
548 }
549
550 current->metadata_count = p + 1;
551
552 CHECK(FUNC(metadata_payload)(ctx, rw, pl));
553
554 metadata_bytes_left -= pl->payload_size;
555 if (metadata_bytes_left == 0)
556 break;
557 }
558#else
559 // Two passes: the first write finds the size (with tracing
560 // disabled), the second write does the real write.
561
562 metadata_start_state = *rw;
563 metadata_start_position = put_bits_count(rw);
564
565 trace = ctx->trace_enable;
566 ctx->trace_enable = 0;
567
568 for (int pass = 1; pass <= 2; pass++) {
569 *rw = metadata_start_state;
570
571 ub(32, metadata_size);
572
573 for (int p = 0; p < current->metadata_count; p++) {
574 APVRawMetadataPayload *pl = &current->payloads[p];
575 uint32_t payload_start_position;
576 uint32_t tmp;
577
578 tmp = pl->payload_type;
579 while (tmp >= 255) {
580 fixed(8, ff_byte, 0xff);
581 tmp -= 255;
582 }
583 xu(8, metadata_payload_type, tmp, 0, 254, 0);
584
585 tmp = pl->payload_size;
586 while (tmp >= 255) {
587 fixed(8, ff_byte, 0xff);
588 tmp -= 255;
589 }
590 xu(8, metadata_payload_size, tmp, 0, 254, 0);
591
592 payload_start_position = put_bits_count(rw);
593
594 err = FUNC(metadata_payload)(ctx, rw, pl);
595 ctx->trace_enable = trace;
596 if (err < 0)
597 return err;
598
599 if (pass == 1) {
600 pl->payload_size = (put_bits_count(rw) -
601 payload_start_position) / 8;
602 }
603 }
604
605 if (pass == 1) {
606 current->metadata_size = (put_bits_count(rw) -
607 metadata_start_position) / 8 - 4;
608 ctx->trace_enable = trace;
609 }
610 }
611#endif
612
613 CHECK(FUNC(filler)(ctx, rw, &current->filler));
614
615 return 0;
616}
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition avassert.h:42
#define FUNC(a)
void ff_copy_bits(PutBitContext *pb, const uint8_t *src, int length)
Copy the content of src to the bitstream.
Definition bitstream.c:49
#define CBS_APV_MAX_AU_FRAMES
Definition cbs_apv.h:29
#define CBS_APV_MAX_METADATA_PAYLOADS
Definition cbs_apv.h:30
static int FUNC pbu_header(CodedBitstreamContext *ctx, RWContext *rw, APVRawPBUHeader *current)
static int FUNC tile_info(CodedBitstreamContext *ctx, RWContext *rw, APVRawTileInfo *current, const APVRawFrameHeader *fh)
static int FUNC metadata_undefined(CodedBitstreamContext *ctx, RWContext *rw, APVRawMetadataUndefined *current, size_t payload_size)
static int FUNC metadata_mdcv(CodedBitstreamContext *ctx, RWContext *rw, APVRawMetadataMDCV *current)
static int FUNC quantization_matrix(CodedBitstreamContext *ctx, RWContext *rw, APVRawQuantizationMatrix *current)
static int FUNC metadata(CodedBitstreamContext *ctx, RWContext *rw, APVRawMetadata *current)
static int FUNC metadata_payload(CodedBitstreamContext *ctx, RWContext *rw, APVRawMetadataPayload *current)
static int FUNC au_info(CodedBitstreamContext *ctx, RWContext *rw, APVRawAUInfo *current)
static int FUNC metadata_filler(CodedBitstreamContext *ctx, RWContext *rw, APVRawMetadataFiller *current, size_t payload_size)
static int FUNC metadata_user_defined(CodedBitstreamContext *ctx, RWContext *rw, APVRawMetadataUserDefined *current, size_t payload_size)
static int FUNC metadata_cll(CodedBitstreamContext *ctx, RWContext *rw, APVRawMetadataCLL *current)
static int FUNC tile(CodedBitstreamContext *ctx, RWContext *rw, APVRawTile *current, int tile_idx, uint32_t tile_size)
static int FUNC tile_header(CodedBitstreamContext *ctx, RWContext *rw, APVRawTileHeader *current, int tile_idx, uint32_t tile_size)
static int FUNC metadata_itu_t_t35(CodedBitstreamContext *ctx, RWContext *rw, APVRawMetadataITUTT35 *current, size_t payload_size)
static int FUNC frame_info(CodedBitstreamContext *ctx, RWContext *rw, APVRawFrameInfo *current)
#define ub(width, name)
Definition cbs_h264.c:95
#define infer(name, value)
Definition cbs_h264.c:131
#define byte_alignment(rw)
Definition cbs_h264.c:138
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define RWContext
Definition cbs_h264.c:93
#define xu(width, name, var, range_min, range_max, subs,...)
Definition cbs_h264.c:101
#define MAX_INT_BITS(length)
#define MAX_UINT_BITS(length)
static const AVColorPrimariesDesc color_primaries[AVCOL_PRI_NB]
Definition csp.c:76
static AVFrame * frame
static struct @111144215057303131116103221376075045141373005341 current
static int get_bits_left(GetBitContext *gb)
Definition get_bits.h:688
static void skip_bits_long(GetBitContext *s, int n)
Skips the specified number of bits.
Definition get_bits.h:280
static const uint8_t * align_get_bits(GetBitContext *s)
Definition get_bits.h:560
static int get_bits_count(const GetBitContext *s)
Definition get_bits.h:254
static unsigned int show_bits(GetBitContext *s, int n)
Show 1-25 bits.
Definition get_bits.h:373
AVBufferRef * av_buffer_alloc(size_t size)
Allocate an AVBuffer of the given size using av_malloc().
Definition buffer.c:77
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition error.h:61
#define AVERROR(e)
Definition error.h:45
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
int profile_idc
Definition h264_levels.c:53
int(* filler)(InterplayACMContext *s, unsigned ind, unsigned col)
@ APV_MAX_TILE_COLS
Definition apv.h:75
@ APV_MAX_TILE_ROWS
Definition apv.h:76
@ APV_METADATA_ITU_T_T35
Definition apv.h:82
@ APV_METADATA_USER_DEFINED
Definition apv.h:86
@ APV_METADATA_CLL
Definition apv.h:84
@ APV_METADATA_MDCV
Definition apv.h:83
@ APV_METADATA_FILLER
Definition apv.h:85
#define fixed(width, name, value)
Definition cbs_apv.c:75
#define u(width, name, range_min, range_max)
Definition cbs_apv.c:68
static void cbs_apv_derive_tile_info(CodedBitstreamContext *ctx, const APVRawFrameHeader *fh)
Definition cbs_apv.c:40
#define us(width, name, range_min, range_max, subs,...)
Definition cbs_apv.c:70
static int cbs_apv_get_num_comp(const APVRawFrameHeader *fh)
Definition cbs_apv.c:25
#define ubs(width, name, subs,...)
Definition cbs_apv.c:72
#define CHECK(call)
Definition cbs_apv.c:59
#define HEADER(name)
Definition cbs_apv.c:55
static const struct TransferCharacteristics transfer_characteristics[]
static int put_bits_count(PutBitContext *s)
Definition put_bits.h:90
static int put_bytes_left(const PutBitContext *s, int round_up)
Definition put_bits.h:145
unsigned int pos
Definition spdifenc.c:431
uint32_t payload_type
Definition cbs_apv.h:166
uint32_t payload_size
Definition cbs_apv.h:167
Context structure for coded bitstream operations.
Definition cbs.h:226
#define av_log(a,...)
static uint8_t tmp[40]
Definition aes_ctr.c:52
int level_idc
Definition h264_levels.c:29
static AVFormatContext * ctx
Definition movenc.c:49
static double c[64]