1 /*
2 * SSA/ASS muxer
3 * Copyright (c) 2008 Michael Niedermayer
4 *
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
28
30
36
48
50 {
53
57 uint8_t *trailer = strstr(par->
extradata,
"\n[Events]");
58
59 if (trailer)
60 trailer = strstr(trailer, "Format:");
61 if (trailer)
62 trailer = strstr(trailer, "\n");
63
64 if (trailer) {
65 header_size = (++trailer - par->
extradata);
69 }
70
72
74 if (!strstr(par->
extradata,
"\n[Events]"))
75 avio_printf(
s->pb,
"[Events]\nFormat: %s, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text\n",
77 }
78
79 return 0;
80 }
81
83 {
84 int n = 0;
87
94 }
100 if (next)
104 n++;
105 }
107 if (n > 1)
108 av_log(
s,
AV_LOG_DEBUG,
"wrote %d ASS lines, cached dialogues: %d, waiting for event id %d\n",
110 }
111
113 {
115
116 /* from the last added to the end of the list */
120 break;
121 prev = cur;
123 }
124 }
125
126 /* from the beginning to the last one added */
127 if (!prev) {
131 break;
132 prev = cur;
134 }
135 }
136
137 if (prev) {
138 prev->
next = dialogue;
139 dialogue->
prev = prev;
140 } else {
143 }
144 if (next) {
145 next->
prev = dialogue;
146 dialogue->
next = next;
147 }
150 }
151
153 {
155
156 long int layer;
157 int text_len;
161 int hh1, mm1, ss1, ms1;
162 int hh2, mm2, ss2, ms2;
164
165 if (!dialogue)
167
174
175 if (ass->
ssa_mode && !strncmp(
p,
"Marked=", 7))
177
178 layer = strtol(
p, &
p, 10);
181 hh1 = (int)(start / 360000); mm1 = (int)(start / 6000) % 60;
182 hh2 = (int)(end / 360000); mm2 = (int)(end / 6000) % 60;
183 ss1 = (int)(start / 100) % 60; ms1 = (int)(start % 100);
184 ss2 = (int)(end / 100) % 60; ms2 = (int)(end % 100);
185 if (hh1 > 9) hh1 = 9, mm1 = 59, ss1 = 59, ms1 = 99;
186 if (hh2 > 9) hh2 = 9, mm2 = 59, ss2 = 59, ms2 = 99;
187
188 text_len = strlen(
p);
189 while (text_len > 0 &&
p[text_len - 1] ==
'\r' ||
p[text_len - 1] ==
'\n')
190 text_len--;
191
192 dialogue->
line =
av_asprintf(
"%s%ld,%d:%02d:%02d.%02d,%d:%02d:%02d.%02d,%.*s",
194 layer, hh1, mm1, ss1, ms1, hh2, mm2, ss2, ms2, text_len,
p);
195 if (!dialogue->
line) {
198 }
201
202 return 0;
203 }
204
206 {
208
210
213 }
214
215 return 0;
216 }
217
218 #define OFFSET(x) offsetof(ASSContext, x)
219 #define E AV_OPT_FLAG_ENCODING_PARAM
221 {
"ignore_readorder",
"write events immediately, even if they're out-of-order",
OFFSET(ignore_readorder),
AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1,
E },
223 };
224
230 };
231
235 .p.mime_type = "text/x-ass",
236 .p.extensions = "ass,ssa",
248 };