~ubuntu-branches/ubuntu/feisty/avidemux/feisty

« back to all changes in this revision

Viewing changes to avidemux/ADM_video/ADM_vidASS.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Daniel T Chen
  • Date: 2006-12-15 17:13:20 UTC
  • mfrom: (1.1.6 upstream)
  • Revision ID: james.westby@ubuntu.com-20061215171320-w79pvpehxx2fr217
Tags: 1:2.3.0-0.0ubuntu1
* Merge from debian-multimedia.org, remaining Ubuntu change:
  - desktop file,
  - no support for ccache and make -j.
* Closes Ubuntu: #69614.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***************************************************************************
 
2
 *                                                                         *
 
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.                                   *
 
7
 *                                                                         *
 
8
 ***************************************************************************/
 
9
/*
 
10
  Initial port from MPlayer by Moonz
 
11
 
 
12
*/
 
13
#include <stdio.h>
 
14
#include <stdlib.h>
 
15
#include <string.h>
 
16
#include "ADM_assert.h"
 
17
 
 
18
#include "config.h"
 
19
#include "fourcc.h"
 
20
#include "avio.hxx"
 
21
#include "avi_vars.h"
 
22
#ifdef HAVE_ENCODER
 
23
 
 
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"
 
31
 
 
32
#ifdef USE_FREETYPE
 
33
 
 
34
#ifndef DIR_SEP
 
35
# ifdef WIN32
 
36
#   define DIR_SEP '\\'
 
37
# else
 
38
#   define DIR_SEP '/'
 
39
# endif
 
40
#endif
 
41
 
 
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" }};
 
50
 
 
51
SCRIPT_CREATE(ass_script,ADMVideoSubASS,assParam);
 
52
BUILD_CREATE(ass_create,ADMVideoSubASS);
 
53
 
 
54
char *ADMVideoSubASS::printConf() 
 
55
{
 
56
      static char buf[50];
 
57
      sprintf((char *)buf," ASS/SSA Subtitles: ");
 
58
      
 
59
      char *filename = (char*)_params->subfile;
 
60
      if(filename)
 
61
      {
 
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));
 
65
          buf[49] = 0;
 
66
      }else
 
67
      {
 
68
        strcat(buf," (no sub)");       
 
69
      }
 
70
      return buf;
 
71
}
 
72
 
 
73
//_______________________________________________________________
 
74
 
 
75
ADMVideoSubASS::ADMVideoSubASS(AVDMGenericVideoStream *in, CONFcouple *conf) 
 
76
{
 
77
        _in=in;         
 
78
        memcpy(&_info,_in->getInfo(),sizeof(_info));
 
79
        _params = new ASSParams;
 
80
        ADM_assert(_params);
 
81
        
 
82
        _ass_i = NULL;
 
83
        _ass_t = NULL;
 
84
        
 
85
        if(conf) {
 
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)
 
91
                _COUPLE_GET(subfile)
 
92
                _COUPLE_GET(fonts_dir)
 
93
                _COUPLE_GET(extract_embedded_fonts)
 
94
        }       
 
95
        else {
 
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;
 
102
                
 
103
                #if 0
 
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");
 
107
                #endif
 
108
        }
 
109
 
 
110
        _uncompressed=new ADMImage(_in->getInfo()->width,_in->getInfo()->height);
 
111
        ADM_assert(_uncompressed);
 
112
        _info.encoding=1;
 
113
 
 
114
        /* ASS initialization */
 
115
        _ass_i = ass_init();
 
116
        ADM_assert(_ass_i);
 
117
        if(_params->subfile)
 
118
              if(!init())
 
119
              {
 
120
                GUI_Error_HIG("Format ?","Are you sure this is an ass file ?"); 
 
121
              }
 
122
 
 
123
}
 
124
// **********************************
 
125
uint8_t ADMVideoSubASS::init(void)
 
126
{
 
127
  _ass_t = ass_read_file((char*)_params->subfile);
 
128
  if(!_ass_t)
 
129
  {
 
130
    return 0;
 
131
     
 
132
  }
 
133
  else
 
134
  {
 
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);
 
146
  }
 
147
  return 1;
 
148
}
 
149
 
 
150
//*******************************************
 
151
ADMVideoSubASS::~ADMVideoSubASS() 
 
152
{
 
153
      if(_uncompressed) DELETE(_uncompressed);
 
154
      
 
155
      if(_params) 
 
156
      {
 
157
        DELETE(_params->subfile);
 
158
        DELETE( _params->fonts_dir);
 
159
        DELETE(_params);
 
160
      }
 
161
}
 
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 )
 
170
 
 
171
uint8_t ADMVideoSubASS::getFrameNumberNoAlloc(uint32_t frame, uint32_t *len, ADMImage *data, uint32_t *flags) 
 
