FFmpeg
mccenc.c
Go to the documentation of this file.
1 /*
2  * MCC subtitle muxer
3  * Copyright (c) 2025 Jacob Lifshay
4  * Copyright (c) 2017 Paul B Mahol
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 "avformat.h"
24 #include "internal.h"
25 #include "mux.h"
26 
27 #include "libavcodec/codec_id.h"
28 #include "libavcodec/smpte_436m.h"
29 
30 #include "libavutil/avassert.h"
31 #include "libavutil/avstring.h"
32 #include "libavutil/error.h"
33 #include "libavutil/ffversion.h"
34 #include "libavutil/log.h"
35 #include "libavutil/macros.h"
36 #include "libavutil/opt.h"
37 #include "libavutil/parseutils.h"
38 #include "libavutil/rational.h"
39 #include "libavutil/time_internal.h" // for localtime_r
40 #include "libavutil/timecode.h"
41 
42 typedef struct MCCContext {
43  const AVClass *class;
48  unsigned mcc_version;
51 } MCCContext;
52 
53 typedef enum MCCVersion
54 {
59 } MCCVersion;
60 
61 static const char mcc_header_v1[] = //
62  "File Format=MacCaption_MCC V1.0\n"
63  "\n"
64  "///////////////////////////////////////////////////////////////////////////////////\n"
65  "// Computer Prompting and Captioning Company\n"
66  "// Ancillary Data Packet Transfer File\n"
67  "//\n"
68  "// Permission to generate this format is granted provided that\n"
69  "// 1. This ANC Transfer file format is used on an as-is basis and no warranty is given, and\n"
70  "// 2. This entire descriptive information text is included in a generated .mcc file.\n"
71  "//\n"
72  "// General file format:\n"
73  "// HH:MM:SS:FF(tab)[Hexadecimal ANC data in groups of 2 characters]\n"
74  "// Hexadecimal data starts with the Ancillary Data Packet DID (Data ID defined in S291M)\n"
75  "// and concludes with the Check Sum following the User Data Words.\n"
76  "// Each time code line must contain at most one complete ancillary data packet.\n"
77  "// To transfer additional ANC Data successive lines may contain identical time code.\n"
78  "// Time Code Rate=[24, 25, 30, 30DF, 50, 60]\n"
79  "//\n"
80  "// ANC data bytes may be represented by one ASCII character according to the following schema:\n"
81  "// G FAh 00h 00h\n"
82  "// H 2 x (FAh 00h 00h)\n"
83  "// I 3 x (FAh 00h 00h)\n"
84  "// J 4 x (FAh 00h 00h)\n"
85  "// K 5 x (FAh 00h 00h)\n"
86  "// L 6 x (FAh 00h 00h)\n"
87  "// M 7 x (FAh 00h 00h)\n"
88  "// N 8 x (FAh 00h 00h)\n"
89  "// O 9 x (FAh 00h 00h)\n"
90  "// P FBh 80h 80h\n"
91  "// Q FCh 80h 80h\n"
92  "// R FDh 80h 80h\n"
93  "// S 96h 69h\n"
94  "// T 61h 01h\n"
95  "// U E1h 00h 00h 00h\n"
96  "// Z 00h\n"
97  "//\n"
98  "///////////////////////////////////////////////////////////////////////////////////\n";
99 
100 static const char mcc_header_v2[] = //
101  "File Format=MacCaption_MCC V2.0\n"
102  "\n"
103  "///////////////////////////////////////////////////////////////////////////////////\n"
104  "// Computer Prompting and Captioning Company\n"
105  "// Ancillary Data Packet Transfer File\n"
106  "//\n"
107  "// Permission to generate this format is granted provided that\n"
108  "// 1. This ANC Transfer file format is used on an as-is basis and no warranty is given, and\n"
109  "// 2. This entire descriptive information text is included in a generated .mcc file.\n"
110  "//\n"
111  "// General file format:\n"
112  "// HH:MM:SS:FF(tab)[Hexadecimal ANC data in groups of 2 characters]\n"
113  "// Hexadecimal data starts with the Ancillary Data Packet DID (Data ID defined in S291M)\n"
114  "// and concludes with the Check Sum following the User Data Words.\n"
115  "// Each time code line must contain at most one complete ancillary data packet.\n"
116  "// To transfer additional ANC Data successive lines may contain identical time code.\n"
117  "// Time Code Rate=[24, 25, 30, 30DF, 50, 60, 60DF]\n"
118  "//\n"
119  "// ANC data bytes may be represented by one ASCII character according to the following schema:\n"
120  "// G FAh 00h 00h\n"
121  "// H 2 x (FAh 00h 00h)\n"
122  "// I 3 x (FAh 00h 00h)\n"
123  "// J 4 x (FAh 00h 00h)\n"
124  "// K 5 x (FAh 00h 00h)\n"
125  "// L 6 x (FAh 00h 00h)\n"
126  "// M 7 x (FAh 00h 00h)\n"
127  "// N 8 x (FAh 00h 00h)\n"
128  "// O 9 x (FAh 00h 00h)\n"
129  "// P FBh 80h 80h\n"
130  "// Q FCh 80h 80h\n"
131  "// R FDh 80h 80h\n"
132  "// S 96h 69h\n"
133  "// T 61h 01h\n"
134  "// U E1h 00h 00h 00h\n"
135  "// Z 00h\n"
136  "//\n"
137  "///////////////////////////////////////////////////////////////////////////////////\n";
138 
139 /**
140  * generated with the bash command:
141  * ```bash
142  * URL="https://code.ffmpeg.org/FFmpeg/FFmpeg/src/branch/master/libavformat/mccenc.c"
143  * python3 -c "from uuid import *; print(str(uuid5(NAMESPACE_URL, '$URL')).upper())"
144  * ```
145  */
146 static const char mcc_ffmpeg_uuid[] = "0087C4F6-A6B4-5469-8C8E-BBF44950401D";
147 
149  { .num = 24, .den = 1 },
150  { .num = 25, .den = 1 },
151  { .num = 30000, .den = 1001 },
152  { .num = 30, .den = 1 },
153  { .num = 50, .den = 1 },
154  { .num = 60000, .den = 1001 },
155  { .num = 60, .den = 1 },
156 };
157 
159 {
160  MCCContext *mcc = avf->priv_data;
161  if (avf->nb_streams != 1) {
162  av_log(avf, AV_LOG_ERROR, "mcc muxer supports at most one stream\n");
163  return AVERROR(EINVAL);
164  }
165  avpriv_set_pts_info(avf->streams[0], 64, mcc->timecode.rate.den, mcc->timecode.rate.num);
166  const char *mcc_header = mcc_header_v1;
167  switch ((MCCVersion)mcc->mcc_version) {
168  case MCC_VERSION_1:
169  if (mcc->timecode.fps == 60 && mcc->timecode.flags & AV_TIMECODE_FLAG_DROPFRAME) {
170  av_log(avf, AV_LOG_FATAL, "MCC Version 1.0 doesn't support 60DF (59.94 fps drop-frame)");
171  return AVERROR(EINVAL);
172  }
173  break;
174  case MCC_VERSION_2:
175  mcc_header = mcc_header_v2;
176  break;
177  }
178  const char *creation_program = mcc->creation_program;
179  if (!creation_program) {
180  if (avf->flags & AVFMT_FLAG_BITEXACT)
181  creation_program = "FFmpeg";
182  else
183  creation_program = "FFmpeg version " FFMPEG_VERSION;
184  } else if (strchr(creation_program, '\n')) {
185  av_log(avf, AV_LOG_FATAL, "creation_program must not contain multiple lines of text");
186  return AVERROR(EINVAL);
187  }
188  if (avf->flags & AVFMT_FLAG_BITEXACT && !av_strcasecmp(mcc->creation_time, "now"))
189  av_log(avf, AV_LOG_ERROR, "creation_time must be overridden for bit-exact output");
190  int64_t timeval = 0;
191  int ret = av_parse_time(&timeval, mcc->creation_time, 0);
192  if (ret < 0) {
193  av_log(avf, AV_LOG_FATAL, "can't parse creation_time");
194  return ret;
195  }
196  struct tm tm;
197  if (!localtime_r((time_t[1]){ timeval / 1000000 }, &tm))
198  return AVERROR(EINVAL);
199  // we can't rely on having the C locale, so convert the date/time to a string ourselves:
200  static const char *const months[12] = {
201  "January",
202  "February",
203  "March",
204  "April",
205  "May",
206  "June",
207  "July",
208  "August",
209  "September",
210  "October",
211  "November",
212  "December",
213  };
214  // assert that values are sane so we don't index out of bounds
215  av_assert0(tm.tm_mon >= 0 && tm.tm_mon <= FF_ARRAY_ELEMS(months));
216  const char *month = months[tm.tm_mon];
217 
218  static const char *const weekdays[7] = {
219  "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"
220  };
221  // assert that values are sane so we don't index out of bounds
222  av_assert0(tm.tm_wday >= 0 && tm.tm_wday < FF_ARRAY_ELEMS(weekdays));
223  const char *weekday = weekdays[tm.tm_wday];
224 
225  avio_printf(avf->pb,
226  "%s\n"
227  "UUID=%s\n"
228  "Creation Program=%s\n"
229  "Creation Date=%s, %s %d, %d\n"
230  "Creation Time=%02d:%02d:%02d\n"
231  "Time Code Rate=%u%s\n\n",
232  mcc_header,
234  creation_program,
235  weekday,
236  month,
237  tm.tm_mday,
238  tm.tm_year + 1900,
239  tm.tm_hour,
240  tm.tm_min,
241  tm.tm_sec,
242  mcc->timecode.fps,
243  mcc->timecode.flags & AV_TIMECODE_FLAG_DROPFRAME ? "DF" : "");
244 
245  return 0;
246 }
247 
248 /// convert the input bytes to hexadecimal with mcc's aliases
249 static void mcc_bytes_to_hex(char *dest, const uint8_t *bytes, size_t bytes_size, int use_u_alias)
250 {
251  while (bytes_size != 0) {
252  switch (bytes[0]) {
253  case 0xFA:
254  *dest = '\0';
255  for (unsigned char code = 'G'; code <= (unsigned char)'O'; code++) {
256  if (bytes_size < 3)
257  break;
258  if (bytes[0] != 0xFA || bytes[1] != 0 || bytes[2] != 0)
259  break;
260  *dest = code;
261  bytes += 3;
262  bytes_size -= 3;
263  }
264  if (*dest) {
265  dest++;
266  continue;
267  }
268  break;
269  case 0xFB:
270  case 0xFC:
271  case 0xFD:
272  if (bytes_size >= 3 && bytes[1] == 0x80 && bytes[2] == 0x80) {
273  *dest++ = bytes[0] - 0xFB + 'P';
274  bytes += 3;
275  bytes_size -= 3;
276  continue;
277  }
278  break;
279  case 0x96:
280  if (bytes_size >= 2 && bytes[1] == 0x69) {
281  *dest++ = 'S';
282  bytes += 2;
283  bytes_size -= 2;
284  continue;
285  }
286  break;
287  case 0x61:
288  if (bytes_size >= 2 && bytes[1] == 0x01) {
289  *dest++ = 'T';
290  bytes += 2;
291  bytes_size -= 2;
292  continue;
293  }
294  break;
295  case 0xE1:
296  if (use_u_alias && bytes_size >= 4 && bytes[1] == 0 && bytes[2] == 0 && bytes[3] == 0) {
297  *dest++ = 'U';
298  bytes += 4;
299  bytes_size -= 4;
300  continue;
301  }
302  break;
303  case 0:
304  *dest++ = 'Z';
305  bytes++;
306  bytes_size--;
307  continue;
308  default:
309  // any other bytes falls through to writing hex
310  break;
311  }
312  for (int shift = 4; shift >= 0; shift -= 4) {
313  int v = (bytes[0] >> shift) & 0xF;
314  if (v < 0xA)
315  *dest++ = v + '0';
316  else
317  *dest++ = v - 0xA + 'A';
318  }
319  bytes++;
320  bytes_size--;
321  }
322  *dest = '\0';
323 }
324 
326 {
327  MCCContext *mcc = avf->priv_data;
328  int64_t pts = pkt->pts;
329  int ret;
330 
331  if (pts == AV_NOPTS_VALUE) {
332  av_log(avf, AV_LOG_WARNING, "Insufficient timestamps.\n");
333  return 0;
334  }
335 
336  char timecode_str[AV_TIMECODE_STR_SIZE];
337 
338  // wrap pts values at 24hr ourselves since they can be bigger than fits in an int
339  av_timecode_make_string(&mcc->timecode, timecode_str, pts % mcc->twenty_four_hr);
340 
341  for (char *p = timecode_str; *p; p++) {
342  // .mcc doesn't use ; for drop-frame time codes
343  if (*p == ';')
344  *p = ':';
345  }
346 
349  if (ret < 0)
350  return ret;
351  AVSmpte436mCodedAnc coded_anc;
352  while ((ret = av_smpte_436m_anc_iter_next(&iter, &coded_anc)) >= 0) {
353  AVSmpte291mAnc8bit anc;
355  &anc, coded_anc.payload_sample_coding, coded_anc.payload_sample_count, coded_anc.payload, avf);
356  if (ret < 0)
357  return ret;
358  // 4 for did, sdid_or_dbn, data_count, and checksum fields.
359  uint8_t mcc_anc[4 + AV_SMPTE_291M_ANC_PAYLOAD_CAPACITY];
360  size_t mcc_anc_len = 0;
361 
362  mcc_anc[mcc_anc_len++] = anc.did;
363  mcc_anc[mcc_anc_len++] = anc.sdid_or_dbn;
364  mcc_anc[mcc_anc_len++] = anc.data_count;
365  memcpy(mcc_anc + mcc_anc_len, anc.payload, anc.data_count);
366  mcc_anc_len += anc.data_count;
367  mcc_anc[mcc_anc_len++] = anc.checksum;
368 
369  unsigned field_number;
370  switch (coded_anc.wrapping_type) {
374  field_number = 0;
375  break;
377  field_number = 1;
378  break;
379  default:
380  av_log(avf,
382  "Unsupported SMPTE 436M ANC Wrapping Type %#x -- discarding ANC packet",
383  (unsigned)coded_anc.wrapping_type);
384  continue;
385  }
386 
387  char field_and_line[32] = "";
388  if (coded_anc.line_number != 9) {
389  snprintf(field_and_line, sizeof(field_and_line), ".%u,%u", field_number, (unsigned)coded_anc.line_number);
390  } else if (field_number != 0) {
391  snprintf(field_and_line, sizeof(field_and_line), ".%u", field_number);
392  }
393 
394  switch ((MCCVersion)mcc->mcc_version) {
395  case MCC_VERSION_1:
396  if (field_and_line[0] != '\0') {
397  av_log(avf,
399  "MCC Version 1.0 doesn't support ANC packets where the field number (got %u) isn't 0 and "
400  "line number (got %u) isn't 9: discarding ANC packet",
401  field_number,
402  (unsigned)coded_anc.line_number);
403  continue;
404  }
405  break;
406  case MCC_VERSION_2:
407  break;
408  }
409 
410  // 1 for terminating nul. 2 since there's 2 hex digits per byte.
411  char hex[1 + 2 * sizeof(mcc_anc)];
412  mcc_bytes_to_hex(hex, mcc_anc, mcc_anc_len, mcc->use_u_alias);
413  avio_printf(avf->pb, "%s%s\t%s\n", timecode_str, field_and_line, hex);
414  }
415  if (ret != AVERROR_EOF)
416  return ret;
417  return 0;
418 }
419 
420 static int mcc_init(AVFormatContext *avf)
421 {
422  MCCContext *mcc = avf->priv_data;
423  int ret;
424 
425  if (avf->nb_streams != 1) {
426  av_log(avf, AV_LOG_ERROR, "mcc muxer supports at most one stream\n");
427  return AVERROR(EINVAL);
428  }
429 
430  AVStream *st = avf->streams[0];
431  AVRational time_code_rate = st->avg_frame_rate;
432  int timecode_flags = 0;
433  AVTimecode twenty_four_hr;
434 
435  if (mcc->override_time_code_rate && (ret = av_parse_video_rate(&time_code_rate, mcc->override_time_code_rate)) < 0)
436  return ret;
437 
438  ret = AVERROR(EINVAL);
439 
440  for (size_t i = 0; i < FF_ARRAY_ELEMS(valid_time_code_rates); i++) {
441  if (time_code_rate.num == valid_time_code_rates[i].num && time_code_rate.den == valid_time_code_rates[i].den) {
442  ret = 0;
443  break;
444  }
445  }
446 
447  if (ret != 0) {
448  if (!mcc->override_time_code_rate && (time_code_rate.num <= 0 || time_code_rate.den <= 0)) {
449  av_log(avf, AV_LOG_FATAL, "time code rate not set, you need to use -override_time_code_rate to set it\n");
450  } else {
451  av_log(avf,
452  AV_LOG_FATAL,
453  "time code rate not supported by mcc: %d/%d\n",
454  time_code_rate.num,
455  time_code_rate.den);
456  }
457  return AVERROR(EINVAL);
458  }
459 
460  avpriv_set_pts_info(st, 64, time_code_rate.den, time_code_rate.num);
461 
462  if (time_code_rate.den == 1001 && time_code_rate.num % 30000 == 0) {
463  timecode_flags |= AV_TIMECODE_FLAG_DROPFRAME;
464  }
465 
466  ret = av_timecode_init(&mcc->timecode, time_code_rate, timecode_flags, 0, avf);
467  if (ret < 0)
468  return ret;
469 
470  // get av_timecode to calculate how many frames are in 24hr
471  ret = av_timecode_init_from_components(&twenty_four_hr, time_code_rate, timecode_flags, 24, 0, 0, 0, avf);
472  if (ret < 0)
473  return ret;
474 
475  mcc->twenty_four_hr = twenty_four_hr.start;
476 
477  if (st->codecpar->codec_id == AV_CODEC_ID_EIA_608) {
478  char args[64];
479  snprintf(args, sizeof(args), "cdp_frame_rate=%d/%d", time_code_rate.num, time_code_rate.den);
480  ret = ff_stream_add_bitstream_filter(st, "eia608_to_smpte436m", args);
481  if (ret < 0)
482  return ret;
483  } else if (st->codecpar->codec_id != AV_CODEC_ID_SMPTE_436M_ANC) {
484  av_log(avf,
485  AV_LOG_ERROR,
486  "mcc muxer supports only codec %s or codec %s\n",
489  return AVERROR(EINVAL);
490  }
491 
492  return 0;
493 }
494 
495 static int mcc_query_codec(enum AVCodecID codec_id, int std_compliance)
496 {
497  (void)std_compliance;
499  return 1;
500  return 0;
501 }
502 
503 #define OFFSET(x) offsetof(MCCContext, x)
504 #define ENC AV_OPT_FLAG_ENCODING_PARAM
505 // clang-format off
506 static const AVOption options[] = {
507  { "override_time_code_rate", "override the `Time Code Rate` value in the output", OFFSET(override_time_code_rate), AV_OPT_TYPE_STRING, { .str = NULL }, 0, INT_MAX, ENC },
508  { "use_u_alias", "use the U alias for E1h 00h 00h 00h, disabled by default because some .mcc files disagree on whether it has 2 or 3 zero bytes", OFFSET(use_u_alias), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, ENC },
509  { "mcc_version", "the mcc file format version", OFFSET(mcc_version), AV_OPT_TYPE_UINT, { .i64 = MCC_VERSION_2 }, MCC_VERSION_MIN, MCC_VERSION_MAX, ENC },
510  { "creation_program", "the creation program", OFFSET(creation_program), AV_OPT_TYPE_STRING, { .str = NULL }, 0, INT_MAX, ENC },
511  { "creation_time", "the creation time", OFFSET(creation_time), AV_OPT_TYPE_STRING, { .str = "now" }, 0, INT_MAX, ENC },
512  { NULL },
513 };
514 // clang-format on
515 
516 static const AVClass mcc_muxer_class = {
517  .class_name = "mcc muxer",
518  .item_name = av_default_item_name,
519  .option = options,
520  .version = LIBAVUTIL_VERSION_INT,
521 };
522 
524  .p.name = "mcc",
525  .p.long_name = NULL_IF_CONFIG_SMALL("MacCaption"),
526  .p.extensions = "mcc",
527  .p.flags = AVFMT_GLOBALHEADER,
528  .p.video_codec = AV_CODEC_ID_NONE,
529  .p.audio_codec = AV_CODEC_ID_NONE,
530  .p.subtitle_codec = AV_CODEC_ID_EIA_608,
531  .p.priv_class = &mcc_muxer_class,
532  .priv_data_size = sizeof(MCCContext),
533  .init = mcc_init,
537 };
AV_CODEC_ID_EIA_608
@ AV_CODEC_ID_EIA_608
Definition: codec_id.h:572
ff_mcc_muxer
const FFOutputFormat ff_mcc_muxer
Definition: mccenc.c:523
AV_SMPTE_436M_WRAPPING_TYPE_VANC_FIELD_1
@ AV_SMPTE_436M_WRAPPING_TYPE_VANC_FIELD_1
Definition: smpte_436m.h:43
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:216
AV_TIMECODE_STR_SIZE
#define AV_TIMECODE_STR_SIZE
Definition: timecode.h:33
AVOutputFormat::name
const char * name
Definition: avformat.h:506
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
opt.h
AV_SMPTE_436M_WRAPPING_TYPE_VANC_PROGRESSIVE_FRAME
@ AV_SMPTE_436M_WRAPPING_TYPE_VANC_PROGRESSIVE_FRAME
Definition: smpte_436m.h:45
MCC_VERSION_MIN
@ MCC_VERSION_MIN
Definition: mccenc.c:57
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:57
AVSmpte291mAnc8bit::checksum
uint8_t checksum
Definition: smpte_436m.h:103
rational.h
int64_t
long long int64_t
Definition: coverity.c:34
av_strcasecmp
int av_strcasecmp(const char *a, const char *b)
Locale-independent case-insensitive compare.
Definition: avstring.c:208
AVFormatContext::streams
AVStream ** streams
A list of all streams in the file.
Definition: avformat.h:1332
ENC
#define ENC
Definition: mccenc.c:504
AVPacket::data
uint8_t * data
Definition: packet.h:552
AVOption
AVOption.
Definition: opt.h:429
AVStream::avg_frame_rate
AVRational avg_frame_rate
Average framerate.
Definition: avformat.h:833
AVTimecode::flags
uint32_t flags
flags such as drop frame, +24 hours support, ...
Definition: timecode.h:43
AVSmpte436mCodedAnc::payload_sample_count
uint16_t payload_sample_count
Definition: smpte_436m.h:121
av_smpte_436m_anc_iter_next
int av_smpte_436m_anc_iter_next(AVSmpte436mAncIterator *iter, AVSmpte436mCodedAnc *anc)
Get the next ANC packet from the iterator, advancing the iterator.
Definition: smpte_436m.c:250
mcc_muxer_class
static const AVClass mcc_muxer_class
Definition: mccenc.c:516
AVSmpte436mCodedAnc::wrapping_type
AVSmpte436mWrappingType wrapping_type
Definition: smpte_436m.h:119
FFOutputFormat::p
AVOutputFormat p
The public AVOutputFormat.
Definition: mux.h:65
mcc_bytes_to_hex
static void mcc_bytes_to_hex(char *dest, const uint8_t *bytes, size_t bytes_size, int use_u_alias)
convert the input bytes to hexadecimal with mcc's aliases
Definition: mccenc.c:249
MCCContext
Definition: mccdec.c:43
mcc_header_v1
static const char mcc_header_v1[]
Definition: mccenc.c:61
MCCContext::creation_program
char * creation_program
Definition: mccenc.c:49
avpriv_set_pts_info
void avpriv_set_pts_info(AVStream *st, int pts_wrap_bits, unsigned int pts_num, unsigned int pts_den)
Set the time base and wrapping info for a given stream.
Definition: avformat.c:777
options
static const AVOption options[]
Definition: mccenc.c:506
MCCContext::twenty_four_hr
int64_t twenty_four_hr
Definition: mccenc.c:45
mcc_header_v2
static const char mcc_header_v2[]
Definition: mccenc.c:100
macros.h
timecode.h
AVTimecode::start
int start
timecode frame start (first base frame number)
Definition: timecode.h:42
query_codec
static int query_codec(enum AVCodecID id, int std_compliance)
Definition: img2enc.c:260
pts
static int64_t pts
Definition: transcode_aac.c:644
AVRational::num
int num
Numerator.
Definition: rational.h:59
avassert.h
AVSmpte291mAnc8bit::payload
uint8_t payload[AV_SMPTE_291M_ANC_PAYLOAD_CAPACITY]
Definition: smpte_436m.h:102
pkt
AVPacket * pkt
Definition: movenc.c:60
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:210
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
codec_id.h
av_timecode_init
int av_timecode_init(AVTimecode *tc, AVRational rate, int flags, int frame_start, void *log_ctx)
Init a timecode struct with the passed parameters.
Definition: timecode.c:201
av_smpte_291m_anc_8bit_decode
int av_smpte_291m_anc_8bit_decode(AVSmpte291mAnc8bit *out, AVSmpte436mPayloadSampleCoding sample_coding, uint16_t sample_count, const uint8_t *payload, void *log_ctx)
Decode a AVSmpte436mCodedAnc payload into AVSmpte291mAnc8bit.
Definition: smpte_436m.c:295
AVFormatContext::flags
int flags
Flags modifying the (de)muxer behaviour.
Definition: avformat.h:1415
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:41
codec_id
enum AVCodecID codec_id
Definition: vaapi_decode.c:410
av_smpte_436m_anc_iter_init
int av_smpte_436m_anc_iter_init(AVSmpte436mAncIterator *iter, const uint8_t *buf, int buf_size)
Set up iteration over the ANC packets in a single AV_CODEC_ID_SMPTE_436M_ANC AVPacket's data.
Definition: smpte_436m.c:234
smpte_436m.h
MCCContext::mcc_version
unsigned mcc_version
Definition: mccenc.c:48
time_internal.h
AVFormatContext
Format I/O context.
Definition: avformat.h:1264
AVSmpte436mCodedAnc::line_number
uint16_t line_number
Definition: smpte_436m.h:118
internal.h
AVStream::codecpar
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:767
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:76
NULL
#define NULL
Definition: coverity.c:32
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
AVSmpte291mAnc8bit::sdid_or_dbn
uint8_t sdid_or_dbn
Definition: smpte_436m.h:100
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:241
AVFormatContext::pb
AVIOContext * pb
I/O context.
Definition: avformat.h:1306
parseutils.h
options
Definition: swscale.c:43
AVTimecode::fps
unsigned fps
frame per second; must be consistent with the rate field
Definition: timecode.h:45
FFOutputFormat
Definition: mux.h:61
av_parse_time
int av_parse_time(int64_t *timeval, const char *timestr, int duration)
Parse timestr and return in *time a corresponding number of microseconds.
Definition: parseutils.c:592
AV_OPT_TYPE_UINT
@ AV_OPT_TYPE_UINT
Underlying C type is unsigned int.
Definition: opt.h:335
AVTimecode::rate
AVRational rate
frame rate in rational form
Definition: timecode.h:44
MCCVersion
MCCVersion
Definition: mccenc.c:53
error.h
AVCodecID
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition: codec_id.h:49
AVFormatContext::nb_streams
unsigned int nb_streams
Number of elements in AVFormatContext.streams.
Definition: avformat.h:1320
av_timecode_init_from_components
int av_timecode_init_from_components(AVTimecode *tc, AVRational rate, int flags, int hh, int mm, int ss, int ff, void *log_ctx)
Init a timecode struct from the passed timecode components.
Definition: timecode.c:211
init
int(* init)(AVBSFContext *ctx)
Definition: dts2pts.c:368
MCC_VERSION_2
@ MCC_VERSION_2
Definition: mccenc.c:56
AVPacket::size
int size
Definition: packet.h:553
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:94
AV_SMPTE_436M_WRAPPING_TYPE_VANC_FIELD_2
@ AV_SMPTE_436M_WRAPPING_TYPE_VANC_FIELD_2
Definition: smpte_436m.h:44
shift
static int shift(int a, int b)
Definition: bonk.c:261
localtime_r
#define localtime_r
Definition: time_internal.h:46
months
static const char months[12][4]
Definition: avidec.c:348
valid_time_code_rates
static AVRational valid_time_code_rates[]
Definition: mccenc.c:148
AV_NOPTS_VALUE
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:247
MCC_VERSION_MAX
@ MCC_VERSION_MAX
Definition: mccenc.c:58
mcc_init
static int mcc_init(AVFormatContext *avf)
Definition: mccenc.c:420
OFFSET
#define OFFSET(x)
Definition: mccenc.c:503
AVSmpte436mCodedAnc
An encoded ANC packet within a single AV_CODEC_ID_SMPTE_436M_ANC AVPacket's data.
Definition: smpte_436m.h:117
avcodec_get_name
const char * avcodec_get_name(enum AVCodecID id)
Get the name of a codec.
Definition: utils.c:406
AVSmpte291mAnc8bit
An ANC packet with an 8-bit payload.
Definition: smpte_436m.h:98
av_parse_video_rate
int av_parse_video_rate(AVRational *rate, const char *arg)
Parse str and store the detected values in *rate.
Definition: parseutils.c:181
mcc_write_header
static int mcc_write_header(AVFormatContext *avf)
Definition: mccenc.c:158
mcc_ffmpeg_uuid
static const char mcc_ffmpeg_uuid[]
generated with the bash command:
Definition: mccenc.c:146
MCCContext::override_time_code_rate
char * override_time_code_rate
Definition: mccenc.c:46
log.h
AVFMT_GLOBALHEADER
#define AVFMT_GLOBALHEADER
Format wants global header.
Definition: avformat.h:477
AV_CODEC_ID_NONE
@ AV_CODEC_ID_NONE
Definition: codec_id.h:50
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
AVPacket::pts
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: packet.h:545
code
and forward the test the status of outputs and forward it to the corresponding return FFERROR_NOT_READY If the filters stores internally one or a few frame for some it can consider them to be part of the FIFO and delay acknowledging a status change accordingly Example code
Definition: filter_design.txt:178
mcc_write_packet
static int mcc_write_packet(AVFormatContext *avf, AVPacket *pkt)
Definition: mccenc.c:325
AV_CODEC_ID_SMPTE_436M_ANC
@ AV_CODEC_ID_SMPTE_436M_ANC
Definition: codec_id.h:606
write_packet
static int write_packet(Muxer *mux, OutputStream *ost, AVPacket *pkt)
Definition: ffmpeg_mux.c:209
AV_TIMECODE_FLAG_DROPFRAME
@ AV_TIMECODE_FLAG_DROPFRAME
timecode is drop frame
Definition: timecode.h:36
AVSmpte436mCodedAnc::payload
uint8_t payload[AV_SMPTE_436M_CODED_ANC_PAYLOAD_CAPACITY]
the payload, has size payload_array_length.
Definition: smpte_436m.h:126
ret
ret
Definition: filter_design.txt:187
AVFMT_FLAG_BITEXACT
#define AVFMT_FLAG_BITEXACT
When muxing, try to avoid writing any random/volatile data to the output.
Definition: avformat.h:1432
AVStream
Stream structure.
Definition: avformat.h:744
AV_LOG_FATAL
#define AV_LOG_FATAL
Something went wrong and recovery is not possible.
Definition: log.h:204
AVClass::class_name
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:81
MCCContext::creation_time
char * creation_time
Definition: mccenc.c:50
avformat.h
avio_printf
int avio_printf(AVIOContext *s, const char *fmt,...) av_printf_format(2
Writes a formatted string to the context.
AVRational::den
int den
Denominator.
Definition: rational.h:60
AVSmpte436mAncIterator
Iterator over the ANC packets in a single AV_CODEC_ID_SMPTE_436M_ANC AVPacket's data.
Definition: smpte_436m.h:30
AV_SMPTE_291M_ANC_PAYLOAD_CAPACITY
#define AV_SMPTE_291M_ANC_PAYLOAD_CAPACITY
the payload capacity of AVSmpte291mAnc8bit (and of AVSmpte291mAnc10bit when that gets added)
Definition: smpte_436m.h:89
AVSmpte291mAnc8bit::data_count
uint8_t data_count
Definition: smpte_436m.h:101
MCCContext::use_u_alias
int use_u_alias
Definition: mccenc.c:47
AV_SMPTE_436M_WRAPPING_TYPE_VANC_FRAME
@ AV_SMPTE_436M_WRAPPING_TYPE_VANC_FRAME
Definition: smpte_436m.h:42
mcc_query_codec
static int mcc_query_codec(enum AVCodecID codec_id, int std_compliance)
Definition: mccenc.c:495
AVCodecParameters::codec_id
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition: codec_par.h:55
AVPacket
This structure stores compressed data.
Definition: packet.h:529
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Underlying C type is int.
Definition: opt.h:327
AVSmpte436mCodedAnc::payload_sample_coding
AVSmpte436mPayloadSampleCoding payload_sample_coding
Definition: smpte_436m.h:120
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
avstring.h
AV_OPT_TYPE_STRING
@ AV_OPT_TYPE_STRING
Underlying C type is a uint8_t* that is either NULL or points to a C string allocated with the av_mal...
Definition: opt.h:276
write_header
static void write_header(FFV1Context *f)
Definition: ffv1enc.c:384
MCC_VERSION_1
@ MCC_VERSION_1
Definition: mccenc.c:55
AVTimecode
Definition: timecode.h:41
snprintf
#define snprintf
Definition: snprintf.h:34
AVFormatContext::priv_data
void * priv_data
Format private data.
Definition: avformat.h:1292
ff_stream_add_bitstream_filter
int ff_stream_add_bitstream_filter(AVStream *st, const char *name, const char *args)
Add a bitstream filter to a stream.
Definition: mux.c:1294
av_timecode_make_string
char * av_timecode_make_string(const AVTimecode *tc, char *buf, int framenum_arg)
Load timecode string in buf.
Definition: timecode.c:104
AVSmpte291mAnc8bit::did
uint8_t did
Definition: smpte_436m.h:99
MCCContext::timecode
AVTimecode timecode
Definition: mccenc.c:44
mux.h