62 "File Format=MacCaption_MCC V%c.0\n" \
64 "///////////////////////////////////////////////////////////////////////////////////\n" \
65 "// Computer Prompting and Captioning Company\n" \
66 "// Ancillary Data Packet Transfer File\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" \
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%s]\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" \
95 "// U E1h 00h 00h 00h\n" \
98 "///////////////////////////////////////////////////////////////////////////////////\n"
100#define MCC_HEADER_PRINTF_ARGS(mcc_version) (mcc_version) + '0', \
101 (mcc_version) == MCC_VERSION_1 ? "" : ", 60DF"
113 { .num = 24, .den = 1 },
114 { .num = 25, .den = 1 },
115 { .num = 30000, .den = 1001 },
116 { .num = 30, .den = 1 },
117 { .num = 50, .den = 1 },
118 { .num = 60000, .den = 1001 },
119 { .num = 60, .den = 1 },
126 if (!creation_program) {
128 creation_program =
"Lavf";
131 }
else if (strchr(creation_program,
'\n')) {
132 av_log(avf,
AV_LOG_FATAL,
"creation_program must not contain multiple lines of text\n");
144 if (!
localtime_r((time_t[1]){ timeval / 1000000 }, &tm))
147 static const char months[12][10] = {
163 const char *month =
months[tm.tm_mon];
165 static const char weekdays[7][10] = {
166 "Sunday",
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday"
170 const char *weekday = weekdays[tm.tm_wday];
175 "Creation Program=%s\n"
176 "Creation Date=%s, %s %d, %d\n"
177 "Creation Time=%02d:%02d:%02d\n"
178 "Time Code Rate=%u%s\n\n",
196static void mcc_bytes_to_hex(
char *dest,
const uint8_t *bytes,
size_t bytes_size,
int use_u_alias)
198 while (bytes_size != 0) {
202 for (
unsigned char code =
'G';
code <= (
unsigned char)
'O';
code++) {
205 if (bytes[0] != 0xFA || bytes[1] != 0 || bytes[2] != 0)
219 if (bytes_size >= 3 && bytes[1] == 0x80 && bytes[2] == 0x80) {
220 *dest++ = bytes[0] - 0xFB +
'P';
227 if (bytes_size >= 2 && bytes[1] == 0x69) {
235 if (bytes_size >= 2 && bytes[1] == 0x01) {
243 if (use_u_alias && bytes_size >= 4 && bytes[1] == 0 && bytes[2] == 0 && bytes[3] == 0) {
260 int v = (bytes[0] >>
shift) & 0xF;
264 *dest++ = v - 0xA +
'A';
288 for (
char *p = timecode_str; *p; p++) {
307 size_t mcc_anc_len = 0;
309 mcc_anc[mcc_anc_len++] = anc.
did;
314 mcc_anc[mcc_anc_len++] = anc.
checksum;
316 unsigned field_number;
329 "Unsupported SMPTE 436M ANC Wrapping Type %#x -- discarding ANC packet\n",
334 char field_and_line[32] =
"";
336 snprintf(field_and_line,
sizeof(field_and_line),
".%u,%u", field_number, (
unsigned)coded_anc.
line_number);
337 }
else if (field_number != 0) {
338 snprintf(field_and_line,
sizeof(field_and_line),
".%u", field_number);
343 if (field_and_line[0] !=
'\0') {
346 "MCC Version 1.0 doesn't support ANC packets where the field number (got %u) isn't 0 and "
347 "line number (got %u) isn't 9: discarding ANC packet\n",
358 char hex[1 + 2 *
sizeof(mcc_anc)];
360 avio_printf(avf->
pb,
"%s%s\t%s\n", timecode_str, field_and_line, hex);
379 int timecode_flags = 0;
396 av_log(avf,
AV_LOG_FATAL,
"time code rate not set, you need to use -override_time_code_rate to set it\n");
400 "time code rate not supported by mcc: %d/%d\n",
409 if (time_code_rate.
den == 1001 && time_code_rate.
num % 30000 == 0) {
419 av_log(avf,
AV_LOG_FATAL,
"MCC Version 1.0 doesn't support 60DF (59.94 fps drop-frame)\n");
433 snprintf(args,
sizeof(args),
"cdp_frame_rate=%d/%d", time_code_rate.
num, time_code_rate.
den);
440 "mcc muxer supports only codec smpte_436m_anc or codec eia_608\n");
449 (void)std_compliance;
455#define OFFSET(x) offsetof(MCCContext, x)
456#define ENC AV_OPT_FLAG_ENCODING_PARAM
459 {
"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 },
460 {
"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 },
469 .class_name =
"mcc muxer",
478 .p.extensions =
"mcc",
simple assert() macros that are a bit more flexible than ISO C assert().
#define av_assert0(cond)
assert() equivalent, that is always enabled.
static const char months[12][4]
int avio_printf(AVIOContext *s, const char *fmt,...) av_printf_format(2
Writes a formatted string to the context.
#define i(width, name, range_min, range_max)
int(* init)(AVBSFContext *ctx)
static int write_packet(Muxer *mux, OutputStream *ost, AVPacket *pkt)
static void write_header(FFV1Context *f)
@ AV_OPT_TYPE_BOOL
Underlying C type is int.
@ 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...
@ AV_OPT_TYPE_UINT
Underlying C type is unsigned int.
AVCodecID
Identify the syntax and semantics of the bitstream.
@ AV_CODEC_ID_SMPTE_436M_ANC
#define AVERROR_EOF
End of file.
#define AV_LOG_WARNING
Something somehow does not look correct.
#define AV_LOG_FATAL
Something went wrong and recovery is not possible.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
const char * av_default_item_name(void *ptr)
Return the context name.
int av_strcasecmp(const char *a, const char *b)
Locale-independent case-insensitive compare.
#define AV_NOPTS_VALUE
Undefined timestamp value.
#define LIBAVUTIL_VERSION_INT
static int query_codec(enum AVCodecID id, int std_compliance)
static int shift(int a, int b)
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Utility Preprocessor macros.
static const struct ValidTimeCodeRate valid_time_code_rates[]
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
static const AVClass mcc_muxer_class
#define MCC_HEADER_PRINTF_ARGS(mcc_version)
static int mcc_query_codec(enum AVCodecID codec_id, int std_compliance)
static int mcc_write_header(AVFormatContext *avf)
static int mcc_init(AVFormatContext *avf)
static const char mcc_ffmpeg_uuid[]
generated with the bash command:
static int mcc_write_packet(AVFormatContext *avf, AVPacket *pkt)
int av_parse_video_rate(AVRational *rate, const char *arg)
Parse str and store the detected values in *rate.
int av_parse_time(int64_t *timeval, const char *timestr, int duration)
Parse timestr and return in *time a corresponding number of microseconds.
Utilities for rational number calculation.
#define FF_ARRAY_ELEMS(a)
int av_smpte_436m_anc_iter_next(AVSmpte436mAncIterator *iter, AVSmpte436mCodedAnc *anc)
Get the next ANC packet from the iterator, advancing the iterator.
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.
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.
#define AV_SMPTE_291M_ANC_PAYLOAD_CAPACITY
the payload capacity of AVSmpte291mAnc8bit (and of AVSmpte291mAnc10bit when that gets added)
@ AV_SMPTE_436M_WRAPPING_TYPE_VANC_FIELD_2
@ AV_SMPTE_436M_WRAPPING_TYPE_VANC_PROGRESSIVE_FRAME
@ AV_SMPTE_436M_WRAPPING_TYPE_VANC_FRAME
@ AV_SMPTE_436M_WRAPPING_TYPE_VANC_FIELD_1
Describe the class of an AVClass context structure.
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
unsigned int nb_streams
Number of elements in AVFormatContext.streams.
AVIOContext * pb
I/O context.
int flags
Flags modifying the (de)muxer behaviour.
void * priv_data
Format private data.
AVStream ** streams
A list of all streams in the file.
This structure stores compressed data.
Rational number (pair of numerator and denominator).
An ANC packet with an 8-bit payload.
uint8_t payload[AV_SMPTE_291M_ANC_PAYLOAD_CAPACITY]
Iterator over the ANC packets in a single AV_CODEC_ID_SMPTE_436M_ANC AVPacket's data.
An encoded ANC packet within a single AV_CODEC_ID_SMPTE_436M_ANC AVPacket's data.
AVSmpte436mWrappingType wrapping_type
AVSmpte436mPayloadSampleCoding payload_sample_coding
uint16_t payload_sample_count
uint8_t payload[AV_SMPTE_436M_CODED_ANC_PAYLOAD_CAPACITY]
the payload, has size payload_array_length.
AVCodecParameters * codecpar
Codec parameters associated with this stream.
AVRational avg_frame_rate
Average framerate.
unsigned fps
frame per second; must be consistent with the rate field
uint32_t flags
flags such as drop frame, +24 hours support, ...
int start
timecode frame start (first base frame number)
char * override_time_code_rate
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.
int av_timecode_init(AVTimecode *tc, AVRational rate, int flags, int frame_start, void *log_ctx)
Init a timecode struct with the passed parameters.
char * av_timecode_make_string(const AVTimecode *tc, char *buf, int framenum_arg)
Load timecode string in buf.
#define AV_TIMECODE_STR_SIZE
@ AV_TIMECODE_FLAG_DROPFRAME
timecode is drop frame