1
/***************************************************************************
3
* This program is free software; you can redistribute it and/or modify *
4
* it under the terms of the GNU General Public License as published by *
5
* the Free Software Foundation; either version 2 of the License, or *
6
* (at your option) any later version. *
8
***************************************************************************/
10
Initial port from MPlayer by Moonz
16
#include "ADM_assert.h"
24
#include "ADM_toolkit/toolkit.hxx"
25
#include "ADM_editor/ADM_edit.hxx"
26
#include "ADM_video/ADM_genvideo.hxx"
27
#include "ADM_video/ADM_vidCommonFilter.h"
28
#include "ADM_video/ADM_vidASS.h"
29
#include "ADM_filter/video_filters.h"
30
#include "ADM_colorspace/ADM_rgb.h"
42
static FILTER_PARAM assParam={7,
43
{ /* float */ "font_scale",
44
/*float*/ "line_spacing",
45
/* int */ "top_margin",
46
/* int */ "bottom_margin",
47
/* bool */ "extract_embedded_fonts",
48
/* ADM_filename */ "fonts_dir",
49
/* ADM_filename */ "subfile" }};
51
SCRIPT_CREATE(ass_script,ADMVideoSubASS,assParam);
52
BUILD_CREATE(ass_create,ADMVideoSubASS);
54
char *ADMVideoSubASS::printConf()
57
sprintf((char *)buf," ASS/SSA Subtitles: ");
59
char *filename = (char*)_params->subfile;
62
if(strrchr(filename, DIR_SEP) != NULL && *(strrchr(filename, DIR_SEP) + 1) != 0)
63
filename = strrchr(filename, DIR_SEP) + 1;
64
strncat(buf, filename, 49-strlen(buf));
68
strcat(buf," (no sub)");
73
//_______________________________________________________________
75
ADMVideoSubASS::ADMVideoSubASS(AVDMGenericVideoStream *in, CONFcouple *conf)
78
memcpy(&_info,_in->getInfo(),sizeof(_info));
79
_params = new ASSParams;
86
#define _COUPLE_GET(x) conf->getCouple(#x, &(_params->x));
87
_COUPLE_GET(font_scale)
88
_COUPLE_GET(line_spacing)
89
_COUPLE_GET(top_margin)
90
_COUPLE_GET(bottom_margin)
92
_COUPLE_GET(fonts_dir)
93
_COUPLE_GET(extract_embedded_fonts)
96
_params->font_scale = 1.;
97
_params->line_spacing = _params->top_margin = _params->bottom_margin = 0;
98
_params->subfile = NULL;
99
_params->fonts_dir = (ADM_filename*)ADM_alloc(6*sizeof(ADM_filename));
100
strcpy((char*)_params->fonts_dir, "/tmp/");
101
_params->extract_embedded_fonts = 1;
104
ADM_dealloc(_params->subfile);
105
_params->subfile = (ADM_filename*)ADM_alloc(sizeof(ADM_filename)*21);
106
strcpy((char*)_params->subfile, "/home/moonz/test.ass");
110
_uncompressed=new ADMImage(_in->getInfo()->width,_in->getInfo()->height);
111
ADM_assert(_uncompressed);
114
/* ASS initialization */
120
GUI_Error_HIG("Format ?","Are you sure this is an ass file ?");
124
// **********************************
125
uint8_t ADMVideoSubASS::init(void)
127
_ass_t = ass_read_file((char*)_params->subfile);
135
ass_settings_t settings;
136
memcpy(&_info,_in->getInfo(),sizeof(_info));
137
_info.height += _params->top_margin + _params->bottom_margin;
138
settings.frame_width = _info.width;
139
settings.frame_height = _info.height;
140
settings.font_size_coeff = _params->font_scale;
141
settings.line_spacing = _params->line_spacing;
142
settings.top_margin = _params->top_margin;
143
settings.bottom_margin = _params->bottom_margin;
144
settings.aspect = ((double)_info.width) / ((double)_info.height);
145
ass_configure(_ass_i, &settings);
150
//*******************************************
151
ADMVideoSubASS::~ADMVideoSubASS()
153
if(_uncompressed) DELETE(_uncompressed);
157
DELETE(_params->subfile);
158
DELETE( _params->fonts_dir);
162
//*******************************************
163
#define _r(c) ((c)>>24)
164
#define _g(c) (((c)>>16)&0xFF)
165
#define _b(c) (((c)>>8)&0xFF)
166
#define _a(c) ((c)&0xFF)
167
#define rgba2y(c) ( (( 263*_r(c) + 516*_g(c) + 100*_b(c)) >> 10) + 16 )
168
#define rgba2u(c) ( (( 450*_r(c) - 376*_g(c) - 73*_b(c)) >> 10) + 128 )
169
#define rgba2v(c) ( ((-152*_r(c) - 298*_g(c) + 450*_b(c)) >> 10) + 128 )
171
uint8_t ADMVideoSubASS::getFrameNumberNoAlloc(uint32_t frame, uint32_t *len, ADMImage *data, uint32_t *flags)
173
uint32_t i, j, k, l, val;
174
uint8_t y, u, v, opacity;
175
int32_t orig_u, orig_v,klong,newu,newv;
177
uint8_t *bitmap, *ydata, *udata, *vdata;
179
if(frame>=_info.nb_frames)
181
printf("[SubAss] out of bound %u/%u\n",frame,_info.nb_frames);
185
int64_t where = (int64_t)(_info.orgFrame + frame) * 1000000LL /
186
(int64_t)_info.fps1000;
188
if(!_in->getFrameNumberNoAlloc(frame, len, _uncompressed, flags))
191
/* Add black borders top / bottom*/
193
uint32_t page=_info.width*_info.height;
194
uint32_t top, bottom;
195
top=_info.width * (_params->top_margin &0xfffe);
200
memset(YPLANE(data),16,top);
201
memset(UPLANE(data),128,top>>2);
202
memset(VPLANE(data),128,top>>2);
204
memcpy(YPLANE(data) + top, YPLANE(_uncompressed),page-top);
205
memcpy(UPLANE(data) + (top>>2), UPLANE(_uncompressed), (page-top)>>2);
206
memcpy(VPLANE(data) + (top>>2), VPLANE(_uncompressed), (page-top)>>2);
209
top=_info.width * (_params->bottom_margin&0xfffe);
213
memset(YPLANE(data)+page-top,16,top);
214
memset(UPLANE(data)+((page-top)>>2),128,top>>2);
215
memset(VPLANE(data)+((page-top)>>2),128,top>>2);
217
// Do we have something to render ?
218
if(!_ass_i || !_ass_t)
220
printf("[Ass] No sub to render\n");
224
ass_image_t *img = ass_render_frame(_ass_i, _ass_t, where);
227
y = rgba2y(img->color);
228
u = rgba2u(img->color);
229
v = rgba2v(img->color);
231
opacity = 255 - _a(img->color);
233
bitmap = img->bitmap;
235
uint32_t offset=img->dst_y * _info.width +img->dst_x;
236
uint32_t offset2=(img->dst_y>>1) * (_info.width>>1)+(img->dst_x >> 1);
238
ydata = YPLANE(data) + offset ;
239
udata = UPLANE(data) + offset2 ;
240
vdata = VPLANE(data) + offset2 ;
242
for(i = 0; i < img->h; ++i)
244
for(j = 0; j < img->w; ++j)
246
k = *(bitmap+j) * opacity / 255;
248
*(ydata+j) = (k*y + (255-k)*orig_y) / 255;
251
bitmap += img->stride;
252
ydata += _info.width;
255
bitmap = img->bitmap;
260
for(i = 0; i < img->h; i += 2)
262
for(j = 0, l = 0; j < img->w; j += 2, ++l)
265
val += *(bitmap + j);
266
val += *(bitmap + j + 1);
267
val += *(bitmap + img->stride + j);
268
val += *(bitmap + img->stride + j + 1);
271
k = val * opacity / 255;
275
orig_u=( k*u+(255-k)*orig_u)/255;
276
orig_v=( k*v+(255-k)*orig_v)/255;
281
bitmap += img->stride << 1;
282
udata += _info.width >> 1;
283
vdata += _info.width >> 1;
292
uint8_t ADMVideoSubASS::getCoupledConf(CONFcouple **conf)
294
*conf=new CONFcouple(7);
296
#define _COUPLE_SET(x) (*conf)->setCouple(#x, _params->x);
297
_COUPLE_SET(font_scale)
298
_COUPLE_SET(line_spacing)
299
_COUPLE_SET(top_margin)
300
_COUPLE_SET(bottom_margin)
302
_COUPLE_SET(fonts_dir)
303
_COUPLE_SET(extract_embedded_fonts)
307
/************************************************/
308
extern uint8_t DIA_ass(ASSParams *param);
309
uint8_t ADMVideoSubASS::configure(AVDMGenericVideoStream *instream)
312
if( DIA_ass(_params))
319
#endif /* HAVE_ENCODER */
320
#endif /* USE_FREETYPE */