Commit | Line | Data |
---|---|---|
2ba45a60 DM |
1 | /* |
2 | * Copyright (c) 2012 Clément Bœsch | |
3 | * | |
4 | * This file is part of FFmpeg. | |
5 | * | |
6 | * FFmpeg is free software; you can redistribute it and/or | |
7 | * modify it under the terms of the GNU Lesser General Public | |
8 | * License as published by the Free Software Foundation; either | |
9 | * version 2.1 of the License, or (at your option) any later version. | |
10 | * | |
11 | * FFmpeg is distributed in the hope that it will be useful, | |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 | * Lesser General Public License for more details. | |
15 | * | |
16 | * You should have received a copy of the GNU Lesser General Public | |
17 | * License along with FFmpeg; if not, write to the Free Software | |
18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
19 | */ | |
20 | ||
21 | /** | |
22 | * @file | |
23 | * Raw subtitles decoder | |
24 | */ | |
25 | ||
26 | #include "avcodec.h" | |
27 | #include "ass.h" | |
28 | #include "libavutil/bprint.h" | |
29 | #include "libavutil/opt.h" | |
30 | ||
31 | typedef struct { | |
32 | AVClass *class; | |
33 | const char *linebreaks; | |
34 | int keep_ass_markup; | |
35 | } TextContext; | |
36 | ||
37 | #define OFFSET(x) offsetof(TextContext, x) | |
38 | #define SD AV_OPT_FLAG_SUBTITLE_PARAM | AV_OPT_FLAG_DECODING_PARAM | |
39 | static const AVOption options[] = { | |
40 | { "keep_ass_markup", "Set if ASS tags must be escaped", OFFSET(keep_ass_markup), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, .flags=SD }, | |
41 | { NULL } | |
42 | }; | |
43 | ||
44 | static int text_decode_frame(AVCodecContext *avctx, void *data, | |
45 | int *got_sub_ptr, AVPacket *avpkt) | |
46 | { | |
f6fa7814 | 47 | int ret = 0; |
2ba45a60 DM |
48 | AVBPrint buf; |
49 | AVSubtitle *sub = data; | |
50 | const char *ptr = avpkt->data; | |
51 | const TextContext *text = avctx->priv_data; | |
52 | const int ts_start = av_rescale_q(avpkt->pts, avctx->time_base, (AVRational){1,100}); | |
53 | const int ts_duration = avpkt->duration != -1 ? | |
54 | av_rescale_q(avpkt->duration, avctx->time_base, (AVRational){1,100}) : -1; | |
55 | ||
56 | av_bprint_init(&buf, 0, AV_BPRINT_SIZE_UNLIMITED); | |
57 | if (ptr && avpkt->size > 0 && *ptr) { | |
58 | ff_ass_bprint_text_event(&buf, ptr, avpkt->size, text->linebreaks, text->keep_ass_markup); | |
f6fa7814 | 59 | ret = ff_ass_add_rect_bprint(sub, &buf, ts_start, ts_duration); |
2ba45a60 | 60 | } |
2ba45a60 | 61 | av_bprint_finalize(&buf, NULL); |
f6fa7814 DM |
62 | if (ret < 0) |
63 | return ret; | |
64 | *got_sub_ptr = sub->num_rects > 0; | |
2ba45a60 DM |
65 | return avpkt->size; |
66 | } | |
67 | ||
68 | #define DECLARE_CLASS(decname) static const AVClass decname ## _decoder_class = { \ | |
69 | .class_name = #decname " decoder", \ | |
70 | .item_name = av_default_item_name, \ | |
71 | .option = decname ## _options, \ | |
72 | .version = LIBAVUTIL_VERSION_INT, \ | |
73 | } | |
74 | ||
75 | #if CONFIG_TEXT_DECODER | |
76 | #define text_options options | |
77 | DECLARE_CLASS(text); | |
78 | ||
79 | AVCodec ff_text_decoder = { | |
80 | .name = "text", | |
81 | .long_name = NULL_IF_CONFIG_SMALL("Raw text subtitle"), | |
82 | .priv_data_size = sizeof(TextContext), | |
83 | .type = AVMEDIA_TYPE_SUBTITLE, | |
84 | .id = AV_CODEC_ID_TEXT, | |
85 | .decode = text_decode_frame, | |
86 | .init = ff_ass_subtitle_header_default, | |
87 | .priv_class = &text_decoder_class, | |
88 | }; | |
89 | #endif | |
90 | ||
f6fa7814 | 91 | #if CONFIG_VPLAYER_DECODER || CONFIG_PJS_DECODER || CONFIG_SUBVIEWER1_DECODER || CONFIG_STL_DECODER |
2ba45a60 DM |
92 | |
93 | static int linebreak_init(AVCodecContext *avctx) | |
94 | { | |
95 | TextContext *text = avctx->priv_data; | |
96 | text->linebreaks = "|"; | |
97 | return ff_ass_subtitle_header_default(avctx); | |
98 | } | |
99 | ||
100 | #if CONFIG_VPLAYER_DECODER | |
101 | #define vplayer_options options | |
102 | DECLARE_CLASS(vplayer); | |
103 | ||
104 | AVCodec ff_vplayer_decoder = { | |
105 | .name = "vplayer", | |
106 | .long_name = NULL_IF_CONFIG_SMALL("VPlayer subtitle"), | |
107 | .priv_data_size = sizeof(TextContext), | |
108 | .type = AVMEDIA_TYPE_SUBTITLE, | |
109 | .id = AV_CODEC_ID_VPLAYER, | |
110 | .decode = text_decode_frame, | |
111 | .init = linebreak_init, | |
112 | .priv_class = &vplayer_decoder_class, | |
f6fa7814 DM |
113 | }; |
114 | #endif | |
115 | ||
116 | #if CONFIG_STL_DECODER | |
117 | #define stl_options options | |
118 | DECLARE_CLASS(stl); | |
119 | ||
120 | AVCodec ff_stl_decoder = { | |
121 | .name = "stl", | |
122 | .long_name = NULL_IF_CONFIG_SMALL("Spruce subtitle format"), | |
123 | .priv_data_size = sizeof(TextContext), | |
124 | .type = AVMEDIA_TYPE_SUBTITLE, | |
125 | .id = AV_CODEC_ID_STL, | |
126 | .decode = text_decode_frame, | |
127 | .init = linebreak_init, | |
128 | .priv_class = &stl_decoder_class, | |
2ba45a60 DM |
129 | }; |
130 | #endif | |
131 | ||
132 | #if CONFIG_PJS_DECODER | |
133 | #define pjs_options options | |
134 | DECLARE_CLASS(pjs); | |
135 | ||
136 | AVCodec ff_pjs_decoder = { | |
137 | .name = "pjs", | |
138 | .long_name = NULL_IF_CONFIG_SMALL("PJS subtitle"), | |
139 | .priv_data_size = sizeof(TextContext), | |
140 | .type = AVMEDIA_TYPE_SUBTITLE, | |
141 | .id = AV_CODEC_ID_PJS, | |
142 | .decode = text_decode_frame, | |
143 | .init = linebreak_init, | |
144 | .priv_class = &pjs_decoder_class, | |
145 | }; | |
146 | #endif | |
147 | ||
148 | #if CONFIG_SUBVIEWER1_DECODER | |
149 | #define subviewer1_options options | |
150 | DECLARE_CLASS(subviewer1); | |
151 | ||
152 | AVCodec ff_subviewer1_decoder = { | |
153 | .name = "subviewer1", | |
154 | .long_name = NULL_IF_CONFIG_SMALL("SubViewer1 subtitle"), | |
155 | .priv_data_size = sizeof(TextContext), | |
156 | .type = AVMEDIA_TYPE_SUBTITLE, | |
157 | .id = AV_CODEC_ID_SUBVIEWER1, | |
158 | .decode = text_decode_frame, | |
159 | .init = linebreak_init, | |
160 | .priv_class = &subviewer1_decoder_class, | |
161 | }; | |
162 | #endif | |
163 | ||
164 | #endif /* text subtitles with '|' line break */ |