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 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  "1,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, 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 {
90 }
91 
92 static void insert_ts(AVBPrint *buf, int ts)
93 {
94  if (ts == -1) {
95  av_bprintf(buf, "9:59:59.99,");
96  } else {
97  int h, m, s;
98 
99  h = ts/360000; ts -= 360000*h;
100  m = ts/ 6000; ts -= 6000*m;
101  s = ts/ 100; ts -= 100*s;
102  av_bprintf(buf, "%d:%02d:%02d.%02d,", h, m, s, ts);
103  }
104 }
105 
106 int ff_ass_bprint_dialog(AVBPrint *buf, const char *dialog,
107  int ts_start, int duration, int raw)
108 {
109  int dlen;
110 
111  if (!raw || raw == 2) {
112  long int layer = 0;
113 
114  if (raw == 2) {
115  /* skip ReadOrder */
116  dialog = strchr(dialog, ',');
117  if (!dialog)
118  return AVERROR_INVALIDDATA;
119  dialog++;
120 
121  /* extract Layer or Marked */
122  layer = strtol(dialog, (char**)&dialog, 10);
123  if (*dialog != ',')
124  return AVERROR_INVALIDDATA;
125  dialog++;
126  }
127  av_bprintf(buf, "Dialogue: %ld,", layer);
128  insert_ts(buf, ts_start);
129  insert_ts(buf, duration == -1 ? -1 : ts_start + duration);
130  if (raw != 2)
131  av_bprintf(buf, "Default,,0,0,0,,");
132  }
133 
134  dlen = strcspn(dialog, "\n");
135  dlen += dialog[dlen] == '\n';
136 
137  av_bprintf(buf, "%.*s", dlen, dialog);
138  if (raw == 2)
139  av_bprintf(buf, "\r\n");
140 
141  return dlen;
142 }
143 
144 int ff_ass_add_rect(AVSubtitle *sub, const char *dialog,
145  int ts_start, int duration, int raw)
146 {
147  AVBPrint buf;
148  int ret, dlen;
149  AVSubtitleRect **rects;
150 
152  if ((ret = ff_ass_bprint_dialog(&buf, dialog, ts_start, duration, raw)) < 0)
153  goto err;
154  dlen = ret;
155  if (!av_bprint_is_complete(&buf))
156  goto errnomem;
157 
158  rects = av_realloc_array(sub->rects, (sub->num_rects+1), sizeof(*sub->rects));
159  if (!rects)
160  goto errnomem;
161  sub->rects = rects;
162  sub->end_display_time = FFMAX(sub->end_display_time, 10 * duration);
163  rects[sub->num_rects] = av_mallocz(sizeof(*rects[0]));
164  rects[sub->num_rects]->type = SUBTITLE_ASS;
165  ret = av_bprint_finalize(&buf, &rects[sub->num_rects]->ass);
166  if (ret < 0)
167  goto err;
168  sub->num_rects++;
169  return dlen;
170 
171 errnomem:
172  ret = AVERROR(ENOMEM);
173 err:
174  av_bprint_finalize(&buf, NULL);
175  return ret;
176 }
177 
179  int ts_start, int duration)
180 {
181  av_bprintf(buf, "\r\n");
182  if (!av_bprint_is_complete(buf))
183  return AVERROR(ENOMEM);
184  return ff_ass_add_rect(sub, buf->str, ts_start, duration, 0);
185 }
186 
187 void ff_ass_bprint_text_event(AVBPrint *buf, const char *p, int size,
188  const char *linebreaks, int keep_ass_markup)
189 {
190  const char *p_end = p + size;
191 
192  for (; p < p_end && *p; p++) {
193 
194  /* forced custom line breaks, not accounted as "normal" EOL */
195  if (linebreaks && strchr(linebreaks, *p)) {
196  av_bprintf(buf, "\\N");
197 
198  /* standard ASS escaping so random characters don't get mis-interpreted
199  * as ASS */
200  } else if (!keep_ass_markup && strchr("{}\\", *p)) {
201  av_bprintf(buf, "\\%c", *p);
202 
203  /* some packets might end abruptly (no \0 at the end, like for example
204  * in some cases of demuxing from a classic video container), some
205  * might be terminated with \n or \r\n which we have to remove (for
206  * consistency with those who haven't), and we also have to deal with
207  * evil cases such as \r at the end of the buffer (and no \0 terminated
208  * character) */
209  } else if (p[0] == '\n') {
210  /* some stuff left so we can insert a line break */
211  if (p < p_end - 1)
212  av_bprintf(buf, "\\N");
213  } else if (p[0] == '\r' && p < p_end - 1 && p[1] == '\n') {
214  /* \r followed by a \n, we can skip it. We don't insert the \N yet
215  * because we don't know if it is followed by more text */
216  continue;
217 
218  /* finally, a sane character */
219  } else {
220  av_bprint_chars(buf, *p, 1);
221  }
222  }
223 }
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:106
#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
unsigned num_rects
Definition: avcodec.h:3803
int av_bprint_finalize(AVBPrint *buf, char **ret_str)
Finalize a print buffer.
Definition: bprint.c:235
AVSubtitleRect ** rects
Definition: avcodec.h:3804
#define ASS_DEFAULT_ALIGNMENT
Definition: ass.h:42
int subtitle_header_size
Definition: avcodec.h:3237
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
static int64_t duration
Definition: ffplay.c:326
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 alignment)
Generate a suitable AVCodecContext.subtitle_header for SUBTITLE_ASS.
Definition: ass.c:29
#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:92
#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:1597
simple assert() macros that are a bit more flexible than ISO C assert().
#define FFMAX(a, b)
Definition: common.h:79
Libavcodec external API header.
#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:144
uint32_t end_display_time
Definition: avcodec.h:3802
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:788
static int av_bprint_is_complete(const AVBPrint *buf)
Test if the print buffer is complete (not truncated).
Definition: bprint.h:185
int ff_ass_add_rect_bprint(AVSubtitle *sub, AVBPrint *buf, int ts_start, int duration)
Same as ff_ass_add_rect_bprint, but taking an AVBPrint buffer instead of a string, and assuming raw=0.
Definition: ass.c:178
main external API structure.
Definition: avcodec.h:1502
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:3768
#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:187
#define ASS_DEFAULT_BOLD
Definition: ass.h:39
char * ass
0 terminated ASS/SSA compatible event line.
Definition: avcodec.h:3794
enum AVSubtitleType type
Definition: avcodec.h:3785
#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:3236
void av_bprint_chars(AVBPrint *buf, char c, unsigned n)
Append char c n times to a print buffer.
Definition: bprint.c:140