Mercurial > mplayer.hg
annotate libmpcodecs/vf_ass.c @ 32142:4614728cab25
build system: Merge all FFmpeg library checks into a single FFmpeg check.
There is little point in assuming that some parts of FFmpeg might be
available without the others. Plus, mixing and matching static and
shared FFmpeg libraries was never supported.
author | diego |
---|---|
date | Mon, 13 Sep 2010 18:19:25 +0000 |
parents | 4c2bbab833d1 |
children | ef21cbba62ee |
rev | line source |
---|---|
20008
fa122b7c71c6
Add copyright notice and vim/emacs comments to libass and vf_ass.c.
eugeni
parents:
19563
diff
changeset
|
1 /* |
26727 | 2 * Copyright (C) 2006 Evgeniy Stepanov <eugeni.stepanov@gmail.com> |
3 * | |
4 * This file is part of MPlayer. | |
5 * | |
6 * MPlayer is free software; you can redistribute it and/or modify | |
7 * it under the terms of the GNU General Public License as published by | |
8 * the Free Software Foundation; either version 2 of the License, or | |
9 * (at your option) any later version. | |
10 * | |
11 * MPlayer 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 | |
14 * GNU General Public License for more details. | |
15 * | |
16 * You should have received a copy of the GNU General Public License along | |
17 * with MPlayer; if not, write to the Free Software Foundation, Inc., | |
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | |
19 */ | |
20008
fa122b7c71c6
Add copyright notice and vim/emacs comments to libass and vf_ass.c.
eugeni
parents:
19563
diff
changeset
|
20 |
18937 | 21 #include "config.h" |
22 | |
23 #include <stdio.h> | |
24 #include <stdlib.h> | |
25 #include <string.h> | |
24545
9e5126679d44
Replace stdint.h #include by functionally equivalent inttypes.h.
diego
parents:
23134
diff
changeset
|
26 #include <inttypes.h> |
18937 | 27 #include <assert.h> |
28 | |
29 #include "config.h" | |
30 #include "mp_msg.h" | |
31 #include "help_mp.h" | |
31489 | 32 #include "mpcommon.h" |
18937 | 33 #include "img_format.h" |
34 #include "mp_image.h" | |
30653
3d23e24c5c60
Declare externally used variables from vd.c as extern in vd.h.
diego
parents:
30642
diff
changeset
|
35 #include "vd.h" |
18937 | 36 #include "vf.h" |
37 | |
38 #include "libvo/fastmemcpy.h" | |
31488
4b738166e825
Add libvo/sub.h #include instead of declaring sub_visibility extern.
diego
parents:
31238
diff
changeset
|
39 #include "libvo/sub.h" |
31927 | 40 #include "libvo/video_out.h" |
18937 | 41 #include "m_option.h" |
42 #include "m_struct.h" | |
43 | |
44 #include "libass/ass_mp.h" | |
31927 | 45 #include "eosd.h" |
18937 | 46 |
47 #define _r(c) ((c)>>24) | |
48 #define _g(c) (((c)>>16)&0xFF) | |
49 #define _b(c) (((c)>>8)&0xFF) | |
50 #define _a(c) ((c)&0xFF) | |
32096 | 51 #define rgba2y(c) ( (( 263*_r(c) + 516*_g(c) + 100*_b(c)) >> 10) + 16 ) |
18937 | 52 #define rgba2u(c) ( ((-152*_r(c) - 298*_g(c) + 450*_b(c)) >> 10) + 128 ) |
53 #define rgba2v(c) ( (( 450*_r(c) - 376*_g(c) - 73*_b(c)) >> 10) + 128 ) | |
54 | |
55 | |
24969
c2b7ba444ade
begin moving const filter data to .text/.rodata sections
rfelker
parents:
24545
diff
changeset
|
56 static const struct vf_priv_s { |
32096 | 57 int outh, outw; |
18937 | 58 |
32096 | 59 unsigned int outfmt; |
18937 | 60 |
32096 | 61 // 1 = auto-added filter: insert only if chain does not support EOSD already |
62 // 0 = insert always | |
63 int auto_insert; | |
18937 | 64 |
32096 | 65 unsigned char *planes[3]; |
66 unsigned char *dirty_rows; | |
24969
c2b7ba444ade
begin moving const filter data to .text/.rodata sections
rfelker
parents:
24545
diff
changeset
|
67 } vf_priv_dflt; |
18937 | 68 |
69 | |
30642
a972c1a4a012
cosmetics: Rename struct vf_instance_s --> vf_instance.
diego
parents:
30638
diff
changeset
|
70 static int config(struct vf_instance *vf, |
32096 | 71 int width, int height, int d_width, int d_height, |
72 unsigned int flags, unsigned int outfmt) | |
18937 | 73 { |
32096 | 74 mp_eosd_res_t res = { 0 }; |
31927 | 75 |
32096 | 76 if (outfmt == IMGFMT_IF09) |
77 return 0; | |
18937 | 78 |
32096 | 79 vf->priv->outh = height + ass_top_margin + ass_bottom_margin; |
80 vf->priv->outw = width; | |
18937 | 81 |
32096 | 82 if (!opt_screen_size_x && !opt_screen_size_y) { |
83 d_width = d_width * vf->priv->outw / width; | |
84 d_height = d_height * vf->priv->outh / height; | |
85 } | |
18937 | 86 |
32096 | 87 vf->priv->planes[1] = malloc(vf->priv->outw * vf->priv->outh); |
88 vf->priv->planes[2] = malloc(vf->priv->outw * vf->priv->outh); | |
89 vf->priv->dirty_rows = malloc(vf->priv->outh); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26727
diff
changeset
|
90 |
32096 | 91 res.w = vf->priv->outw; |
92 res.h = vf->priv->outh; | |
93 res.srcw = width; | |
94 res.srch = height; | |
95 res.mt = ass_top_margin; | |
96 res.mb = ass_bottom_margin; | |
97 eosd_configure(&res, 0); | |
18937 | 98 |
32096 | 99 return vf_next_config(vf, vf->priv->outw, vf->priv->outh, d_width, |
100 d_height, flags, outfmt); | |
18937 | 101 } |
102 | |
30642
a972c1a4a012
cosmetics: Rename struct vf_instance_s --> vf_instance.
diego
parents:
30638
diff
changeset
|
103 static void get_image(struct vf_instance *vf, mp_image_t *mpi) |
18937 | 104 { |
32096 | 105 if (mpi->type == MP_IMGTYPE_IPB) |
106 return; | |
107 if (mpi->flags & MP_IMGFLAG_PRESERVE) | |
108 return; | |
109 if (mpi->imgfmt != vf->priv->outfmt) | |
110 return; // colorspace differ | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26727
diff
changeset
|
111 |
32096 | 112 // width never changes, always try full DR |
113 mpi->priv = vf->dmpi = vf_get_image(vf->next, mpi->imgfmt, mpi->type, | |
114 mpi->flags | MP_IMGFLAG_READABLE, | |
115 vf->priv->outw, vf->priv->outh); | |
18937 | 116 |
32096 | 117 if ( (vf->dmpi->flags & MP_IMGFLAG_DRAW_CALLBACK) && |
118 !(vf->dmpi->flags & MP_IMGFLAG_DIRECT)) { | |
119 mp_msg(MSGT_ASS, MSGL_INFO, MSGTR_MPCODECS_FullDRNotPossible); | |
120 return; | |
121 } | |
122 // set up mpi as a cropped-down image of dmpi: | |
123 if (mpi->flags & MP_IMGFLAG_PLANAR) { | |
124 mpi->planes[0] = vf->dmpi->planes[0] + ass_top_margin * vf->dmpi->stride[0]; | |
125 mpi->planes[1] = vf->dmpi->planes[1] + (ass_top_margin >> mpi->chroma_y_shift) * vf->dmpi->stride[1]; | |
126 mpi->planes[2] = vf->dmpi->planes[2] + (ass_top_margin >> mpi->chroma_y_shift) * vf->dmpi->stride[2]; | |
127 mpi->stride[1] = vf->dmpi->stride[1]; | |
128 mpi->stride[2] = vf->dmpi->stride[2]; | |
129 } else { | |
130 mpi->planes[0] = vf->dmpi->planes[0] + ass_top_margin * vf->dmpi->stride[0]; | |
131 } | |
132 mpi->stride[0] = vf->dmpi->stride[0]; | |
133 mpi->width = vf->dmpi->width; | |
134 mpi->flags |= MP_IMGFLAG_DIRECT; | |
135 mpi->flags &= ~MP_IMGFLAG_DRAW_CALLBACK; | |
136 // vf->dmpi->flags &= ~MP_IMGFLAG_DRAW_CALLBACK; | |
18937 | 137 } |
138 | |
139 static void blank(mp_image_t *mpi, int y1, int y2) | |
140 { | |
32096 | 141 int color[3] = { 16, 128, 128 }; // black (YUV) |
142 int y; | |
143 unsigned char *dst; | |
144 int chroma_rows = (y2 - y1) >> mpi->chroma_y_shift; | |
18937 | 145 |
32096 | 146 dst = mpi->planes[0] + y1 * mpi->stride[0]; |
147 for (y = 0; y < y2 - y1; ++y) { | |
148 memset(dst, color[0], mpi->w); | |
149 dst += mpi->stride[0]; | |
150 } | |
151 dst = mpi->planes[1] + (y1 >> mpi->chroma_y_shift) * mpi->stride[1]; | |
152 for (y = 0; y < chroma_rows; ++y) { | |
153 memset(dst, color[1], mpi->chroma_width); | |
154 dst += mpi->stride[1]; | |
155 } | |
156 dst = mpi->planes[2] + (y1 >> mpi->chroma_y_shift) * mpi->stride[2]; | |
157 for (y = 0; y < chroma_rows; ++y) { | |
158 memset(dst, color[2], mpi->chroma_width); | |
159 dst += mpi->stride[2]; | |
160 } | |
18937 | 161 } |
162 | |
30642
a972c1a4a012
cosmetics: Rename struct vf_instance_s --> vf_instance.
diego
parents:
30638
diff
changeset
|
163 static int prepare_image(struct vf_instance *vf, mp_image_t *mpi) |
18937 | 164 { |
32096 | 165 if (mpi->flags & MP_IMGFLAG_DIRECT || |
166 mpi->flags & MP_IMGFLAG_DRAW_CALLBACK) { | |
167 vf->dmpi = mpi->priv; | |
168 if (!vf->dmpi) { | |
169 mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_MPCODECS_FunWhydowegetNULL); | |
170 return 0; | |
171 } | |
172 mpi->priv = NULL; | |
173 // we've used DR, so we're ready... | |
174 if (ass_top_margin) | |
175 blank(vf->dmpi, 0, ass_top_margin); | |
176 if (ass_bottom_margin) | |
177 blank(vf->dmpi, vf->priv->outh - ass_bottom_margin, vf->priv->outh); | |
178 if (!(mpi->flags & MP_IMGFLAG_PLANAR)) | |
179 vf->dmpi->planes[1] = mpi->planes[1]; // passthrough rgb8 palette | |
180 return 0; | |
181 } | |
182 // hope we'll get DR buffer: | |
183 vf->dmpi = vf_get_image(vf->next, vf->priv->outfmt, MP_IMGTYPE_TEMP, | |
184 MP_IMGFLAG_ACCEPT_STRIDE | MP_IMGFLAG_READABLE, | |
185 vf->priv->outw, vf->priv->outh); | |
18937 | 186 |
32096 | 187 // copy mpi->dmpi... |
188 if (mpi->flags & MP_IMGFLAG_PLANAR) { | |
189 memcpy_pic(vf->dmpi->planes[0] + ass_top_margin * vf->dmpi->stride[0], | |
190 mpi->planes[0], | |
191 mpi->w, | |
192 mpi->h, | |
193 vf->dmpi->stride[0], | |
194 mpi->stride[0]); | |
195 memcpy_pic(vf->dmpi->planes[1] + (ass_top_margin >> mpi->chroma_y_shift) * vf->dmpi->stride[1], | |
196 mpi->planes[1], | |
197 mpi->w >> mpi->chroma_x_shift, | |
198 mpi->h >> mpi->chroma_y_shift, | |
199 vf->dmpi->stride[1], | |
200 mpi->stride[1]); | |
201 memcpy_pic(vf->dmpi->planes[2] + (ass_top_margin >> mpi->chroma_y_shift) * vf->dmpi->stride[2], | |
202 mpi->planes[2], | |
203 mpi->w >> mpi->chroma_x_shift, | |
204 mpi->h >> mpi->chroma_y_shift, | |
205 vf->dmpi->stride[2], | |
206 mpi->stride[2]); | |
207 } else { | |
208 memcpy_pic(vf->dmpi->planes[0] + ass_top_margin * vf->dmpi->stride[0], | |
209 mpi->planes[0], | |
210 mpi->w * (vf->dmpi->bpp / 8), | |
211 mpi->h, | |
212 vf->dmpi->stride[0], | |
213 mpi->stride[0]); | |
214 vf->dmpi->planes[1] = mpi->planes[1]; // passthrough rgb8 palette | |
215 } | |
216 if (ass_top_margin) | |
217 blank(vf->dmpi, 0, ass_top_margin); | |
218 if (ass_bottom_margin) | |
219 blank(vf->dmpi, vf->priv->outh - ass_bottom_margin, vf->priv->outh); | |
220 return 0; | |
18937 | 221 } |
222 | |
223 /** | |
224 * \brief Copy specified rows from render_context.dmpi to render_context.planes, upsampling to 4:4:4 | |
225 */ | |
32096 | 226 static void copy_from_image(struct vf_instance *vf, int first_row, |
227 int last_row) | |
18937 | 228 { |
32096 | 229 int pl; |
230 int i, j, k; | |
231 unsigned char val; | |
232 int chroma_rows; | |
18937 | 233 |
32096 | 234 first_row -= (first_row % 2); |
235 last_row += (last_row % 2); | |
236 chroma_rows = (last_row - first_row) / 2; | |
18937 | 237 |
32096 | 238 assert(first_row >= 0); |
239 assert(first_row <= last_row); | |
240 assert(last_row <= vf->priv->outh); | |
29383
e9cab9f6ed62
Make sure clip coordinates are inside the screen area.
eugeni
parents:
29263
diff
changeset
|
241 |
32096 | 242 for (pl = 1; pl < 3; ++pl) { |
243 int dst_stride = vf->priv->outw; | |
244 int src_stride = vf->dmpi->stride[pl]; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26727
diff
changeset
|
245 |
32096 | 246 unsigned char *src = vf->dmpi->planes[pl] + (first_row / 2) * src_stride; |
247 unsigned char *dst = vf->priv->planes[pl] + first_row * dst_stride; | |
248 unsigned char *dst_next = dst + dst_stride; | |
249 for (i = 0; i < chroma_rows; ++i) { | |
250 if ((vf->priv->dirty_rows[first_row + i * 2 ] == 0) || | |
251 (vf->priv->dirty_rows[first_row + i * 2 + 1] == 0)) { | |
252 for (j = 0, k = 0; j < vf->dmpi->chroma_width; ++j, k += 2) { | |
253 val = *(src + j); | |
254 *(dst + k ) = val; | |
255 *(dst + k + 1) = val; | |
256 *(dst_next + k ) = val; | |
257 *(dst_next + k + 1) = val; | |
258 } | |
259 } | |
260 src += src_stride; | |
261 dst = dst_next + dst_stride; | |
262 dst_next = dst + dst_stride; | |
263 } | |
264 } | |
265 for (i = first_row; i < last_row; ++i) | |
266 vf->priv->dirty_rows[i] = 1; | |
18937 | 267 } |
268 | |
269 /** | |
270 * \brief Copy all previously copied rows back to render_context.dmpi | |
271 */ | |
30642
a972c1a4a012
cosmetics: Rename struct vf_instance_s --> vf_instance.
diego
parents:
30638
diff
changeset
|
272 static void copy_to_image(struct vf_instance *vf) |
18937 | 273 { |
32096 | 274 int pl; |
275 int i, j, k; | |
276 for (pl = 1; pl < 3; ++pl) { | |
277 int dst_stride = vf->dmpi->stride[pl]; | |
278 int src_stride = vf->priv->outw; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26727
diff
changeset
|
279 |
32096 | 280 unsigned char *dst = vf->dmpi->planes[pl]; |
281 unsigned char *src = vf->priv->planes[pl]; | |
282 unsigned char *src_next = vf->priv->planes[pl] + src_stride; | |
283 for (i = 0; i < vf->dmpi->chroma_height; ++i) { | |
284 if ((vf->priv->dirty_rows[i * 2] == 1)) { | |
285 assert(vf->priv->dirty_rows[i * 2 + 1] == 1); | |
286 for (j = 0, k = 0; j < vf->dmpi->chroma_width; ++j, k += 2) { | |
287 unsigned val = 0; | |
288 val += *(src + k); | |
289 val += *(src + k + 1); | |
290 val += *(src_next + k); | |
291 val += *(src_next + k + 1); | |
292 *(dst + j) = val >> 2; | |
293 } | |
294 } | |
295 dst += dst_stride; | |
296 src = src_next + src_stride; | |
297 src_next = src + src_stride; | |
298 } | |
299 } | |
18937 | 300 } |
301 | |
32096 | 302 static void my_draw_bitmap(struct vf_instance *vf, unsigned char *bitmap, |
303 int bitmap_w, int bitmap_h, int stride, | |
304 int dst_x, int dst_y, unsigned color) | |
18937 | 305 { |
32096 | 306 unsigned char y = rgba2y(color); |
307 unsigned char u = rgba2u(color); | |
308 unsigned char v = rgba2v(color); | |
309 unsigned char opacity = 255 - _a(color); | |
310 unsigned char *src, *dsty, *dstu, *dstv; | |
311 int i, j; | |
312 mp_image_t *dmpi = vf->dmpi; | |
18937 | 313 |
32096 | 314 src = bitmap; |
315 dsty = dmpi->planes[0] + dst_x + dst_y * dmpi->stride[0]; | |
316 dstu = vf->priv->planes[1] + dst_x + dst_y * vf->priv->outw; | |
317 dstv = vf->priv->planes[2] + dst_x + dst_y * vf->priv->outw; | |
318 for (i = 0; i < bitmap_h; ++i) { | |
319 for (j = 0; j < bitmap_w; ++j) { | |
320 unsigned k = ((unsigned) src[j]) * opacity / 255; | |
321 dsty[j] = (k * y + (255 - k) * dsty[j]) / 255; | |
322 dstu[j] = (k * u + (255 - k) * dstu[j]) / 255; | |
323 dstv[j] = (k * v + (255 - k) * dstv[j]) / 255; | |
324 } | |
325 src += stride; | |
326 dsty += dmpi->stride[0]; | |
327 dstu += vf->priv->outw; | |
328 dstv += vf->priv->outw; | |
329 } | |
18937 | 330 } |
331 | |
32096 | 332 static int render_frame(struct vf_instance *vf, mp_image_t *mpi, |
333 const ASS_Image *img) | |
18937 | 334 { |
32096 | 335 if (img) { |
336 memset(vf->priv->dirty_rows, 0, vf->priv->outh); // reset dirty rows | |
337 while (img) { | |
338 copy_from_image(vf, img->dst_y, img->dst_y + img->h); | |
339 my_draw_bitmap(vf, img->bitmap, img->w, img->h, img->stride, | |
340 img->dst_x, img->dst_y, img->color); | |
341 img = img->next; | |
342 } | |
343 copy_to_image(vf); | |
344 } | |
345 return 0; | |
18937 | 346 } |
347 | |
30642
a972c1a4a012
cosmetics: Rename struct vf_instance_s --> vf_instance.
diego
parents:
30638
diff
changeset
|
348 static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts) |
18937 | 349 { |
32096 | 350 ASS_Image *images = eosd_render_frame(pts, NULL); |
351 prepare_image(vf, mpi); | |
352 if (images) | |
353 render_frame(vf, mpi, images); | |
18937 | 354 |
32096 | 355 return vf_next_put_image(vf, vf->dmpi, pts); |
18937 | 356 } |
357 | |
30642
a972c1a4a012
cosmetics: Rename struct vf_instance_s --> vf_instance.
diego
parents:
30638
diff
changeset
|
358 static int query_format(struct vf_instance *vf, unsigned int fmt) |
18937 | 359 { |
32096 | 360 switch (fmt) { |
361 case IMGFMT_YV12: | |
362 case IMGFMT_I420: | |
363 case IMGFMT_IYUV: | |
364 return vf_next_query_format(vf, vf->priv->outfmt); | |
365 } | |
366 return 0; | |
18937 | 367 } |
368 | |
369 static int control(vf_instance_t *vf, int request, void *data) | |
370 { | |
32096 | 371 switch (request) { |
372 case VFCTRL_INIT_EOSD: | |
373 return CONTROL_TRUE; | |
374 case VFCTRL_DRAW_EOSD: | |
375 return CONTROL_TRUE; | |
376 } | |
377 return vf_next_control(vf, request, data); | |
18937 | 378 } |
379 | |
30642
a972c1a4a012
cosmetics: Rename struct vf_instance_s --> vf_instance.
diego
parents:
30638
diff
changeset
|
380 static void uninit(struct vf_instance *vf) |
18937 | 381 { |
32096 | 382 if (vf->priv->planes[1]) |
383 free(vf->priv->planes[1]); | |
384 if (vf->priv->planes[2]) | |
385 free(vf->priv->planes[2]); | |
386 if (vf->priv->dirty_rows) | |
387 free(vf->priv->dirty_rows); | |
18937 | 388 } |
389 | |
32096 | 390 static const unsigned int fmt_list[] = { |
391 IMGFMT_YV12, | |
392 IMGFMT_I420, | |
393 IMGFMT_IYUV, | |
394 0 | |
18937 | 395 }; |
396 | |
30638
a7b908875c14
Rename open() vf initialization function to vf_open().
diego
parents:
30633
diff
changeset
|
397 static int vf_open(vf_instance_t *vf, char *args) |
18937 | 398 { |
32096 | 399 int flags; |
400 vf->priv->outfmt = vf_match_csp(&vf->next, fmt_list, IMGFMT_YV12); | |
401 if (vf->priv->outfmt) | |
402 flags = vf_next_query_format(vf, vf->priv->outfmt); | |
403 if (!vf->priv->outfmt || (vf->priv->auto_insert && flags & VFCAP_EOSD)) { | |
404 uninit(vf); | |
405 return 0; | |
406 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26727
diff
changeset
|
407 |
32096 | 408 if (vf->priv->auto_insert) |
409 mp_msg(MSGT_ASS, MSGL_INFO, "[ass] auto-open\n"); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26727
diff
changeset
|
410 |
32096 | 411 vf->config = config; |
412 vf->query_format = query_format; | |
413 vf->uninit = uninit; | |
414 vf->control = control; | |
415 vf->get_image = get_image; | |
416 vf->put_image = put_image; | |
417 vf->default_caps = VFCAP_EOSD; | |
418 return 1; | |
18937 | 419 } |
420 | |
421 #define ST_OFF(f) M_ST_OFF(struct vf_priv_s,f) | |
24969
c2b7ba444ade
begin moving const filter data to .text/.rodata sections
rfelker
parents:
24545
diff
changeset
|
422 static const m_option_t vf_opts_fields[] = { |
32096 | 423 {"auto", ST_OFF(auto_insert), CONF_TYPE_FLAG, 0, 0, 1, NULL}, |
424 {NULL, NULL, 0, 0, 0, 0, NULL} | |
18937 | 425 }; |
426 | |
24969
c2b7ba444ade
begin moving const filter data to .text/.rodata sections
rfelker
parents:
24545
diff
changeset
|
427 static const m_struct_t vf_opts = { |
32096 | 428 "ass", |
429 sizeof(struct vf_priv_s), | |
430 &vf_priv_dflt, | |
431 vf_opts_fields | |
18937 | 432 }; |
433 | |
24969
c2b7ba444ade
begin moving const filter data to .text/.rodata sections
rfelker
parents:
24545
diff
changeset
|
434 const vf_info_t vf_info_ass = { |
32096 | 435 "Render ASS/SSA subtitles", |
436 "ass", | |
437 "Evgeniy Stepanov", | |
438 "", | |
439 vf_open, | |
440 &vf_opts | |
18937 | 441 }; |