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
25
27
33
45
47 {
50
54 }
58 uint8_t *trailer = strstr(par->
extradata,
"\n[Events]");
59
60 if (trailer)
61 trailer = strstr(trailer, "Format:");
62 if (trailer)
63 trailer = strstr(trailer, "\n");
64
65 if (trailer++) {
70 }
71
73 if (par->
extradata[header_size - 1] !=
'\n')
76 if (!strstr(par->
extradata,
"\n[Events]"))
77 avio_printf(
s->pb,
"[Events]\r\nFormat: %s, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text\r\n",
79 }
80
81 return 0;
82 }
83
85 {
86 int n = 0;
89
96 }
102 if (next)
106 n++;
107 }
109 if (n > 1)
110 av_log(
s,
AV_LOG_DEBUG,
"wrote %d ASS lines, cached dialogues: %d, waiting for event id %d\n",
112 }
113
115 {
117
118 /* from the last added to the end of the list */
122 break;
123 prev = cur;
125 }
126 }
127
128 /* from the beginning to the last one added */
129 if (!prev) {
133 break;
134 prev = cur;
136 }
137 }
138
139 if (prev) {
140 prev->
next = dialogue;
141 dialogue->
prev = prev;
142 } else {
145 }
146 if (next) {
147 next->
prev = dialogue;
148 dialogue->
next = next;
149 }
152 }
153
155 {
157
158 long int layer;
162 int hh1, mm1, ss1, ms1;
163 int hh2, mm2, ss2, ms2;
165
166 if (!dialogue)
168
173 if (*p == ',')
174 p++;
175
176 if (ass->
ssa_mode && !strncmp(p,
"Marked=", 7))
177 p += 7;
178
179 layer = strtol(p, &p, 10);
180 if (*p == ',')
181 p++;
182 hh1 = (
int)(start / 360000); mm1 = (
int)(start / 6000) % 60;
183 hh2 = (
int)(end / 360000); mm2 = (
int)(end / 6000) % 60;
184 ss1 = (
int)(start / 100) % 60; ms1 = (
int)(start % 100);
185 ss2 = (
int)(end / 100) % 60; ms2 = (
int)(end % 100);
186 if (hh1 > 9) hh1 = 9, mm1 = 59, ss1 = 59, ms1 = 99;
187 if (hh2 > 9) hh2 = 9, mm2 = 59, ss2 = 59, ms2 = 99;
188
189 dialogue->
line =
av_asprintf(
"%s%ld,%d:%02d:%02d.%02d,%d:%02d:%02d.%02d,%s",
191 layer, hh1, mm1, ss1, ms1, hh2, mm2, ss2, ms2, p);
192 if (!dialogue->
line) {
195 }
198
199 return 0;
200 }
201
203 {
205
207
210 }
211
212 return 0;
213 }
214
215 #define OFFSET(x) offsetof(ASSContext, x)
216 #define E AV_OPT_FLAG_ENCODING_PARAM
218 {
"ignore_readorder",
"write events immediately, even if they're out-of-order",
OFFSET(ignore_readorder),
AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1,
E },
220 };
221
227 };
228
232 .mime_type = "text/x-ass",
233 .extensions = "ass,ssa",
241 };