FFmpeg  4.4.4
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  int play_res_x, int play_res_y,
31  const char *font, int font_size,
32  int primary_color, int secondary_color,
33  int outline_color, int back_color,
34  int bold, int italic, int underline,
35  int border_style, int alignment)
36 {
38  "[Script Info]\r\n"
39  "; Script generated by FFmpeg/Lavc%s\r\n"
40  "ScriptType: v4.00+\r\n"
41  "PlayResX: %d\r\n"
42  "PlayResY: %d\r\n"
43  "ScaledBorderAndShadow: yes\r\n"
44  "\r\n"
45  "[V4+ Styles]\r\n"
46 
47  /* ASSv4 header */
48  "Format: Name, "
49  "Fontname, Fontsize, "
50  "PrimaryColour, SecondaryColour, OutlineColour, BackColour, "
51  "Bold, Italic, Underline, StrikeOut, "
52  "ScaleX, ScaleY, "
53  "Spacing, Angle, "
54  "BorderStyle, Outline, Shadow, "
55  "Alignment, MarginL, MarginR, MarginV, "
56  "Encoding\r\n"
57 
58  "Style: "
59  "Default," /* Name */
60  "%s,%d," /* Font{name,size} */
61  "&H%x,&H%x,&H%x,&H%x," /* {Primary,Secondary,Outline,Back}Colour */
62  "%d,%d,%d,0," /* Bold, Italic, Underline, StrikeOut */
63  "100,100," /* Scale{X,Y} */
64  "0,0," /* Spacing, Angle */
65  "%d,1,0," /* BorderStyle, Outline, Shadow */
66  "%d,10,10,10," /* Alignment, Margin[LRV] */
67  "0\r\n" /* Encoding */
68 
69  "\r\n"
70  "[Events]\r\n"
71  "Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text\r\n",
73  play_res_x, play_res_y, font, font_size,
74  primary_color, secondary_color, outline_color, back_color,
75  -bold, -italic, -underline, border_style, alignment);
76 
77  if (!avctx->subtitle_header)
78  return AVERROR(ENOMEM);
79  avctx->subtitle_header_size = strlen(avctx->subtitle_header);
80  return 0;
81 }
82 
84  const char *font, int font_size,
85  int color, int back_color,
86  int bold, int italic, int underline,
87  int border_style, int alignment)
88 {
89  return ff_ass_subtitle_header_full(avctx,
91  font, font_size, color, color,
92  back_color, back_color,
93  bold, italic, underline,
94  border_style, alignment);
95 }
96 
98 {
108 }
109 
110 char *ff_ass_get_dialog(int readorder, int layer, const char *style,
111  const char *speaker, const char *text)
112 {
113  return av_asprintf("%d,%d,%s,%s,0,0,0,,%s",
114  readorder, layer, style ? style : "Default",
115  speaker ? speaker : "", text);
116 }
117 
118 int ff_ass_add_rect(AVSubtitle *sub, const char *dialog,
119  int readorder, int layer, const char *style,
120  const char *speaker)
121 {
122  char *ass_str;
123  AVSubtitleRect **rects;
124 
125  rects = av_realloc_array(sub->rects, sub->num_rects+1, sizeof(*sub->rects));
126  if (!rects)
127  return AVERROR(ENOMEM);
128  sub->rects = rects;
129  rects[sub->num_rects] = av_mallocz(sizeof(*rects[0]));
130  if (!rects[sub->num_rects])
131  return AVERROR(ENOMEM);
132  rects[sub->num_rects]->type = SUBTITLE_ASS;
133  ass_str = ff_ass_get_dialog(readorder, layer, style, speaker, dialog);
134  if (!ass_str)
135  return AVERROR(ENOMEM);
136  rects[sub->num_rects]->ass = ass_str;
137  sub->num_rects++;
138  return 0;
139 }
140 
142 {
143  FFASSDecoderContext *s = avctx->priv_data;
144  if (!(avctx->flags2 & AV_CODEC_FLAG2_RO_FLUSH_NOOP))
145  s->readorder = 0;
146 }
147 
148 void ff_ass_bprint_text_event(AVBPrint *buf, const char *p, int size,
149  const char *linebreaks, int keep_ass_markup)
150 {
151  const char *p_end = p + size;
152 
153  for (; p < p_end && *p; p++) {
154 
155  /* forced custom line breaks, not accounted as "normal" EOL */
156  if (linebreaks && strchr(linebreaks, *p)) {
157  av_bprintf(buf, "\\N");
158 
159  /* standard ASS escaping so random characters don't get mis-interpreted
160  * as ASS */
161  } else if (!keep_ass_markup && strchr("{}\\", *p)) {
162  av_bprintf(buf, "\\%c", *p);
163 
164  /* some packets might end abruptly (no \0 at the end, like for example
165  * in some cases of demuxing from a classic video container), some
166  * might be terminated with \n or \r\n which we have to remove (for
167  * consistency with those who haven't), and we also have to deal with
168  * evil cases such as \r at the end of the buffer (and no \0 terminated
169  * character) */
170  } else if (p[0] == '\n') {
171  /* some stuff left so we can insert a line break */
172  if (p < p_end - 1)
173  av_bprintf(buf, "\\N");
174  } else if (p[0] == '\r' && p < p_end - 1 && p[1] == '\n') {
175  /* \r followed by a \n, we can skip it. We don't insert the \N yet
176  * because we don't know if it is followed by more text */
177  continue;
178 
179  /* finally, a sane character */
180  } else {
181  av_bprint_chars(buf, *p, 1);
182  }
183  }
184 }
int ff_ass_subtitle_header_full(AVCodecContext *avctx, int play_res_x, int play_res_y, const char *font, int font_size, int primary_color, int secondary_color, int outline_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
int ff_ass_subtitle_header_default(AVCodecContext *avctx)
Generate a suitable AVCodecContext.subtitle_header for SUBTITLE_ASS with default style.
Definition: ass.c:97
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:83
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:148
void ff_ass_decoder_flush(AVCodecContext *avctx)
Helper to flush a text subtitles decoder making use of the FFASSDecoderContext.
Definition: ass.c:141
char * ff_ass_get_dialog(int readorder, int layer, const char *style, const char *speaker, const char *text)
Craft an ASS dialog string.
Definition: ass.c:110
int ff_ass_add_rect(AVSubtitle *sub, const char *dialog, int readorder, int layer, const char *style, const char *speaker)
Add an ASS dialog to a subtitle.
Definition: ass.c:118
#define ASS_DEFAULT_PLAYRESY
Definition: ass.h:29
#define ASS_DEFAULT_ALIGNMENT
Definition: ass.h:42
#define ASS_DEFAULT_PLAYRESX
Definition: ass.h:28
#define ASS_DEFAULT_FONT_SIZE
Definition: ass.h:36
#define ASS_DEFAULT_COLOR
Definition: ass.h:37
#define ASS_DEFAULT_BORDERSTYLE
Definition: ass.h:43
#define ASS_DEFAULT_BACK_COLOR
Definition: ass.h:38
#define ASS_DEFAULT_FONT
Definition: ass.h:35
#define ASS_DEFAULT_BOLD
Definition: ass.h:39
#define ASS_DEFAULT_UNDERLINE
Definition: ass.h:41
#define ASS_DEFAULT_ITALIC
Definition: ass.h:40
simple assert() macros that are a bit more flexible than ISO C assert().
Libavcodec external API header.
char * av_asprintf(const char *fmt,...)
Definition: avstring.c:113
void av_bprintf(AVBPrint *buf, const char *fmt,...)
Definition: bprint.c:94
void av_bprint_chars(AVBPrint *buf, char c, unsigned n)
Append char c n times to a print buffer.
Definition: bprint.c:140
#define s(width, name)
Definition: cbs_vp9.c:257
common internal and external API header
static float sub(float src0, float src1)
#define AV_CODEC_FLAG2_RO_FLUSH_NOOP
Do not reset ASS ReadOrder field on flush (subtitles decoding)
Definition: avcodec.h:388
#define AV_CODEC_FLAG_BITEXACT
Use only bitexact stuff (except (I)DCT).
Definition: avcodec.h:333
@ SUBTITLE_ASS
Formatted text, the ass field must be set by the decoder and is authoritative.
Definition: avcodec.h:2682
#define AVERROR(e)
Definition: error.h:43
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:237
void * av_realloc_array(void *ptr, size_t nmemb, size_t size)
Allocate, reallocate, or free an array.
Definition: mem.c:198
#define AV_STRINGIFY(s)
Definition: macros.h:36
#define LIBAVCODEC_VERSION
Definition: version.h:37
main external API structure.
Definition: avcodec.h:536
int subtitle_header_size
Definition: avcodec.h:2017
int flags2
AV_CODEC_FLAG2_*.
Definition: avcodec.h:623
uint8_t * subtitle_header
Header containing style information for text subtitles.
Definition: avcodec.h:2016
int flags
AV_CODEC_FLAG_*.
Definition: avcodec.h:616
void * priv_data
Definition: avcodec.h:563
char * ass
0 terminated ASS/SSA compatible event line.
Definition: avcodec.h:2717
enum AVSubtitleType type
Definition: avcodec.h:2708
int size