172
{
 
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;
 
176
        uint8_t orig_y;
 
177
        uint8_t *bitmap, *ydata, *udata, *vdata;
 
178
 
 
179
        if(frame>=_info.nb_frames)
 
180
        {
 
181
          printf("[SubAss] out of bound %u/%u\n",frame,_info.nb_frames); 
 
182
        }
 
183
        ADM_assert(_params);
 
184
 
 
185
        int64_t  where = (int64_t)(_info.orgFrame + frame) * 1000000LL /
 
186
                          (int64_t)_info.fps1000;
 
187
 
 
188
        if(!_in->getFrameNumberNoAlloc(frame, len, _uncompressed, flags))
 
189
                return 0;
 
190
 
 
191
        /* Add black borders top / bottom*/
 
192
 
 
193
        uint32_t page=_info.width*_info.height;
 
194
        uint32_t top, bottom;
 
195
        top=_info.width * (_params->top_margin &0xfffe);
 
196
        if(top>page) top=0;
 
197
        
 
198
        if(top)
 
199
        {
 
200
            memset(YPLANE(data),16,top);
 
201
            memset(UPLANE(data),128,top>>2);
 
202
            memset(VPLANE(data),128,top>>2);
 
203
        }
 
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);
 
207
 
 
208
        // Now do bottom
 
209
        top=_info.width * (_params->bottom_margin&0xfffe);
 
210
        if(top>page) top=0;
 
211
        if(top)
 
212
        {
 
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);
 
216
        }
 
217
        // Do we have something to render ?
 
218
        if(!_ass_i || !_ass_t)
 
219
        {
 
220
          printf("[Ass] No sub to render\n");
 
221
          return 1; 
 
222
        }
 
223
 
 
224
        ass_image_t *img = ass_render_frame(_ass_i, _ass_t, where);
 
225
 
 
226
        while(img) {
 
227
                  y = rgba2y(img->color);
 
228
                  u = rgba2u(img->color);
 
229
                  v = rgba2v(img->color);
 
230
 
 
231
                  opacity = 255 - _a(img->color);
 
232
 
 
233
                  bitmap = img->bitmap;
 
234
 
 
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); 
 
237
 
 
238
                  ydata = YPLANE(data) + offset ;
 
239
                  udata = UPLANE(data) + offset2 ;
 
240
                  vdata = VPLANE(data) + offset2 ;
 
241
 
 
242
                  for(i = 0; i < img->h; ++i) 
 
243
                  {
 
244
                          for(j = 0; j < img->w; ++j) 
 
245
                          {
 
246
                                  k = *(bitmap+j) * opacity / 255;
 
247
                                  orig_y = *(ydata+j);
 
248
                                  *(ydata+j) = (k*y + (255-k)*orig_y) / 255;
 
249
                          }
 
250
 
 
251
                          bitmap += img->stride;
 
252
                          ydata += _info.width;
 
253
                  }
 
254
 
 
255
                  bitmap = img->bitmap;
 
256
                  
 
257
                  newu=u-128;
 
258
                  newv=v-128;
 
259
 
 
260
                  for(i = 0; i < img->h; i += 2) 
 
261
                  {
 
262
                          for(j = 0, l = 0; j < img->w; j += 2, ++l) 
 
263
                          {
 
264
                                  val = 0;
 
265
                                  val += *(bitmap + j);
 
266
                                  val += *(bitmap + j + 1);
 
267
                                  val += *(bitmap + img->stride + j);
 
268
                                  val += *(bitmap + img->stride + j + 1);
 
269
                                  val >>= 2;
 
270
 
 
271
                                  k = val * opacity / 255;
 
272
                                  orig_u = *(udata+l);
 
273
                                  orig_v = *(vdata+l);
 
274
 
 
275
                                  orig_u=( k*u+(255-k)*orig_u)/255;
 
276
                                  orig_v=( k*v+(255-k)*orig_v)/255;
 
277
                                  *(udata+l) = orig_u;
 
278
                                  *(vdata+l) = orig_v;
 
279
                          }
 
280
 
 
281
                          bitmap += img->stride << 1;
 
282
                          udata += _info.width >> 1;
 
283
                          vdata += _info.width >> 1;
 
284
                  }
 
285
 
 
286
                  img = img->next;
 
287
        }
 
288
 
 
289
        return 1;
 
290
}
 
291
 
 
292
uint8_t ADMVideoSubASS::getCoupledConf(CONFcouple **conf) 
 
293
{
 
294
        *conf=new CONFcouple(7);
 
295
 
 
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)
 
301
        _COUPLE_SET(subfile)
 
302
        _COUPLE_SET(fonts_dir)
 
303
        _COUPLE_SET(extract_embedded_fonts)
 
304
 
 
305
        return 1;
 
306
}
 
307
/************************************************/
 
308
extern uint8_t DIA_ass(ASSParams *param);
 
309
uint8_t ADMVideoSubASS::configure(AVDMGenericVideoStream *instream) 
 
310
{
 
311
  _in=instream;
 
312
  if( DIA_ass(_params))
 
313
  {
 
314
    init();
 
315
    return 1; 
 
316
  }
 
317
  return 0;
 
318
}
 
319
#endif /* HAVE_ENCODER */
 
320
#endif /* USE_FREETYPE */