FFmpeg: libavcodec/srtenc.c Source File

FFmpeg
srtenc.c
Go to the documentation of this file.
1 /*
2  * SubRip subtitle encoder
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 <stdarg.h>
23 #include "avcodec.h"
24 #include "libavutil/avstring.h"
25 #include "libavutil/bprint.h"
26 #include "ass_split.h"
27 #include "ass.h"
28 
29 
30  #define SRT_STACK_SIZE 64
31 
32  typedef struct {
33   AVCodecContext *avctx;
34   ASSSplitContext *ass_ctx;
35   AVBPrint buffer;
36   char stack[SRT_STACK_SIZE];
37   int stack_ptr;
38   int alignment_applied;
39 } SRTContext;
40 
41 
42 #ifdef __GNUC__
43 __attribute__ ((__format__ (__printf__, 2, 3)))
44 #endif
45  static void srt_print(SRTContext *s, const char *str, ...)
46 {
47  va_list vargs;
48  va_start(vargs, str);
49  av_vbprintf(&s->buffer, str, vargs);
50  va_end(vargs);
51 }
52 
53  static int srt_stack_push(SRTContext *s, const char c)
54 {
55  if (s->stack_ptr >= SRT_STACK_SIZE)
56  return -1;
57  s->stack[s->stack_ptr++] = c;
58  return 0;
59 }
60 
61  static char srt_stack_pop(SRTContext *s)
62 {
63  if (s->stack_ptr <= 0)
64  return 0;
65  return s->stack[--s->stack_ptr];
66 }
67 
68  static int srt_stack_find(SRTContext *s, const char c)
69 {
70  int i;
71  for (i = s->stack_ptr-1; i >= 0; i--)
72  if (s->stack[i] == c)
73  break;
74  return i;
75 }
76 
77  static void srt_close_tag(SRTContext *s, char tag)
78 {
79  srt_print(s, "</%c%s>", tag, tag == 'f' ? "ont" : "");
80 }
81 
82  static void srt_stack_push_pop(SRTContext *s, const char c, int close)
83 {
84  if (close) {
85  int i = c ? srt_stack_find(s, c) : 0;
86  if (i < 0)
87  return;
88  while (s->stack_ptr != i)
89  srt_close_tag(s, srt_stack_pop(s));
90  } else if (srt_stack_push(s, c) < 0)
91  av_log(s->avctx, AV_LOG_ERROR, "tag stack overflow\n");
92 }
93 
94  static void srt_style_apply(SRTContext *s, const char *style)
95 {
96  ASSStyle *st = ff_ass_style_get(s->ass_ctx, style);
97  if (st) {
98  int c = st->primary_color & 0xFFFFFF;
99  if (st->font_name && strcmp(st->font_name, ASS_DEFAULT_FONT) ||
100  st->font_size != ASS_DEFAULT_FONT_SIZE ||
101  c != ASS_DEFAULT_COLOR) {
102  srt_print(s, "<font");
103  if (st->font_name && strcmp(st->font_name, ASS_DEFAULT_FONT))
104  srt_print(s, " face=\"%s\"", st->font_name);
105  if (st->font_size != ASS_DEFAULT_FONT_SIZE)
106  srt_print(s, " size=\"%d\"", st->font_size);
107  if (c != ASS_DEFAULT_COLOR)
108  srt_print(s, " color=\"#%06x\"",
109  (c & 0xFF0000) >> 16 | c & 0xFF00 | (c & 0xFF) << 16);
110  srt_print(s, ">");
111  srt_stack_push(s, 'f');
112  }
113  if (st->bold != ASS_DEFAULT_BOLD) {
114  srt_print(s, "<b>");
115  srt_stack_push(s, 'b');
116  }
117  if (st->italic != ASS_DEFAULT_ITALIC) {
118  srt_print(s, "<i>");
119  srt_stack_push(s, 'i');
120  }
121  if (st->underline != ASS_DEFAULT_UNDERLINE) {
122  srt_print(s, "<u>");
123  srt_stack_push(s, 'u');
124  }
125  if (st->alignment != ASS_DEFAULT_ALIGNMENT) {
126  srt_print(s, "{\\an%d}", st->alignment);
127  s->alignment_applied = 1;
128  }
129  }
130 }
131 
132 
133  static av_cold int srt_encode_init(AVCodecContext *avctx)
134 {
135  SRTContext *s = avctx->priv_data;
136  s->avctx = avctx;
137  s->ass_ctx = ff_ass_split(avctx->subtitle_header);
138  av_bprint_init(&s->buffer, 0, AV_BPRINT_SIZE_UNLIMITED);
139  return s->ass_ctx ? 0 : AVERROR_INVALIDDATA;
140 }
141 
142  static void srt_text_cb(void *priv, const char *text, int len)
143 {
144  SRTContext *s = priv;
145  av_bprint_append_data(&s->buffer, text, len);
146 }
147 
148  static void srt_new_line_cb(void *priv, int forced)
149 {
150  srt_print(priv, "\r\n");
151 }
152 
153  static void srt_style_cb(void *priv, char style, int close)
154 {
155  srt_stack_push_pop(priv, style, close);
156  if (!close)
157  srt_print(priv, "<%c>", style);
158 }
159 
160  static void srt_color_cb(void *priv, unsigned int color, unsigned int color_id)
161 {
162  if (color_id > 1)
163  return;
164  srt_stack_push_pop(priv, 'f', color == 0xFFFFFFFF);
165  if (color != 0xFFFFFFFF)
166  srt_print(priv, "<font color=\"#%06x\">",
167  (color & 0xFF0000) >> 16 | color & 0xFF00 | (color & 0xFF) << 16);
168 }
169 
170  static void srt_font_name_cb(void *priv, const char *name)
171 {
172  srt_stack_push_pop(priv, 'f', !name);
173  if (name)
174  srt_print(priv, "<font face=\"%s\">", name);
175 }
176 
177  static void srt_font_size_cb(void *priv, int size)
178 {
179  srt_stack_push_pop(priv, 'f', size < 0);
180  if (size >= 0)
181  srt_print(priv, "<font size=\"%d\">", size);
182 }
183 
184  static void srt_alignment_cb(void *priv, int alignment)
185 {
186  SRTContext *s = priv;
187  if (!s->alignment_applied && alignment >= 0) {
188  srt_print(s, "{\\an%d}", alignment);
189  s->alignment_applied = 1;
190  }
191 }
192 
193  static void srt_cancel_overrides_cb(void *priv, const char *style)
194 {
195  srt_stack_push_pop(priv, 0, 1);
196  srt_style_apply(priv, style);
197 }
198 
199  static void srt_move_cb(void *priv, int x1, int y1, int x2, int y2,
200  int t1, int t2)
201 {
202  // TODO: add a AV_PKT_DATA_SUBTITLE_POSITION side data when a new subtitles
203  // encoding API passing the AVPacket is available.
204 }
205 
206  static void srt_end_cb(void *priv)
207 {
208  srt_stack_push_pop(priv, 0, 1);
209 }
210 
211  static const ASSCodesCallbacks srt_callbacks = {
212  .text = srt_text_cb,
213  .new_line = srt_new_line_cb,
214  .style = srt_style_cb,
215  .color = srt_color_cb,
216  .font_name = srt_font_name_cb,
217  .font_size = srt_font_size_cb,
218  .alignment = srt_alignment_cb,
219  .cancel_overrides = srt_cancel_overrides_cb,
220  .move = srt_move_cb,
221  .end = srt_end_cb,
222 };
223 
224  static int srt_encode_frame(AVCodecContext *avctx,
225  unsigned char *buf, int bufsize, const AVSubtitle *sub)
226 {
227  SRTContext *s = avctx->priv_data;
228  ASSDialog *dialog;
229  int i, num;
230 
231  av_bprint_clear(&s->buffer);
232 
233  for (i=0; i<sub->num_rects; i++) {
234 
235  if (sub->rects[i]->type != SUBTITLE_ASS) {
236  av_log(avctx, AV_LOG_ERROR, "Only SUBTITLE_ASS type supported.\n");
237  return AVERROR(ENOSYS);
238  }
239 
240  dialog = ff_ass_split_dialog(s->ass_ctx, sub->rects[i]->ass, 0, &num);
241  for (; dialog && num--; dialog++) {
242  s->alignment_applied = 0;
243  srt_style_apply(s, dialog->style);
244  ff_ass_split_override_codes(&srt_callbacks, s, dialog->text);
245  }
246  }
247 
248  if (!av_bprint_is_complete(&s->buffer))
249  return AVERROR(ENOMEM);
250  if (!s->buffer.len)
251  return 0;
252 
253  if (s->buffer.len > bufsize) {
254  av_log(avctx, AV_LOG_ERROR, "Buffer too small for ASS event.\n");
255  return -1;
256  }
257  memcpy(buf, s->buffer.str, s->buffer.len);
258 
259  return s->buffer.len;
260 }
261 
262  static int srt_encode_close(AVCodecContext *avctx)
263 {
264  SRTContext *s = avctx->priv_data;
265  ff_ass_split_free(s->ass_ctx);
266  av_bprint_finalize(&s->buffer, NULL);
267  return 0;
268 }
269 
270 #if CONFIG_SRT_ENCODER
271 /* deprecated encoder */
272 AVCodec ff_srt_encoder = {
273  .name = "srt",
274  .long_name = NULL_IF_CONFIG_SMALL("SubRip subtitle"),
275  .type = AVMEDIA_TYPE_SUBTITLE,
276  .id = AV_CODEC_ID_SUBRIP,
277  .priv_data_size = sizeof(SRTContext),
278  .init = srt_encode_init,
279  .encode_sub = srt_encode_frame,
280  .close = srt_encode_close,
281 };
282 #endif
283 
284 #if CONFIG_SUBRIP_ENCODER
285 AVCodec ff_subrip_encoder = {
286  .name = "subrip",
287  .long_name = NULL_IF_CONFIG_SMALL("SubRip subtitle"),
288  .type = AVMEDIA_TYPE_SUBTITLE,
289  .id = AV_CODEC_ID_SUBRIP,
290  .priv_data_size = sizeof(SRTContext),
291  .init = srt_encode_init,
292  .encode_sub = srt_encode_frame,
293  .close = srt_encode_close,
294 };
295 #endif
SRT_STACK_SIZE
#define SRT_STACK_SIZE
Definition: srtenc.c:30
ASSDialog::style
char * style
name of the ASSStyle to use with this dialog
Definition: ass_split.h:75
NULL
#define NULL
Definition: coverity.c:32
s
const char * s
Definition: avisynth_c.h:631
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
ASSDialog
fields extracted from the [Events] section
Definition: ass_split.h:71
init
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
ff_ass_split
ASSSplitContext * ff_ass_split(const char *buf)
Split a full ASS file or a ASS header from a string buffer and store the split structure in a newly a...
Definition: ass_split.c:356
srt_callbacks
static const ASSCodesCallbacks srt_callbacks
Definition: srtenc.c:211
srt_encode_init
static av_cold int srt_encode_init(AVCodecContext *avctx)
Definition: srtenc.c:133
SRTContext
Definition: srtenc.c:32
srt_encode_frame
static int srt_encode_frame(AVCodecContext *avctx, unsigned char *buf, int bufsize, const AVSubtitle *sub)
Definition: srtenc.c:224
AVSubtitle::num_rects
unsigned num_rects
Definition: avcodec.h:3511
AVCodec
AVCodec.
Definition: avcodec.h:3181
av_bprint_finalize
int av_bprint_finalize(AVBPrint *buf, char **ret_str)
Finalize a print buffer.
Definition: bprint.c:235
AVSubtitle::rects
AVSubtitleRect ** rects
Definition: avcodec.h:3512
ASSDialog::text
char * text
actual text which will be displayed as a subtitle, can include style override control codes (see ff_a...
Definition: ass_split.h:81
ASSStyle::alignment
int alignment
position of the text (left, center, top...), defined after the layout of the numpad (1-3 sub...
Definition: ass_split.h:58
ASSSplitContext
This struct can be casted to ASS to access to the split data.
Definition: ass_split.c:197
ASS_DEFAULT_ALIGNMENT
#define ASS_DEFAULT_ALIGNMENT
Definition: ass.h:42
av_cold
#define av_cold
Definition: attributes.h:74
srt_stack_pop
static char srt_stack_pop(SRTContext *s)
Definition: srtenc.c:61
srt_font_size_cb
static void srt_font_size_cb(void *priv, int size)
Definition: srtenc.c:177
ASSStyle::bold
int bold
whether text is bold (1) or not (0)
Definition: ass_split.h:47
SRTContext::stack_ptr
int stack_ptr
Definition: srtenc.c:37
ff_ass_split_override_codes
int ff_ass_split_override_codes(const ASSCodesCallbacks *callbacks, void *priv, const char *buf)
Split override codes out of a ASS "Dialogue" Text field.
Definition: ass_split.c:423
av_bprint_append_data
void av_bprint_append_data(AVBPrint *buf, const char *data, unsigned size)
Append data to a print buffer.
Definition: bprint.c:158
tag
uint32_t tag
Definition: movenc.c:1333
srt_encode_close
static int srt_encode_close(AVCodecContext *avctx)
Definition: srtenc.c:262
size
ptrdiff_t size
Definition: opengl_enc.c:101
ff_ass_split_dialog
ASSDialog * ff_ass_split_dialog(ASSSplitContext *ctx, const char *buf, int cache, int *number)
Split one or several ASS "Dialogue" lines from a string buffer and store them in a already initialize...
Definition: ass_split.c:391
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
SRTContext::alignment_applied
int alignment_applied
Definition: srtenc.c:38
SRTContext::avctx
AVCodecContext * avctx
Definition: srtenc.c:33
ASS_DEFAULT_UNDERLINE
#define ASS_DEFAULT_UNDERLINE
Definition: ass.h:41
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
AV_BPRINT_SIZE_UNLIMITED
#define AV_BPRINT_SIZE_UNLIMITED
AVERROR
#define AVERROR(e)
Definition: error.h:43
ASS_DEFAULT_FONT
#define ASS_DEFAULT_FONT
Definition: ass.h:35
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:175
av_bprint_init
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
Definition: bprint.c:69
t1
#define t1
Definition: regdef.h:29
ASSStyle::font_size
int font_size
font height
Definition: ass_split.h:42
AVCodec::name
const char * name
Name of the codec implementation.
Definition: avcodec.h:3188
avcodec.h
Libavcodec external API header.
ASS_DEFAULT_FONT_SIZE
#define ASS_DEFAULT_FONT_SIZE
Definition: ass.h:36
SRTContext::stack
char stack[SRT_STACK_SIZE]
Definition: srtenc.c:36
srt_color_cb
static void srt_color_cb(void *priv, unsigned int color, unsigned int color_id)
Definition: srtenc.c:160
srt_close_tag
static void srt_close_tag(SRTContext *s, char tag)
Definition: srtenc.c:77
ASSCodesCallbacks::text
void(* text)(void *priv, const char *text, int len)
Definition: ass_split.h:144
srt_move_cb
static void srt_move_cb(void *priv, int x1, int y1, int x2, int y2, int t1, int t2)
Definition: srtenc.c:199
srt_stack_push
static int srt_stack_push(SRTContext *s, const char c)
Definition: srtenc.c:53
ASSStyle::italic
int italic
whether text is italic (1) or not (0)
Definition: ass_split.h:48
av_bprint_is_complete
static int av_bprint_is_complete(const AVBPrint *buf)
Test if the print buffer is complete (not truncated).
Definition: bprint.h:185
ASSCodesCallbacks
Set of callback functions corresponding to each override codes that can be encountered in a "Dialogue...
Definition: ass_split.h:139
srt_style_apply
static void srt_style_apply(SRTContext *s, const char *style)
Definition: srtenc.c:94
ASSStyle::primary_color
int primary_color
color that a subtitle will normally appear in
Definition: ass_split.h:43
AVCodecContext
main external API structure.
Definition: avcodec.h:1241
SRTContext::ass_ctx
ASSSplitContext * ass_ctx
Definition: srtenc.c:34
buf
void * buf
Definition: avisynth_c.h:553
av_vbprintf
void av_vbprintf(AVBPrint *buf, const char *fmt, va_list vl_arg)
Append a formatted string to a print buffer.
Definition: bprint.c:117
srt_cancel_overrides_cb
static void srt_cancel_overrides_cb(void *priv, const char *style)
Definition: srtenc.c:193
ASSStyle::font_name
char * font_name
font face (case sensitive)
Definition: ass_split.h:41
ASSStyle
fields extracted from the [V4(+) Styles] section
Definition: ass_split.h:39
ff_ass_style_get
ASSStyle * ff_ass_style_get(ASSSplitContext *ctx, const char *style)
Find an ASSStyle structure by its name.
Definition: ass_split.c:518
srt_style_cb
static void srt_style_cb(void *priv, char style, int close)
Definition: srtenc.c:153
av_bprint_clear
void av_bprint_clear(AVBPrint *buf)
Reset the string to "" but keep internal allocated data.
Definition: bprint.c:227
srt_font_name_cb
static void srt_font_name_cb(void *priv, const char *name)
Definition: srtenc.c:170
SRTContext::buffer
AVBPrint buffer
Definition: srtenc.c:35
ASS_DEFAULT_COLOR
#define ASS_DEFAULT_COLOR
Definition: ass.h:37
c
static double c[64]
Definition: vsrc_mptestsrc.c:87
srt_new_line_cb
static void srt_new_line_cb(void *priv, int forced)
Definition: srtenc.c:148
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:1283
SUBTITLE_ASS
Formatted text, the ass field must be set by the decoder and is authoritative.
Definition: avcodec.h:3476
ASS_DEFAULT_ITALIC
#define ASS_DEFAULT_ITALIC
Definition: ass.h:40
srt_stack_find
static int srt_stack_find(SRTContext *s, const char c)
Definition: srtenc.c:68
srt_print
static void srt_print(SRTContext *s, const char *str,...)
Definition: srtenc.c:45
len
int len
Definition: vorbis_enc_data.h:452
ASS_DEFAULT_BOLD
#define ASS_DEFAULT_BOLD
Definition: ass.h:39
AVSubtitleRect::ass
char * ass
0 terminated ASS/SSA compatible event line.
Definition: avcodec.h:3502
srt_alignment_cb
static void srt_alignment_cb(void *priv, int alignment)
Definition: srtenc.c:184
ff_ass_split_free
void ff_ass_split_free(ASSSplitContext *ctx)
Free all the memory allocated for an ASSSplitContext.
Definition: ass_split.c:410
srt_text_cb
static void srt_text_cb(void *priv, const char *text, int len)
Definition: srtenc.c:142
srt_end_cb
static void srt_end_cb(void *priv)
Definition: srtenc.c:206
AVSubtitleRect::type
enum AVSubtitleType type
Definition: avcodec.h:3493
t2
#define t2
Definition: regdef.h:30
ASSStyle::underline
int underline
whether text is underlined (1) or not (0)
Definition: ass_split.h:49
srt_stack_push_pop
static void srt_stack_push_pop(SRTContext *s, const char c, int close)
Definition: srtenc.c:82
name
const char * name
Definition: opengl_enc.c:103
AVCodecContext::subtitle_header
uint8_t * subtitle_header
Header containing style information for text subtitles.
Definition: avcodec.h:2957

Generated on Wed Jun 10 2015 01:56:49 for FFmpeg by   doxygen 1.8.6

AltStyle によって変換されたページ (->オリジナル) /