FFmpeg  4.4.4
h264_metadata_bsf.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/avstring.h"
20 #include "libavutil/display.h"
21 #include "libavutil/common.h"
22 #include "libavutil/opt.h"
23 
24 #include "bsf.h"
25 #include "cbs.h"
26 #include "cbs_bsf.h"
27 #include "cbs_h264.h"
28 #include "h264.h"
29 #include "h264_levels.h"
30 #include "h264_sei.h"
31 
32 enum {
35 };
36 
37 enum {
39  LEVEL_AUTO = -1,
40 };
41 
42 typedef struct H264MetadataContext {
44 
46 
47  int aud;
49 
51 
53 
59 
61 
64 
65  int crop_left;
67  int crop_top;
69 
70  const char *sei_user_data;
72 
74 
76  double rotate;
77  int flip;
79 
80  int level;
82 
83 
86 {
88  int primary_pic_type_mask = 0xff;
89  int err, i, j;
90 
91  static const int primary_pic_type_table[] = {
92  0x084, // 2, 7
93  0x0a5, // 0, 2, 5, 7
94  0x0e7, // 0, 1, 2, 5, 6, 7
95  0x210, // 4, 9
96  0x318, // 3, 4, 8, 9
97  0x294, // 2, 4, 7, 9
98  0x3bd, // 0, 2, 3, 4, 5, 7, 8, 9
99  0x3ff, // 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
100  };
101 
102  for (i = 0; i < au->nb_units; i++) {
103  if (au->units[i].type == H264_NAL_SLICE ||
104  au->units[i].type == H264_NAL_IDR_SLICE) {
105  H264RawSlice *slice = au->units[i].content;
106  for (j = 0; j < FF_ARRAY_ELEMS(primary_pic_type_table); j++) {
107  if (!(primary_pic_type_table[j] &
108  (1 << slice->header.slice_type)))
109  primary_pic_type_mask &= ~(1 << j);
110  }
111  }
112  }
113  for (j = 0; j < FF_ARRAY_ELEMS(primary_pic_type_table); j++)
114  if (primary_pic_type_mask & (1 << j))
115  break;
116  if (j >= FF_ARRAY_ELEMS(primary_pic_type_table)) {
117  av_log(bsf, AV_LOG_ERROR, "No usable primary_pic_type: "
118  "invalid slice types?\n");
119  return AVERROR_INVALIDDATA;
120  }
121 
122  ctx->aud_nal = (H264RawAUD) {
123  .nal_unit_header.nal_unit_type = H264_NAL_AUD,
124  .primary_pic_type = j,
125  };
126 
128  &ctx->aud_nal, NULL);
129  if (err < 0) {
130  av_log(bsf, AV_LOG_ERROR, "Failed to insert AUD.\n");
131  return err;
132  }
133 
134  return 0;
135 }
136 
138  H264RawSPS *sps)
139 {
141  int need_vui = 0;
142  int crop_unit_x, crop_unit_y;
143 
144  if (ctx->sample_aspect_ratio.num && ctx->sample_aspect_ratio.den) {
145  // Table E-1.
146  static const AVRational sar_idc[] = {
147  { 0, 0 }, // Unspecified (never written here).
148  { 1, 1 }, { 12, 11 }, { 10, 11 }, { 16, 11 },
149  { 40, 33 }, { 24, 11 }, { 20, 11 }, { 32, 11 },
150  { 80, 33 }, { 18, 11 }, { 15, 11 }, { 64, 33 },
151  { 160, 99 }, { 4, 3 }, { 3, 2 }, { 2, 1 },
152  };
153  int num, den, i;
154 
155  av_reduce(&num, &den, ctx->sample_aspect_ratio.num,
156  ctx->sample_aspect_ratio.den, 65535);
157 
158  for (i = 1; i < FF_ARRAY_ELEMS(sar_idc); i++) {
159  if (num == sar_idc[i].num &&
160  den == sar_idc[i].den)
161  break;
162  }
163  if (i == FF_ARRAY_ELEMS(sar_idc)) {
164  sps->vui.aspect_ratio_idc = 255;
165  sps->vui.sar_width = num;
166  sps->vui.sar_height = den;
167  } else {
168  sps->vui.aspect_ratio_idc = i;
169  }
170  sps->vui.aspect_ratio_info_present_flag = 1;
171  need_vui = 1;
172  }
173 
174 #define SET_VUI_FIELD(field) do { \
175  if (ctx->field >= 0) { \
176  sps->vui.field = ctx->field; \
177  need_vui = 1; \
178  } \
179  } while (0)
180 
181  if (ctx->overscan_appropriate_flag >= 0) {
182  SET_VUI_FIELD(overscan_appropriate_flag);
183  sps->vui.overscan_info_present_flag = 1;
184  }
185 
186  if (ctx->video_format >= 0 ||
187  ctx->video_full_range_flag >= 0 ||
188  ctx->colour_primaries >= 0 ||
189  ctx->transfer_characteristics >= 0 ||
190  ctx->matrix_coefficients >= 0) {
191 
192  SET_VUI_FIELD(video_format);
193 
194  SET_VUI_FIELD(video_full_range_flag);
195 
196  if (ctx->colour_primaries >= 0 ||
197  ctx->transfer_characteristics >= 0 ||
198  ctx->matrix_coefficients >= 0) {
199 
200  SET_VUI_FIELD(colour_primaries);
202  SET_VUI_FIELD(matrix_coefficients);
203 
204  sps->vui.colour_description_present_flag = 1;
205  }
206  sps->vui.video_signal_type_present_flag = 1;
207  }
208 
209  if (ctx->chroma_sample_loc_type >= 0) {
210  sps->vui.chroma_sample_loc_type_top_field =
211  ctx->chroma_sample_loc_type;
212  sps->vui.chroma_sample_loc_type_bottom_field =
213  ctx->chroma_sample_loc_type;
214  sps->vui.chroma_loc_info_present_flag = 1;
215  need_vui = 1;
216  }
217 
218  if (ctx->tick_rate.num && ctx->tick_rate.den) {
219  int num, den;
220 
221  av_reduce(&num, &den, ctx->tick_rate.num, ctx->tick_rate.den,
222  UINT32_MAX > INT_MAX ? UINT32_MAX : INT_MAX);
223 
224  sps->vui.time_scale = num;
225  sps->vui.num_units_in_tick = den;
226 
227  sps->vui.timing_info_present_flag = 1;
228  need_vui = 1;
229  }
230  SET_VUI_FIELD(fixed_frame_rate_flag);
231 
232  if (sps->separate_colour_plane_flag || sps->chroma_format_idc == 0) {
233  crop_unit_x = 1;
234  crop_unit_y = 2 - sps->frame_mbs_only_flag;
235  } else {
236  crop_unit_x = 1 + (sps->chroma_format_idc < 3);
237  crop_unit_y = (1 + (sps->chroma_format_idc < 2)) *
238  (2 - sps->frame_mbs_only_flag);
239  }
240 #define CROP(border, unit) do { \
241  if (ctx->crop_ ## border >= 0) { \
242  if (ctx->crop_ ## border % unit != 0) { \
243  av_log(bsf, AV_LOG_ERROR, "Invalid value for crop_%s: " \
244  "must be a multiple of %d.\n", #border, unit); \
245  return AVERROR(EINVAL); \
246  } \
247  sps->frame_crop_ ## border ## _offset = \
248  ctx->crop_ ## border / unit; \
249  sps->frame_cropping_flag = 1; \
250  } \
251  } while (0)
252  CROP(left, crop_unit_x);
253  CROP(right, crop_unit_x);
254  CROP(top, crop_unit_y);
255  CROP(bottom, crop_unit_y);
256 #undef CROP
257 
258  if (ctx->level != LEVEL_UNSET) {
259  int level_idc;
260 
261  if (ctx->level == LEVEL_AUTO) {
262  const H264LevelDescriptor *desc;
263  int64_t bit_rate;
264  int width, height, dpb_frames;
265  int framerate;
266 
267  if (sps->vui.nal_hrd_parameters_present_flag) {
268  bit_rate = (sps->vui.nal_hrd_parameters.bit_rate_value_minus1[0] + 1) *
269  (INT64_C(1) << (sps->vui.nal_hrd_parameters.bit_rate_scale + 6));
270  } else if (sps->vui.vcl_hrd_parameters_present_flag) {
271  bit_rate = (sps->vui.vcl_hrd_parameters.bit_rate_value_minus1[0] + 1) *
272  (INT64_C(1) << (sps->vui.vcl_hrd_parameters.bit_rate_scale + 6));
273  // Adjust for VCL vs. NAL limits.
274  bit_rate = bit_rate * 6 / 5;
275  } else {
276  bit_rate = 0;
277  }
278 
279  // Don't use max_dec_frame_buffering if it is only inferred.
280  dpb_frames = sps->vui.bitstream_restriction_flag ?
281  sps->vui.max_dec_frame_buffering : H264_MAX_DPB_FRAMES;
282 
283  width = 16 * (sps->pic_width_in_mbs_minus1 + 1);
284  height = 16 * (sps->pic_height_in_map_units_minus1 + 1) *
285  (2 - sps->frame_mbs_only_flag);
286 
287  if (sps->vui.timing_info_present_flag)
288  framerate = sps->vui.time_scale / sps->vui.num_units_in_tick / 2;
289  else
290  framerate = 0;
291 
292  desc = ff_h264_guess_level(sps->profile_idc, bit_rate, framerate,
294  if (desc) {
295  level_idc = desc->level_idc;
296  } else {
297  av_log(bsf, AV_LOG_WARNING, "Stream does not appear to "
298  "conform to any level: using level 6.2.\n");
299  level_idc = 62;
300  }
301  } else {
302  level_idc = ctx->level;
303  }
304 
305  if (level_idc == 9) {
306  if (sps->profile_idc == 66 ||
307  sps->profile_idc == 77 ||
308  sps->profile_idc == 88) {
309  sps->level_idc = 11;
310  sps->constraint_set3_flag = 1;
311  } else {
312  sps->level_idc = 9;
313  }
314  } else {
315  sps->level_idc = level_idc;
316  }
317  }
318 
319  if (need_vui)
320  sps->vui_parameters_present_flag = 1;
321 
322  return 0;
323 }
324 
326  AVPacket *pkt,
328  int seek_point)
329 {
332  int err;
333 
334  message = NULL;
335  while (ff_cbs_sei_find_message(ctx->common.output, au,
337  &message) == 0) {
338  H264RawSEIDisplayOrientation *disp = message->payload;
339  int32_t *matrix;
340 
341  matrix = av_malloc(9 * sizeof(int32_t));
342  if (!matrix)
343  return AVERROR(ENOMEM);
344 
346  disp->anticlockwise_rotation *
347  180.0 / 65536.0);
348  av_display_matrix_flip(matrix, disp->hor_flip, disp->ver_flip);
349 
350  // If there are multiple display orientation messages in an
351  // access unit, then the last one added to the packet (i.e.
352  // the first one in the access unit) will prevail.
354  (uint8_t*)matrix,
355  9 * sizeof(int32_t));
356  if (err < 0) {
357  av_log(bsf, AV_LOG_ERROR, "Failed to attach extracted "
358  "displaymatrix side data to packet.\n");
359  av_free(matrix);
360  return AVERROR(ENOMEM);
361  }
362  }
363 
364  if (ctx->display_orientation == BSF_ELEMENT_REMOVE ||
365  ctx->display_orientation == BSF_ELEMENT_INSERT) {
366  ff_cbs_sei_delete_message_type(ctx->common.output, au,
368  }
369 
370  if (ctx->display_orientation == BSF_ELEMENT_INSERT) {
372  &ctx->display_orientation_payload;
373  uint8_t *data;
375  int write = 0;
376 
378  if (data && size >= 9 * sizeof(int32_t)) {
379  int32_t matrix[9];
380  double dmatrix[9];
381  int hflip, vflip, i;
382  double scale_x, scale_y, angle;
383 
384  memcpy(matrix, data, sizeof(matrix));
385 
386  for (i = 0; i < 9; i++)
387  dmatrix[i] = matrix[i] / 65536.0;
388 
389  // Extract scale factors.
390  scale_x = hypot(dmatrix[0], dmatrix[3]);
391  scale_y = hypot(dmatrix[1], dmatrix[4]);
392 
393  // Select flips to make the main diagonal positive.
394  hflip = dmatrix[0] < 0.0;
395  vflip = dmatrix[4] < 0.0;
396  if (hflip)
397  scale_x = -scale_x;
398  if (vflip)
399  scale_y = -scale_y;
400 
401  // Rescale.
402  for (i = 0; i < 9; i += 3) {
403  dmatrix[i] /= scale_x;
404  dmatrix[i + 1] /= scale_y;
405  }
406 
407  // Extract rotation.
408  angle = atan2(dmatrix[3], dmatrix[0]);
409 
410  if (!(angle >= -M_PI && angle <= M_PI) ||
411  matrix[2] != 0.0 || matrix[5] != 0.0 ||
412  matrix[6] != 0.0 || matrix[7] != 0.0) {
413  av_log(bsf, AV_LOG_WARNING, "Input display matrix is not "
414  "representable in H.264 parameters.\n");
415  } else {
416  disp->hor_flip = hflip;
417  disp->ver_flip = vflip;
418  disp->anticlockwise_rotation =
419  (uint16_t)rint((angle >= 0.0 ? angle
420  : angle + 2 * M_PI) *
421  32768.0 / M_PI);
422  write = 1;
423  }
424  }
425 
426  if (seek_point) {
427  if (!isnan(ctx->rotate)) {
428  disp->anticlockwise_rotation =
429  (uint16_t)rint((ctx->rotate >= 0.0 ? ctx->rotate
430  : ctx->rotate + 360.0) *
431  65536.0 / 360.0);
432  write = 1;
433  }
434  if (ctx->flip) {
435  disp->hor_flip = !!(ctx->flip & FLIP_HORIZONTAL);
436  disp->ver_flip = !!(ctx->flip & FLIP_VERTICAL);
437  write = 1;
438  }
439  }
440 
441  if (write) {
443 
444  err = ff_cbs_sei_add_message(ctx->common.output, au, 1,
446  disp, NULL);
447  if (err < 0) {
448  av_log(bsf, AV_LOG_ERROR, "Failed to add display orientation "
449  "SEI message to access unit.\n");
450  return err;
451  }
452  }
453  }
454 
455  return 0;
456 }
457 
460 {
462  int err, i, has_sps, seek_point;
463 
464  // If an AUD is present, it must be the first NAL unit.
465  if (au->nb_units && au->units[0].type == H264_NAL_AUD) {
466  if (ctx->aud == BSF_ELEMENT_REMOVE)
467  ff_cbs_delete_unit(au, 0);
468  } else {
469  if (pkt && ctx->aud == BSF_ELEMENT_INSERT) {
470  err = h264_metadata_insert_aud(bsf, au);
471  if (err < 0)
472  return err;
473  }
474  }
475 
476  has_sps = 0;
477  for (i = 0; i < au->nb_units; i++) {
478  if (au->units[i].type == H264_NAL_SPS) {
479  err = h264_metadata_update_sps(bsf, au->units[i].content);
480  if (err < 0)
481  return err;
482  has_sps = 1;
483  }
484  }
485 
486  if (pkt) {
487  // The current packet should be treated as a seek point for metadata
488  // insertion if any of:
489  // - It is the first packet in the stream.
490  // - It contains an SPS, indicating that a sequence might start here.
491  // - It is marked as containing a key frame.
492  seek_point = !ctx->done_first_au || has_sps ||
494  } else {
495  seek_point = 0;
496  }
497 
498  if (ctx->sei_user_data && seek_point) {
499  err = ff_cbs_sei_add_message(ctx->common.output, au, 1,
501  &ctx->sei_user_data_payload, NULL);
502  if (err < 0) {
503  av_log(bsf, AV_LOG_ERROR, "Failed to add user data SEI "
504  "message to access unit.\n");
505  return err;
506  }
507  }
508 
509  if (ctx->delete_filler) {
510  for (i = au->nb_units - 1; i >= 0; i--) {
511  if (au->units[i].type == H264_NAL_FILLER_DATA) {
512  ff_cbs_delete_unit(au, i);
513  continue;
514  }
515  }
516 
517  ff_cbs_sei_delete_message_type(ctx->common.output, au,
519  }
520 
521  if (pkt && ctx->display_orientation != BSF_ELEMENT_PASS) {
523  seek_point);
524  if (err < 0)
525  return err;
526  }
527 
528  if (pkt)
529  ctx->done_first_au = 1;
530 
531  return 0;
532 }
533 
536  .fragment_name = "access unit",
537  .unit_name = "NAL unit",
538  .update_fragment = &h264_metadata_update_fragment,
539 };
540 
542 {
544 
545  if (ctx->sei_user_data) {
546  SEIRawUserDataUnregistered *udu = &ctx->sei_user_data_payload;
547  int i, j;
548 
549  // Parse UUID. It must be a hex string of length 32, possibly
550  // containing '-'s between hex digits (which we ignore).
551  for (i = j = 0; j < 32 && i < 64 && ctx->sei_user_data[i]; i++) {
552  int c, v;
553  c = ctx->sei_user_data[i];
554  if (c == '-') {
555  continue;
556  } else if (av_isxdigit(c)) {
557  c = av_tolower(c);
558  v = (c <= '9' ? c - '0' : c - 'a' + 10);
559  } else {
560  break;
561  }
562  if (j & 1)
563  udu->uuid_iso_iec_11578[j / 2] |= v;
564  else
565  udu->uuid_iso_iec_11578[j / 2] = v << 4;
566  ++j;
567  }
568  if (j == 32 && ctx->sei_user_data[i] == '+') {
569  udu->data = (uint8_t*)ctx->sei_user_data + i + 1;
570  udu->data_length = strlen(udu->data) + 1;
571  } else {
572  av_log(bsf, AV_LOG_ERROR, "Invalid user data: "
573  "must be \"UUID+string\".\n");
574  return AVERROR(EINVAL);
575  }
576  }
577 
579 }
580 
581 #define OFFSET(x) offsetof(H264MetadataContext, x)
582 #define FLAGS (AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_BSF_PARAM)
583 static const AVOption h264_metadata_options[] = {
584  BSF_ELEMENT_OPTIONS_PIR("aud", "Access Unit Delimiter NAL units",
585  aud, FLAGS),
586 
587  { "sample_aspect_ratio", "Set sample aspect ratio (table E-1)",
588  OFFSET(sample_aspect_ratio), AV_OPT_TYPE_RATIONAL,
589  { .dbl = 0.0 }, 0, 65535, FLAGS },
590 
591  { "overscan_appropriate_flag", "Set VUI overscan appropriate flag",
592  OFFSET(overscan_appropriate_flag), AV_OPT_TYPE_INT,
593  { .i64 = -1 }, -1, 1, FLAGS },
594 
595  { "video_format", "Set video format (table E-2)",
596  OFFSET(video_format), AV_OPT_TYPE_INT,
597  { .i64 = -1 }, -1, 7, FLAGS},
598  { "video_full_range_flag", "Set video full range flag",
599  OFFSET(video_full_range_flag), AV_OPT_TYPE_INT,
600  { .i64 = -1 }, -1, 1, FLAGS },
601  { "colour_primaries", "Set colour primaries (table E-3)",
602  OFFSET(colour_primaries), AV_OPT_TYPE_INT,
603  { .i64 = -1 }, -1, 255, FLAGS },
604  { "transfer_characteristics", "Set transfer characteristics (table E-4)",
606  { .i64 = -1 }, -1, 255, FLAGS },
607  { "matrix_coefficients", "Set matrix coefficients (table E-5)",
608  OFFSET(matrix_coefficients), AV_OPT_TYPE_INT,
609  { .i64 = -1 }, -1, 255, FLAGS },
610 
611  { "chroma_sample_loc_type", "Set chroma sample location type (figure E-1)",
612  OFFSET(chroma_sample_loc_type), AV_OPT_TYPE_INT,
613  { .i64 = -1 }, -1, 6, FLAGS },
614 
615  { "tick_rate", "Set VUI tick rate (num_units_in_tick / time_scale)",
616  OFFSET(tick_rate), AV_OPT_TYPE_RATIONAL,
617  { .dbl = 0.0 }, 0, UINT_MAX, FLAGS },
618  { "fixed_frame_rate_flag", "Set VUI fixed frame rate flag",
619  OFFSET(fixed_frame_rate_flag), AV_OPT_TYPE_INT,
620  { .i64 = -1 }, -1, 1, FLAGS },
621 
622  { "crop_left", "Set left border crop offset",
623  OFFSET(crop_left), AV_OPT_TYPE_INT,
624  { .i64 = -1 }, -1, H264_MAX_WIDTH, FLAGS },
625  { "crop_right", "Set right border crop offset",
626  OFFSET(crop_right), AV_OPT_TYPE_INT,
627  { .i64 = -1 }, -1, H264_MAX_WIDTH, FLAGS },
628  { "crop_top", "Set top border crop offset",
629  OFFSET(crop_top), AV_OPT_TYPE_INT,
630  { .i64 = -1 }, -1, H264_MAX_HEIGHT, FLAGS },
631  { "crop_bottom", "Set bottom border crop offset",
632  OFFSET(crop_bottom), AV_OPT_TYPE_INT,
633  { .i64 = -1 }, -1, H264_MAX_HEIGHT, FLAGS },
634 
635  { "sei_user_data", "Insert SEI user data (UUID+string)",
636  OFFSET(sei_user_data), AV_OPT_TYPE_STRING, { .str = NULL }, .flags = FLAGS },
637 
638  { "delete_filler", "Delete all filler (both NAL and SEI)",
639  OFFSET(delete_filler), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, FLAGS},
640 
641  BSF_ELEMENT_OPTIONS_PIRE("display_orientation",
642  "Display orientation SEI",
643  display_orientation, FLAGS),
644 
645  { "rotate", "Set rotation in display orientation SEI (anticlockwise angle in degrees)",
647  { .dbl = NAN }, -360.0, +360.0, FLAGS },
648  { "flip", "Set flip in display orientation SEI",
650  { .i64 = 0 }, 0, FLIP_HORIZONTAL | FLIP_VERTICAL, FLAGS, "flip" },
651  { "horizontal", "Set hor_flip",
653  { .i64 = FLIP_HORIZONTAL }, .flags = FLAGS, .unit = "flip" },
654  { "vertical", "Set ver_flip",
656  { .i64 = FLIP_VERTICAL }, .flags = FLAGS, .unit = "flip" },
657 
658  { "level", "Set level (table A-1)",
660  { .i64 = LEVEL_UNSET }, LEVEL_UNSET, 0xff, FLAGS, "level" },
661  { "auto", "Attempt to guess level from stream properties",
663  { .i64 = LEVEL_AUTO }, .flags = FLAGS, .unit = "level" },
664 #define LEVEL(name, value) name, NULL, 0, AV_OPT_TYPE_CONST, \
665  { .i64 = value }, .flags = FLAGS, .unit = "level"
666  { LEVEL("1", 10) },
667  { LEVEL("1b", 9) },
668  { LEVEL("1.1", 11) },
669  { LEVEL("1.2", 12) },
670  { LEVEL("1.3", 13) },
671  { LEVEL("2", 20) },
672  { LEVEL("2.1", 21) },
673  { LEVEL("2.2", 22) },
674  { LEVEL("3", 30) },
675  { LEVEL("3.1", 31) },
676  { LEVEL("3.2", 32) },
677  { LEVEL("4", 40) },
678  { LEVEL("4.1", 41) },
679  { LEVEL("4.2", 42) },
680  { LEVEL("5", 50) },
681  { LEVEL("5.1", 51) },
682  { LEVEL("5.2", 52) },
683  { LEVEL("6", 60) },
684  { LEVEL("6.1", 61) },
685  { LEVEL("6.2", 62) },
686 #undef LEVEL
687 
688  { NULL }
689 };
690 
691 static const AVClass h264_metadata_class = {
692  .class_name = "h264_metadata_bsf",
693  .item_name = av_default_item_name,
694  .option = h264_metadata_options,
695  .version = LIBAVUTIL_VERSION_INT,
696 };
697 
698 static const enum AVCodecID h264_metadata_codec_ids[] = {
700 };
701 
703  .name = "h264_metadata",
704  .priv_data_size = sizeof(H264MetadataContext),
705  .priv_class = &h264_metadata_class,
707  .close = &ff_cbs_bsf_generic_close,
710 };
static enum AVCodecID codec_ids[]
uint8_t
int32_t
uint8_t * av_packet_get_side_data(const AVPacket *pkt, enum AVPacketSideDataType type, buffer_size_t *size)
Definition: avpacket.c:368
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:31
void ff_cbs_delete_unit(CodedBitstreamFragment *frag, int position)
Delete a unit from a fragment and free all memory it uses.
Definition: cbs.c:812
int ff_cbs_insert_unit_content(CodedBitstreamFragment *frag, int position, CodedBitstreamUnitType type, void *content, AVBufferRef *content_buf)
Insert a new unit into a fragment with the given content.
Definition: cbs.c:737
int ff_cbs_bsf_generic_filter(AVBSFContext *bsf, AVPacket *pkt)
Filter operation for CBS BSF.
Definition: cbs_bsf.c:63
int ff_cbs_bsf_generic_init(AVBSFContext *bsf, const CBSBSFType *type)
Initialise generic CBS BSF setup.
Definition: cbs_bsf.c:112
void ff_cbs_bsf_generic_close(AVBSFContext *bsf)
Close a generic CBS BSF instance.
Definition: cbs_bsf.c:152
#define BSF_ELEMENT_OPTIONS_PIR(name, help, field, opt_flags)
Definition: cbs_bsf.h:106
#define BSF_ELEMENT_OPTIONS_PIRE(name, help, field, opt_flags)
Definition: cbs_bsf.h:117
@ BSF_ELEMENT_REMOVE
Definition: cbs_bsf.h:100
@ BSF_ELEMENT_INSERT
Definition: cbs_bsf.h:98
@ BSF_ELEMENT_PASS
Definition: cbs_bsf.h:93
static int FUNC() sps(CodedBitstreamContext *ctx, RWContext *rw, H264RawSPS *current)
static int FUNC() aud(CodedBitstreamContext *ctx, RWContext *rw, H264RawAUD *current)
void ff_cbs_sei_delete_message_type(CodedBitstreamContext *ctx, CodedBitstreamFragment *au, uint32_t payload_type)
Delete all messages with the given payload type from an access unit.
Definition: cbs_sei.c:350
int ff_cbs_sei_add_message(CodedBitstreamContext *ctx, CodedBitstreamFragment *au, int prefix, uint32_t payload_type, void *payload_data, AVBufferRef *payload_buf)
Add an SEI message to an access unit.
Definition: cbs_sei.c:247
int ff_cbs_sei_find_message(CodedBitstreamContext *ctx, CodedBitstreamFragment *au, uint32_t payload_type, SEIRawMessage **iter)
Iterate over messages with the given payload type in an access unit.
Definition: cbs_sei.c:297
static int FUNC() message(CodedBitstreamContext *ctx, RWContext *rw, SEIRawMessage *current)
static av_always_inline void filter(int16_t *output, ptrdiff_t out_stride, const int16_t *low, ptrdiff_t low_stride, const int16_t *high, ptrdiff_t high_stride, int len, int clip)
Definition: cfhddsp.c:27
common internal and external API header
#define NULL
Definition: coverity.c:32
Display matrix.
@ AV_OPT_TYPE_CONST
Definition: opt.h:234
@ AV_OPT_TYPE_RATIONAL
Definition: opt.h:230
@ AV_OPT_TYPE_FLAGS
Definition: opt.h:224
@ AV_OPT_TYPE_INT
Definition: opt.h:225
@ AV_OPT_TYPE_DOUBLE
Definition: opt.h:227
@ AV_OPT_TYPE_STRING
Definition: opt.h:229
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition: codec_id.h:46
@ AV_CODEC_ID_H264
Definition: codec_id.h:76
@ AV_CODEC_ID_NONE
Definition: codec_id.h:47
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: packet.h:410
FF_ENABLE_DEPRECATION_WARNINGS int av_packet_add_side_data(AVPacket *pkt, enum AVPacketSideDataType type, uint8_t *data, size_t size)
Wrap an existing array as a packet side data.
Definition: avpacket.c:309
@ AV_PKT_DATA_DISPLAYMATRIX
This side data contains a 3x3 transformation matrix describing an affine transformation that needs to...
Definition: packet.h:108
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
#define AVERROR(e)
Definition: error.h:43
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:200
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:194
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:235
int av_reduce(int *dst_num, int *dst_den, int64_t num, int64_t den, int64_t max)
Reduce a fraction.
Definition: rational.c:35
static av_const int av_tolower(int c)
Locale-independent conversion of ASCII characters to lowercase.
Definition: avstring.h:246
static av_const int av_isxdigit(int c)
Locale-independent conversion of ASCII isxdigit.
Definition: avstring.h:256
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
void av_display_rotation_set(int32_t matrix[9], double angle)
Initialize a transformation matrix describing a pure counterclockwise rotation by the specified angle...
Definition: display.c:50
void av_display_matrix_flip(int32_t matrix[9], int hflip, int vflip)
Flip the input matrix horizontally and/or vertically.
Definition: display.c:65
H.264 common definitions.
@ H264_NAL_SPS
Definition: h264.h:41
@ H264_NAL_SLICE
Definition: h264.h:35
@ H264_NAL_FILLER_DATA
Definition: h264.h:46
@ H264_NAL_AUD
Definition: h264.h:43
@ H264_NAL_IDR_SLICE
Definition: h264.h:39
@ H264_MAX_WIDTH
Definition: h264.h:108
@ H264_MAX_DPB_FRAMES
Definition: h264.h:76
@ H264_MAX_HEIGHT
Definition: h264.h:109
const H264LevelDescriptor * ff_h264_guess_level(int profile_idc, int64_t bitrate, int framerate, int width, int height, int max_dec_frame_buffering)
Guess the level of a stream from some parameters.
Definition: h264_levels.c:78
#define CROP(border, unit)
@ FLIP_HORIZONTAL
@ FLIP_VERTICAL
@ LEVEL_UNSET
@ LEVEL_AUTO
const AVBitStreamFilter ff_h264_metadata_bsf
#define FLAGS
#define SET_VUI_FIELD(field)
static const CBSBSFType h264_metadata_type
#define LEVEL(name, value)
static const AVOption h264_metadata_options[]
static int h264_metadata_handle_display_orientation(AVBSFContext *bsf, AVPacket *pkt, CodedBitstreamFragment *au, int seek_point)
static int h264_metadata_init(AVBSFContext *bsf)
static int h264_metadata_update_sps(AVBSFContext *bsf, H264RawSPS *sps)
#define OFFSET(x)
static enum AVCodecID h264_metadata_codec_ids[]
static int h264_metadata_update_fragment(AVBSFContext *bsf, AVPacket *pkt, CodedBitstreamFragment *au)
static const AVClass h264_metadata_class
static int h264_metadata_insert_aud(AVBSFContext *bsf, CodedBitstreamFragment *au)
int i
Definition: input.c:407
static void flip(AVCodecContext *avctx, AVFrame *frame)
Definition: rawdec.c:137
static const struct TransferCharacteristics transfer_characteristics[AVCOL_TRC_NB]
int buffer_size_t
Definition: internal.h:306
#define isnan(x)
Definition: libm.h:340
static av_const double hypot(double x, double y)
Definition: libm.h:366
const char * desc
Definition: libsvtav1.c:79
#define NAN
Definition: mathematics.h:64
#define M_PI
Definition: mathematics.h:52
const char data[16]
Definition: mxf.c:142
AVOptions.
@ SEI_TYPE_FILLER_PAYLOAD
Definition: sei.h:33
@ SEI_TYPE_DISPLAY_ORIENTATION
Definition: sei.h:77
@ SEI_TYPE_USER_DATA_UNREGISTERED
Definition: sei.h:35
#define FF_ARRAY_ELEMS(a)
The bitstream filter state.
Definition: bsf.h:49
void * priv_data
Opaque filter-specific private data.
Definition: bsf.h:70
const char * name
Definition: bsf.h:99
Describe the class of an AVClass context structure.
Definition: log.h:67
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:72
AVOption.
Definition: opt.h:248
This structure stores compressed data.
Definition: packet.h:346
int flags
A combination of AV_PKT_FLAG values.
Definition: packet.h:375
Rational number (pair of numerator and denominator).
Definition: rational.h:58
enum AVCodecID codec_id
Definition: cbs_bsf.h:26
Coded bitstream fragment structure, combining one or more units.
Definition: cbs.h:118
CodedBitstreamUnit * units
Pointer to an array of units of length nb_units_allocated.
Definition: cbs.h:164
int nb_units
Number of units in this fragment.
Definition: cbs.h:149
void * content
Pointer to the decomposed form of this unit.
Definition: cbs.h:103
CodedBitstreamUnitType type
Codec-specific type of this unit.
Definition: cbs.h:70
SEIRawUserDataUnregistered sei_user_data_payload
H264RawSEIDisplayOrientation display_orientation_payload
const char * sei_user_data
AVRational sample_aspect_ratio
uint16_t display_orientation_repetition_period
Definition: cbs_h264.h:280
uint8_t slice_type
Definition: cbs_h264.h:293
H264RawSliceHeader header
Definition: cbs_h264.h:368
uint8_t uuid_iso_iec_11578[16]
Definition: cbs_sei.h:44
uint8_t level
Definition: svq3.c:206
#define rint
Definition: tablegen.h:41
#define av_free(p)
#define av_malloc(s)
#define av_log(a,...)
int framerate
Definition: h264_levels.c:65
int dpb_frames
Definition: h264_levels.c:159
int level_idc
Definition: h264_levels.c:25
AVPacket * pkt
Definition: movenc.c:59
AVFormatContext * ctx
Definition: movenc.c:48
#define height
#define width
int size
static void rotate(const float rot_quaternion[2][4], float *vec)
Rotate vector with given rotation quaternion.
Definition: vf_v360.c:3919
static double c[64]