FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
ass.c
Go to the documentation of this file.
1 /*
2  * SSA/ASS common functions
3  * Copyright (c) 2010 Aurelien Jacobs <aurel@gnuage.org>
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 
22 #include "avcodec.h"
23 #include "ass.h"
24 #include "libavutil/avassert.h"
25 #include "libavutil/avstring.h"
26 #include "libavutil/bprint.h"
27 #include "libavutil/common.h"
28 
30  const char *font, int font_size,
31  int color, int back_color,
32  int bold, int italic, int underline,
33  int border_style, int alignment)
34 {
36  "[Script Info]\r\n"
37  "; Script generated by FFmpeg/Lavc%s\r\n"
38  "ScriptType: v4.00+\r\n"
39  "PlayResX: %d\r\n"
40  "PlayResY: %d\r\n"
41  "\r\n"
42  "[V4+ Styles]\r\n"
43 
44  /* ASSv4 header */
45  "Format: Name, "
46  "Fontname, Fontsize, "
47  "PrimaryColour, SecondaryColour, OutlineColour, BackColour, "
48  "Bold, Italic, Underline, StrikeOut, "
49  "ScaleX, ScaleY, "
50  "Spacing, Angle, "
51  "BorderStyle, Outline, Shadow, "
52  "Alignment, MarginL, MarginR, MarginV, "
53  "Encoding\r\n"
54 
55  "Style: "
56  "Default," /* Name */
57  "%s,%d," /* Font{name,size} */
58  "&H%x,&H%x,&H%x,&H%x," /* {Primary,Secondary,Outline,Back}Colour */
59  "%d,%d,%d,0," /* Bold, Italic, Underline, StrikeOut */
60  "100,100," /* Scale{X,Y} */
61  "0,0," /* Spacing, Angle */
62  "%d,1,0," /* BorderStyle, Outline, Shadow */
63  "%d,10,10,10," /* Alignment, Margin[LRV] */
64  "0\r\n" /* Encoding */
65 
66  "\r\n"
67  "[Events]\r\n"
68  "Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text\r\n",
71  font, font_size, color, color, back_color, back_color,
72  -bold, -italic, -underline, border_style, alignment);
73 
74  if (!avctx->subtitle_header)
75  return AVERROR(ENOMEM);
76  avctx->subtitle_header_size = strlen(avctx->subtitle_header);
77  return 0;
78 }
79 
81 {
91 }
92 
93 static void insert_ts(AVBPrint *buf, int ts)
94 {
95  if (ts == -1) {
96  av_bprintf(buf, "9:59:59.99,");
97  } else {
98  int h, m, s;
99 
100  h = ts/360000; ts -= 360000*h;
101  m = ts/ 6000; ts -= 6000*m;
102  s = ts/ 100; ts -= 100*s;
103  av_bprintf(buf, "%d:%02d:%02d.%02d,", h, m, s, ts);
104  }
105 }
106 
107 int ff_ass_bprint_dialog(AVBPrint *buf, const char *dialog,
108  int ts_start, int duration, int raw)
109 {
110  int dlen;
111 
112  if (!raw || raw == 2) {
113  long int layer = 0;
114 
115  if (raw == 2) {
116  /* skip ReadOrder */
117  dialog = strchr(dialog, ',');
118  if (!dialog)
119  return AVERROR_INVALIDDATA;
120  dialog++;
121 
122  /* extract Layer or Marked */
123  layer = strtol(dialog, (char**)&dialog, 10);
124  if (*dialog != ',')
125  return AVERROR_INVALIDDATA;
126  dialog++;
127  }
128  av_bprintf(buf, "Dialogue: %ld,", layer);
129  insert_ts(buf, ts_start);
130  insert_ts(buf, duration == -1 ? -1 : ts_start + duration);
131  if (raw != 2)
132  av_bprintf(buf, "Default,,0,0,0,,");
133  }
134 
135  dlen = strcspn(dialog, "\n");
136  dlen += dialog[dlen] == '\n';
137 
138  av_bprintf(buf, "%.*s", dlen, dialog);
139  if (raw == 2)
140  av_bprintf(buf, "\r\n");
141 
142  return dlen;
143 }
144 
145 int ff_ass_add_rect(AVSubtitle *sub, const char *dialog,
146  int ts_start, int duration, int raw)
147 {
148  AVBPrint buf;
149  int ret, dlen;
150  AVSubtitleRect **rects;
151 
153  if ((ret = ff_ass_bprint_dialog(&buf, dialog, ts_start, duration, raw)) < 0)
154  goto err;
155  dlen = ret;
156  if (!av_bprint_is_complete(&buf))
157  goto errnomem;
158 
159  rects = av_realloc_array(sub->rects, (sub->num_rects+1), sizeof(*sub->rects));
160  if (!rects)
161  goto errnomem;
162  sub->rects = rects;
163  sub->end_display_time = FFMAX(sub->end_display_time, 10 * duration);
164  rects[sub->num_rects] = av_mallocz(sizeof(*rects[0]));
165  if (!rects[sub->num_rects])
166  goto errnomem;
167  rects[sub->num_rects]->type = SUBTITLE_ASS;
168  ret = av_bprint_finalize(&buf, &rects[sub->num_rects]->ass);
169  if (ret < 0)
170  goto err;
171  sub->num_rects++;
172  return dlen;
173 
174 errnomem:
175  ret = AVERROR(ENOMEM);
176 err:
177  av_bprint_finalize(&buf, NULL);
178  return ret;
179 }
180 
182  int ts_start, int duration)
183 {
184  av_bprintf(buf, "\r\n");
185  if (!av_bprint_is_complete(buf))
186  return AVERROR(ENOMEM);
187  return ff_ass_add_rect(sub, buf->str, ts_start, duration, 0);
188 }
189 
190 void ff_ass_bprint_text_event(AVBPrint *buf, const char *p, int size,
191  const char *linebreaks, int keep_ass_markup)
192 {
193  const char *p_end = p + size;
194 
195  for (; p < p_end && *p; p++) {
196 
197  /* forced custom line breaks, not accounted as "normal" EOL */
198  if (linebreaks && strchr(linebreaks, *p)) {
199  av_bprintf(buf, "\\N");
200 
201  /* standard ASS escaping so random characters don't get mis-interpreted
202  * as ASS */
203  } else if (!keep_ass_markup && strchr("{}\\", *p)) {
204  av_bprintf(buf, "\\%c", *p);
205 
206  /* some packets might end abruptly (no \0 at the end, like for example
207  * in some cases of demuxing from a classic video container), some
208  * might be terminated with \n or \r\n which we have to remove (for
209  * consistency with those who haven't), and we also have to deal with
210  * evil cases such as \r at the end of the buffer (and no \0 terminated
211  * character) */
212  } else if (p[0] == '\n') {
213  /* some stuff left so we can insert a line break */
214  if (p < p_end - 1)
215  av_bprintf(buf, "\\N");
216  } else if (p[0] == '\r' && p < p_end - 1 && p[1] == '\n') {
217  /* \r followed by a \n, we can skip it. We don't insert the \N yet
218  * because we don't know if it is followed by more text */
219  continue;
220 
221  /* finally, a sane character */
222  } else {
223  av_bprint_chars(buf, *p, 1);
224  }
225  }
226 }
int ff_ass_bprint_dialog(AVBPrint *buf, const char *dialog, int ts_start, int duration, int raw)
Add an ASS dialog line to an AVBPrint buffer.
Definition: ass.c:107
#define NULL
Definition: coverity.c:32
const char * s
Definition: avisynth_c.h:631
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
void av_bprintf(AVBPrint *buf, const char *fmt,...)
Definition: bprint.c:94
#define ASS_DEFAULT_BORDERSTYLE
Definition: ass.h:43
int ff_ass_subtitle_header(AVCodecContext *avctx, const char *font, int font_size, int color, int back_color, int bold, int italic, int underline, int border_style, int alignment)
Generate a suitable AVCodecContext.subtitle_header for SUBTITLE_ASS.
Definition: ass.c:29
unsigned num_rects
Definition: avcodec.h:3737
int av_bprint_finalize(AVBPrint *buf, char **ret_str)
Finalize a print buffer.
Definition: bprint.c:235
AVSubtitleRect ** rects
Definition: avcodec.h:3738
#define ASS_DEFAULT_ALIGNMENT
Definition: ass.h:42
int subtitle_header_size
Definition: avcodec.h:3150
int ff_ass_subtitle_header_default(AVCodecContext *avctx)
Generate a suitable AVCodecContext.subtitle_header for SUBTITLE_ASS with default style.
Definition: ass.c:80
ptrdiff_t size
Definition: opengl_enc.c:101
#define ASS_DEFAULT_PLAYRESY
Definition: ass.h:29
unsigned m
Definition: audioconvert.c:187
static void insert_ts(AVBPrint *buf, int ts)
Definition: ass.c:93
#define ASS_DEFAULT_BACK_COLOR
Definition: ass.h:38
#define ASS_DEFAULT_UNDERLINE
Definition: ass.h:41
#define AV_BPRINT_SIZE_UNLIMITED
#define AVERROR(e)
Definition: error.h:43
#define ASS_DEFAULT_FONT
Definition: ass.h:35
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
Definition: bprint.c:69
int flags
AV_CODEC_FLAG_*.
Definition: avcodec.h:1627
simple assert() macros that are a bit more flexible than ISO C assert().
#define FFMAX(a, b)
Definition: common.h:94
#define ASS_DEFAULT_FONT_SIZE
Definition: ass.h:36
int ff_ass_add_rect(AVSubtitle *sub, const char *dialog, int ts_start, int duration, int raw)
Add an ASS dialog line to an AVSubtitle as a new AVSubtitleRect.
Definition: ass.c:145
uint32_t end_display_time
Definition: avcodec.h:3736
char * av_asprintf(const char *fmt,...)
Definition: avstring.c:113
#define AV_CODEC_FLAG_BITEXACT
Use only bitexact stuff (except (I)DCT).
Definition: avcodec.h:787
int64_t duration
Definition: movenc-test.c:63
static int av_bprint_is_complete(const AVBPrint *buf)
Test if the print buffer is complete (not truncated).
Definition: bprint.h:185
Libavcodec external API header.
int ff_ass_add_rect_bprint(AVSubtitle *sub, AVBPrint *buf, int ts_start, int duration)
Same as ff_ass_add_rect, but taking an AVBPrint buffer instead of a string, and assuming raw=0...
Definition: ass.c:181
main external API structure.
Definition: avcodec.h:1532
void * buf
Definition: avisynth_c.h:553
#define AV_STRINGIFY(s)
Definition: macros.h:36
#define LIBAVCODEC_VERSION
Definition: version.h:38
common internal and external API header
#define ASS_DEFAULT_COLOR
Definition: ass.h:37
void * av_realloc_array(void *ptr, size_t nmemb, size_t size)
Definition: mem.c:208
Formatted text, the ass field must be set by the decoder and is authoritative.
Definition: avcodec.h:3693
#define ASS_DEFAULT_ITALIC
Definition: ass.h:40
void ff_ass_bprint_text_event(AVBPrint *buf, const char *p, int size, const char *linebreaks, int keep_ass_markup)
Escape a text subtitle using ASS syntax into an AVBPrint buffer.
Definition: ass.c:190
#define ASS_DEFAULT_BOLD
Definition: ass.h:39
char * ass
0 terminated ASS/SSA compatible event line.
Definition: avcodec.h:3728
enum AVSubtitleType type
Definition: avcodec.h:3719
#define ASS_DEFAULT_PLAYRESX
Definition: ass.h:28
void * av_mallocz(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:252
uint8_t * subtitle_header
Header containing style information for text subtitles.
Definition: avcodec.h:3149
void av_bprint_chars(AVBPrint *buf, char c, unsigned n)
Append char c n times to a print buffer.
Definition: bprint.c:140