/
matroska.h
281 lines (250 loc) · 9.75 KB
/
matroska.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
#ifndef MATROSKA_H
#define MATROSKA_H
#define MIN(X, Y) (((X) < (Y)) ? (X) : (Y))
/* Output specificators */
#if (defined (WIN32) || defined (_WIN32_WCE)) && (defined(__MINGW32__) || !defined(__GNUC__))
#define LLD_M "I64d"
#define LLU_M "I64u"
#define LLD "%I64d"
#define LLU "%I64u"
#elif defined (__SYMBIAN32__)
#define LLD_M "d"
#define LLU_M "u"
#define LLD "%d"
#define LLU "%u"
#elif defined(__DARWIN__) || defined(__APPLE__)
#define LLD_M "lld"
#define LLU_M "llu"
#define LLD "%lld"
#define LLU "%llu"
#elif defined(_LP64) /* Unix 64 bits */
#define LLD_M "ld"
#define LLU_M "lu"
#define LLD "%ld"
#define LLU "%lu"
#else /* Unix 32 bits */
#define LLD_M "lld"
#define LLU_M "llu"
#define LLD "%lld"
#define LLU "%llu"
#endif
/* EBML header ids */
#define MATROSKA_EBML_HEADER 0x1A45DFA3
#define MATROSKA_EBML_VERSION 0x4286
#define MATROSKA_EBML_READ_VERSION 0x42F7
#define MATROSKA_EBML_MAX_ID_LENGTH 0x42F2
#define MATROSKA_EBML_MAX_SIZE_LENGTH 0x42F3
#define MATROSKA_EBML_DOC_TYPE 0x4282
#define MATROSKA_EBML_DOC_TYPE_VERSION 0x4287
#define MATROSKA_EBML_DOC_TYPE_READ_VERSION 0x4285
/* Segment ids */
#define MATROSKA_SEGMENT_HEADER 0x18538067
#define MATROSKA_SEGMENT_SEEK_HEAD 0x114D9B74
#define MATROSKA_SEGMENT_INFO 0x1549A966
#define MATROSKA_SEGMENT_CLUSTER 0x1F43B675
#define MATROSKA_SEGMENT_TRACKS 0x1654AE6B
#define MATROSKA_SEGMENT_CUES 0x1C53BB6B
#define MATROSKA_SEGMENT_ATTACHMENTS 0x1941A469
#define MATROSKA_SEGMENT_CHAPTERS 0x1043A770
#define MATROSKA_SEGMENT_TAGS 0x1254C367
/* Segment info ids */
#define MATROSKA_SEGMENT_INFO_SEGMENT_UID 0x73A4
#define MATROSKA_SEGMENT_INFO_SEGMENT_FILENAME 0x7384
#define MATROSKA_SEGMENT_INFO_PREV_UID 0x3CB923
#define MATROSKA_SEGMENT_INFO_PREV_FILENAME 0x3C83AB
#define MATROSKA_SEGMENT_INFO_NEXT_UID 0x3EB923
#define MATROSKA_SEGMENT_INFO_NEXT_FILENAME 0x3E83BB
#define MATROSKA_SEGMENT_INFO_SEGMENT_FAMILY 0x4444
#define MATROSKA_SEGMENT_INFO_CHAPTER_TRANSLATE 0x6924
#define MATROSKA_SEGMENT_INFO_TIMECODE_SCALE 0x2AD7B1
#define MATROSKA_SEGMENT_INFO_DURATION 0x4489
#define MATROSKA_SEGMENT_INFO_DATE_UTC 0x4461
#define MATROSKA_SEGMENT_INFO_TITLE 0x7BA9
#define MATROSKA_SEGMENT_MUXING_APP 0x4D80
#define MATROSKA_SEGMENT_WRITING_APP 0x5741
/* Segment cluster ids */
#define MATROSKA_SEGMENT_CLUSTER_TIMECODE 0xE7
#define MATROSKA_SEGMENT_CLUSTER_SILENT_TRACKS 0x5854
#define MATROSKA_SEGMENT_CLUSTER_POSITION 0xA7
#define MATROSKA_SEGMENT_CLUSTER_PREV_SIZE 0xAB
#define MATROSKA_SEGMENT_CLUSTER_SIMPLE_BLOCK 0xA3
#define MATROSKA_SEGMENT_CLUSTER_ENCRYPTED_BLOCK 0xAF
/* Segment cluster block group ids */
#define MATROSKA_SEGMENT_CLUSTER_BLOCK_GROUP 0xA0
#define MATROSKA_SEGMENT_CLUSTER_BLOCK_GROUP_BLOCK 0xA1
#define MATROSKA_SEGMENT_CLUSTER_BLOCK_GROUP_BLOCK_VIRTUAL 0xA2
#define MATROSKA_SEGMENT_CLUSTER_BLOCK_GROUP_BLOCK_ADDITIONS 0x75A1
#define MATROSKA_SEGMENT_CLUSTER_BLOCK_GROUP_BLOCK_DURATION 0x9B
#define MATROSKA_SEGMENT_CLUSTER_BLOCK_GROUP_REFERENCE_PRIORITY 0xFA
#define MATROSKA_SEGMENT_CLUSTER_BLOCK_GROUP_REFERENCE_BLOCK 0xFB
#define MATROSKA_SEGMENT_CLUSTER_BLOCK_GROUP_CODEC_STATE 0xA4
#define MATROSKA_SEGMENT_CLUSTER_BLOCK_GROUP_DISCARD_PADDING 0x75A2
#define MATROSKA_SEGMENT_CLUSTER_BLOCK_GROUP_SLICES 0x8E
#define MATROSKA_SEGMENT_CLUSTER_BLOCK_GROUP_REFERENCE_FRAME 0xC8
/* Segment tracks ids */
#define MATROSKA_SEGMENT_TRACK_ENTRY 0xAE
#define MATROSKA_SEGMENT_TRACK_TRACK_NUMBER 0xD7
#define MATROSKA_SEGMENT_TRACK_TRACK_UID 0x73C5
#define MATROSKA_SEGMENT_TRACK_TRACK_TYPE 0x83
#define MATROSKA_SEGMENT_TRACK_FLAG_ENABLED 0xB9
#define MATROSKA_SEGMENT_TRACK_FLAG_DEFAULT 0x88
#define MATROSKA_SEGMENT_TRACK_FLAG_FORCED 0x55AA
#define MATROSKA_SEGMENT_TRACK_FLAG_LACING 0x9C
#define MATROSKA_SEGMENT_TRACK_MIN_CACHE 0x6DE7
#define MATROSKA_SEGMENT_TRACK_MAX_CACHE 0x6DF8
#define MATROSKA_SEGMENT_TRACK_DEFAULT_DURATION 0x23E383
#define MATROSKA_SEGMENT_TRACK_DEFAULT_DECODED_FIELD_DURATION 0x234E7A
#define MATROSKA_SEGMENT_TRACK_MAX_BLOCK_ADDITION_ID 0x55EE
#define MATROSKA_SEGMENT_TRACK_NAME 0x536E
#define MATROSKA_SEGMENT_TRACK_LANGUAGE 0x22B59C
#define MATROSKA_SEGMENT_TRACK_CODEC_ID 0x86
#define MATROSKA_SEGMENT_TRACK_CODEC_PRIVATE 0x63A2
#define MATROSKA_SEGMENT_TRACK_CODEC_NAME 0x258688
#define MATROSKA_SEGMENT_TRACK_CODEC_ATTACHMENT_LINK 0x7446
#define MATROSKA_SEGMENT_TRACK_CODEC_DECODE_ALL 0xAA
#define MATROSKA_SEGMENT_TRACK_TRACK_OVERLAY 0x6FAB
#define MATROSKA_SEGMENT_TRACK_CODEC_DELAY 0x56AA
#define MATROSKA_SEGMENT_TRACK_SEEK_PRE_ROLL 0x56BB
#define MATROSKA_SEGMENT_TRACK_TRACK_TRANSLATE 0x6624
#define MATROSKA_SEGMENT_TRACK_VIDEO 0xE0
#define MATROSKA_SEGMENT_TRACK_AUDIO 0xE1
#define MATROSKA_SEGMENT_TRACK_TRACK_OPERATION 0xE2
#define MATROSKA_SEGMENT_TRACK_CONTENT_ENCODINGS 0x6D80
/* Misc ids */
#define MATROSKA_VOID 0xEC
#define MATROSKA_CRC32 0xBF
/* DEFENCE FROM THE FOOL - deprecated IDs */
#define MATROSKA_SEGMENT_TRACK_TRACK_TIMECODE_SCALE 0x23314F
#define MATROSKA_SEGMENT_TRACK_TRACK_OFFSET 0x537F
/* DivX trick track extenstions (in track entry) */
#define MATROSKA_SEGMENT_TRACK_TRICK_TRACK_UID 0xC0
#define MATROSKA_SEGMENT_TRACK_TRICK_TRACK_SEGMENT_UID 0xC1
#define MATROSKA_SEGMENT_TRACK_TRICK_TRACK_FLAG 0xC6
#define MATROSKA_SEGMENT_TRACK_TRICK_MASTER_TRACK_UID 0xC7
#define MATROSKA_SEGMENT_TRACK_TRICK_MASTER_TRACK_SEGMENT_UID 0xC4
/* Other defines */
#define MATROSKA_MAX_ID_LENGTH 4
#define MAX_FILE_NAME_SIZE 260
/* Enums */
enum matroska_track_entry_type {
MATROSKA_TRACK_TYPE_VIDEO = 1,
MATROSKA_TRACK_TYPE_AUDIO = 2,
MATROSKA_TRACK_TYPE_COMPLEX = 3,
MATROSKA_TRACK_TYPE_LOGO = 0x10,
MATROSKA_TRACK_TYPE_SUBTITLE = 0x11,
MATROSKA_TRACK_TYPE_BUTTONS = 0x12,
MATROSKA_TRACK_TYPE_CONTROL = 0x20,
};
enum matroska_track_subtitle_codec_id {
MATROSKA_TRACK_SUBTITLE_CODEC_ID_UTF8 = 0,
MATROSKA_TRACK_SUBTITLE_CODEC_ID_SSA,
MATROSKA_TRACK_SUBTITLE_CODEC_ID_ASS,
MATROSKA_TRACK_SUBTITLE_CODEC_ID_USF,
MATROSKA_TRACK_SUBTITLE_CODEC_ID_WEBVTT,
MATROSKA_TRACK_SUBTITLE_CODEC_ID_BITMAP,
MATROSKA_TRACK_SUBTITLE_CODEC_ID_VOBSUB,
MATROSKA_TRACK_SUBTITLE_CODEC_ID_KATE
};
char* matroska_track_text_subtitle_id_strings[] = {
"S_TEXT/UTF8",
"S_TEXT/SSA",
"S_TEXT/ASS",
"S_TEXT/USF",
"S_TEXT/WEBVTT",
"S_IMAGE/BMP",
"S_VOBSUB",
"S_KATE"
};
char* matroska_track_text_subtitle_id_extensions[] = {
"srt", "ssa", "ass",
"usf", "vtt", "bmp",
NULL, NULL // Unknown
};
char* avc_codec_id = "V_MPEG4/ISO/AVC";
/* Messages */
#define MATROSKA_INFO "\nMatroska parser info: "
#define MATROSKA_WARNING "\nMatroska parser warning: "
#define MATROSKA_ERROR "\nMatroska parser error: "
/* Boilerplate code */
#define MATROSKA_SWITCH_BREAK(a,b) (a)=0;(b)=0;break
/* Structures */
struct block_addition {
char* cue_settings_list;
ULLONG cue_settings_list_size;
char* cue_identifier;
ULLONG cue_identifier_size;
char* comment;
ULLONG comment_size;
};
struct matroska_sub_sentence {
char* text;
ULLONG text_size;
ULLONG time_start;
ULLONG time_end;
struct block_addition* blockaddition;
};
struct matroska_avc_frame {
UBYTE *data;
ULLONG len;
ULLONG FTS;
};
struct matroska_sub_track {
char* header; // Style header for ASS/SSA (and other) subtitles
char* lang;
ULLONG track_number;
ULLONG lang_index;
enum matroska_track_subtitle_codec_id codec_id;
int sentence_count;
struct matroska_sub_sentence** sentences;
};
struct matroska_ctx {
struct matroska_sub_track** sub_tracks;
struct lib_ccx_ctx* ctx;
struct cc_subtitle dec_sub;
int avc_track_number; // ID of AVC track. -1 if there is none
int sub_tracks_count;
int block_index;
int sentence_count;
char* filename;
ULLONG current_second;
FILE* file;
};
/* Bytestream and parser functions */
void skip_bytes(FILE* file, ULLONG n);
void set_bytes(FILE* file, ULLONG n);
ULLONG get_current_byte(FILE* file);
UBYTE* read_byte_block(FILE* file, ULLONG n);
char* read_bytes_signed(FILE* file, ULLONG n);
UBYTE mkv_read_byte(FILE* file);
ULLONG read_vint_length(FILE* file);
UBYTE* read_vint_block(FILE* file);
char* read_vint_block_signed(FILE* file);
ULLONG read_vint_block_int(FILE* file);
char* read_vint_block_string(FILE* file);
void read_vint_block_skip(FILE* file);
void parse_ebml(FILE* file);
void parse_segment_info(FILE* file);
struct matroska_sub_sentence* parse_segment_cluster_block_group_block(struct matroska_ctx* mkv_ctx, ULLONG cluster_timecode);
void parse_segment_cluster_block_group(struct matroska_ctx* mkv_ctx, ULLONG cluster_timecode);
void parse_segment_cluster(struct matroska_ctx* mkv_ctx);
void parse_simple_block(struct matroska_ctx* mkv_ctx, ULLONG frame_timestamp);
int process_avc_frame_mkv(struct matroska_ctx* mkv_ctx, struct matroska_avc_frame frame);
void parse_segment_track_entry(struct matroska_ctx* mkv_ctx);
void parse_private_codec_data(struct matroska_ctx* mkv_ctx);
void parse_segment_tracks(struct matroska_ctx* mkv_ctx);
void parse_segment(struct matroska_ctx* mkv_ctx);
/* Writing and helper functions */
char* generate_timestamp_utf8(ULLONG milliseconds);
char* generate_timestamp_ass_ssa(ULLONG milliseconds);
int find_sub_track_index(struct matroska_ctx* mkv_ctx, ULLONG track_number);
char* get_track_entry_type_description(enum matroska_track_entry_type type);
enum matroska_track_subtitle_codec_id get_track_subtitle_codec_id(char* codec_id);
char* generate_filename_from_track(struct matroska_ctx* mkv_ctx, struct matroska_sub_track* track);
char* ass_ssa_sentence_erase_read_order(char* text);
void save_sub_track(struct matroska_ctx* mkv_ctx, struct matroska_sub_track* track);
void free_sub_track(struct matroska_sub_track* track);
void matroska_save_all(struct matroska_ctx* mkv_ctx,char* lang);
void matroska_free_all(struct matroska_ctx* mkv_ctx);
void matroska_parse(struct matroska_ctx* mkv_ctx);
FILE* create_file(struct lib_ccx_ctx *ctx);
#endif // MATROSKA_H