52 .offset = offsetof(
ASS, script_info),
61 { .section =
"V4+ Styles",
62 .format_header =
"Format",
63 .fields_header =
"Style",
66 .offset_count = offsetof(
ASS, styles_count),
93 { .section =
"V4 Styles",
94 .format_header =
"Format",
95 .fields_header =
"Style",
98 .offset_count = offsetof(
ASS, styles_count),
120 { .section =
"Events",
121 .format_header =
"Format",
122 .fields_header =
"Dialogue",
125 .offset_count = offsetof(
ASS, dialogs_count),
148 memcpy(str, buf, len);
152 *(
char **)dest = str;
158 return sscanf(buf,
"%d", (
int *)dest) == 1;
162 return sscanf(buf,
"%f", (
float *)dest) == 1;
166 return sscanf(buf,
"&H%8x", (
int *)dest) == 1 ||
167 sscanf(buf,
"%d", (
int *)dest) == 1;
172 if ((c = sscanf(buf,
"%d:%02d:%02d.%02d", &h, &m, &s, &cs)) == 4)
173 *(
int *)dest = 360000*h + 6000*m + 100*s + cs;
179 if (sscanf(buf,
"%d", &a) == 1) {
181 *(
int *)dest = a + ((a&4) >> 1) - 5*!!(a&8);
214 tmp += *count * section->
size;
215 memset(tmp, 0, section->
size);
222 return buf ==
'\r' || buf ==
'\n' || buf == 0;
254 while (buf && *buf) {
259 if (buf[0] ==
';' || (buf[0] ==
'!' && buf[1] ==
':'))
262 len = strcspn(buf,
":\r\n");
263 if (buf[len] ==
':' &&
266 if (ass_sections[i].fields_header &&
267 !strncmp(buf, ass_sections[i].fields_header, len)) {
278 if (!strncmp(buf, section->
format_header, len) && buf[len] ==
':') {
282 len = strcspn(buf,
", \r\n");
288 if (!strncmp(buf, section->
fields[i].
name, len)) {
293 buf =
skip_space(buf + len + (buf[len] ==
','));
301 if (!strncmp(buf, section->
fields_header, len) && buf[len] ==
':') {
303 if (!struct_ptr)
return NULL;
314 for (i=0; !
is_eol(*buf) && i < *number; i++) {
315 int last = i == *number - 1;
317 len = strcspn(buf, last ?
"\r\n" :
",\r\n");
324 if (!last && *buf) buf++;
329 len = strcspn(buf,
":\r\n");
330 if (buf[len] ==
':') {
332 if (!strncmp(buf, section->
fields[i].
name, len)) {
343 buf += strcspn(buf,
"\n");
357 while (buf && *buf) {
358 if (sscanf(buf,
"[%15[0-9A-Za-z+ ]]%c", section, &c) == 2) {
359 buf += strcspn(buf,
"\n");
362 if (!strcmp(section, ass_sections[i].section)) {
367 buf += strcspn(buf,
"\n");
379 if (buf && !memcmp(buf,
"\xef\xbb\xbf", 3))
401 for (i=0; i<*
count; i++, ptr += section->
size)
414 int cache,
int *number)
420 if (!strcmp(ass_sections[i].
section,
"Events")) {
469 len = last ? strlen(buf) : strcspn(buf,
",");
470 if (len >= INT_MAX) {
497 const char *text =
NULL;
501 while (buf && *buf) {
502 if (text && callbacks->
text &&
503 (sscanf(buf,
"\\%1[nN]", new_line) == 1 ||
504 !strncmp(buf,
"{\\", 2))) {
505 callbacks->
text(priv, text, text_len);
508 if (sscanf(buf,
"\\%1[nN]", new_line) == 1) {
510 callbacks->
new_line(priv, new_line[0] ==
'N');
512 }
else if (!strncmp(buf,
"{\\", 2)) {
514 while (*buf ==
'\\') {
515 char style[2],
c[2], sep[2], c_num[2] =
"0",
tmp[128] = {0};
516 unsigned int color = 0xFFFFFFFF;
518 int x1, y1, x2, y2,
t1 = -1,
t2 = -1;
519 if (sscanf(buf,
"\\%1[bisu]%1[01\\}]%n", style, c, &len) > 1) {
520 int close = c[0] ==
'0' ? 1 : c[0] ==
'1' ? 0 : -1;
522 if (callbacks->
style)
523 callbacks->
style(priv, style[0], close);
524 }
else if (sscanf(buf,
"\\c%1[\\}]%n", sep, &len) > 0 ||
525 sscanf(buf,
"\\c&H%X&%1[\\}]%n", &color, sep, &len) > 1 ||
526 sscanf(buf,
"\\%1[1234]c%1[\\}]%n", c_num, sep, &len) > 1 ||
527 sscanf(buf,
"\\%1[1234]c&H%X&%1[\\}]%n", c_num, &color, sep, &len) > 2) {
528 if (callbacks->
color)
529 callbacks->
color(priv, color, c_num[0] -
'0');
530 }
else if (sscanf(buf,
"\\alpha%1[\\}]%n", sep, &len) > 0 ||
531 sscanf(buf,
"\\alpha&H%2X&%1[\\}]%n", &
alpha, sep, &len) > 1 ||
532 sscanf(buf,
"\\%1[1234]a%1[\\}]%n", c_num, sep, &len) > 1 ||
533 sscanf(buf,
"\\%1[1234]a&H%2X&%1[\\}]%n", c_num, &
alpha, sep, &len) > 2) {
534 if (callbacks->
alpha)
535 callbacks->
alpha(priv,
alpha, c_num[0] -
'0');
536 }
else if (sscanf(buf,
"\\fn%1[\\}]%n", sep, &len) > 0 ||
537 sscanf(buf,
"\\fn%127[^\\}]%1[\\}]%n",
tmp, sep, &len) > 1) {
540 }
else if (sscanf(buf,
"\\fs%1[\\}]%n", sep, &len) > 0 ||
541 sscanf(buf,
"\\fs%u%1[\\}]%n", &size, sep, &len) > 1) {
544 }
else if (sscanf(buf,
"\\a%1[\\}]%n", sep, &len) > 0 ||
545 sscanf(buf,
"\\a%2u%1[\\}]%n", &an, sep, &len) > 1 ||
546 sscanf(buf,
"\\an%1[\\}]%n", sep, &len) > 0 ||
547 sscanf(buf,
"\\an%1u%1[\\}]%n", &an, sep, &len) > 1) {
548 if (an != -1 && buf[2] !=
'n')
549 an = (an&3) + (an&4 ? 6 : an&8 ? 3 : 0);
552 }
else if (sscanf(buf,
"\\r%1[\\}]%n", sep, &len) > 0 ||
553 sscanf(buf,
"\\r%127[^\\}]%1[\\}]%n",
tmp, sep, &len) > 1) {
556 }
else if (sscanf(buf,
"\\move(%d,%d,%d,%d)%1[\\}]%n", &x1, &y1, &x2, &y2, sep, &len) > 4 ||
557 sscanf(buf,
"\\move(%d,%d,%d,%d,%d,%d)%1[\\}]%n", &x1, &y1, &x2, &y2, &t1, &
t2, sep, &len) > 6) {
559 callbacks->
move(priv, x1, y1, x2, y2, t1,
t2);
560 }
else if (sscanf(buf,
"\\pos(%d,%d)%1[\\}]%n", &x1, &y1, sep, &len) > 2) {
562 callbacks->
move(priv, x1, y1, x1, y1, -1, -1);
563 }
else if (sscanf(buf,
"\\org(%d,%d)%1[\\}]%n", &x1, &y1, sep, &len) > 2) {
565 callbacks->
origin(priv, x1, y1);
567 len = strcspn(buf+1,
"\\}") + 2;
582 if (text && callbacks->
text)
583 callbacks->
text(priv, text, text_len);
585 callbacks->
end(priv);
594 if (!style || !*style)
int(* ASSConvertFunc)(void *dest, const char *buf, int len)
static const char * skip_space(const char *buf)
char * style
name of the ASSStyle to use with this dialog
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
void(* new_line)(void *priv, int forced)
fields extracted from the [Events] section
static int convert_alignment(void *dest, const char *buf, int len)
void(* move)(void *priv, int x1, int y1, int x2, int y2, int t1, int t2)
static int convert_str(void *dest, const char *buf, int len)
ASSDialog * ff_ass_split_dialog2(ASSSplitContext *ctx, const char *buf)
Split one ASS Dialogue line from a string buffer.
ASSSplitContext * ff_ass_split(const char *buf)
Split a full ASS file or a ASS header from a string buffer and store the split structure in a newly a...
static const ASSSection ass_sections[]
ASSDialog * dialogs
array of split out dialogs
const char * format_header
static int convert_color(void *dest, const char *buf, int len)
structure containing the whole split ASS data
void(* cancel_overrides)(void *priv, const char *style)
static int * get_default_field_orders(const ASSSection *section, int *number)
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
static int ass_split(ASSSplitContext *ctx, const char *buf)
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
static const char * ass_split_section(ASSSplitContext *ctx, const char *buf)
char * text
actual text which will be displayed as a subtitle, can include style override control codes (see ff_a...
This struct can be casted to ASS to access to the split data.
void ff_ass_free_dialog(ASSDialog **dialogp)
Free a dialogue obtained from ff_ass_split_dialog2().
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf offset
static av_cold int end(AVCodecContext *avctx)
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
int ff_ass_split_override_codes(const ASSCodesCallbacks *callbacks, void *priv, const char *buf)
Split override codes out of a ASS "Dialogue" Text field.
const char * fields_header
static int is_eol(char buf)
void * av_realloc_array(void *ptr, size_t nmemb, size_t size)
ASSDialog * ff_ass_split_dialog(ASSSplitContext *ctx, const char *buf, int cache, int *number)
Split one or several ASS "Dialogue" lines from a string buffer and store them in an already initializ...
void(* color)(void *priv, unsigned int, unsigned int color_id)
void(* font_name)(void *priv, const char *name)
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this field
int av_reallocp_array(void *ptr, size_t nmemb, size_t size)
Allocate, reallocate, or free an array through a pointer to a pointer.
void(* font_size)(void *priv, int size)
the definition of that something depends on the semantic of the filter The callback must examine the status of the filter s links and proceed accordingly The status of output links is stored in the status_in and status_out fields and tested by the then the processing requires a frame on this link and the filter is expected to make efforts in that direction The status of input links is stored by the fifo and status_out fields
Set of callback functions corresponding to each override codes that can be encountered in a "Dialogue...
#define FF_ARRAY_ELEMS(a)
static int convert_flt(void *dest, const char *buf, int len)
Libavcodec external API header.
static const ASSConvertFunc convert_func[]
void(* origin)(void *priv, int x, int y)
static const int16_t alpha[]
void(* alignment)(void *priv, int alignment)
static void free_section(ASSSplitContext *ctx, const ASSSection *section)
static uint8_t * realloc_section_array(ASSSplitContext *ctx)
fields extracted from the [V4(+) Styles] section
ASSStyle * ff_ass_style_get(ASSSplitContext *ctx, const char *style)
Find an ASSStyle structure by its name.
static const OMX_CALLBACKTYPE callbacks
void(* alpha)(void *priv, int alpha, int alpha_id)
static int convert_timestamp(void *dest, const char *buf, int len)
static int convert_int(void *dest, const char *buf, int len)
char * name
name of the tyle (case sensitive)
void(* text)(void *priv, const char *text, int len)
int dialogs_count
number of ASSDialog in the dialogs array
int styles_count
number of ASSStyle in the styles array
void ff_ass_split_free(ASSSplitContext *ctx)
Free all the memory allocated for an ASSSplitContext.
#define av_malloc_array(a, b)
fields extracted from the [Script Info] section
void(* style)(void *priv, char style, int close)
ASSStyle * styles
array of split out styles
int * field_order[FF_ARRAY_ELEMS(ass_sections)]
int field_number[FF_ARRAY_ELEMS(ass_sections)]