]> CyberLeo.Net >> Repos - CDN/portage-cdn.git/blob - media-video/mplayer/files/mplayer-1.0_rc2_p27725-ass.patch
media-video/mplayer: add ASS patch
[CDN/portage-cdn.git] / media-video / mplayer / files / mplayer-1.0_rc2_p27725-ass.patch
1 --- /dev/null   2008-11-20 00:48:23.364006051 -0600
2 +++ mplayer-1.0_rc2_p27725/libmpcodecs/vf_fixpts.c      2008-12-17 14:07:32.000000000 -0600
3 @@ -0,0 +1,137 @@
4 +/*
5 +    Copyright (C) 2007 Nicolas George <nicolas.george@normalesup.org>
6 +
7 +    This program is free software; you can redistribute it and/or modify
8 +    it under the terms of the GNU General Public License as published by
9 +    the Free Software Foundation; either version 2 of the License, or
10 +    (at your option) any later version.
11 +
12 +    This program 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
15 +    GNU General Public License for more details.
16 +
17 +    You should have received a copy of the GNU General Public License
18 +    along with this program; if not, write to the Free Software
19 +    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 +*/
21 +
22 +#include <stdio.h>
23 +#include <stdlib.h>
24 +#include <string.h>
25 +#include <inttypes.h>
26 +
27 +#include "config.h"
28 +#include "mp_msg.h"
29 +#include "help_mp.h"
30 +
31 +#include "img_format.h"
32 +#include "mp_image.h"
33 +#include "vf.h"
34 +
35 +struct vf_priv_s {
36 +    double current;
37 +    double step;
38 +    int autostart;
39 +    int autostep;
40 +    unsigned have_step: 1;
41 +    unsigned print: 1;
42 +};
43 +
44 +static int put_image(vf_instance_t *vf, mp_image_t *src, double pts)
45 +{
46 +    struct vf_priv_s *p = vf->priv;
47 +
48 +    if(p->print) {
49 +       if(pts == MP_NOPTS_VALUE)
50 +           printf("PTS: undef\n");
51 +       else
52 +           printf("PTS: %f\n", pts);
53 +    }
54 +    if(pts != MP_NOPTS_VALUE && p->autostart != 0) {
55 +       p->current = pts;
56 +       if(p->autostart > 0)
57 +           p->autostart--;
58 +    } else if(pts != MP_NOPTS_VALUE && p->autostep > 0) {
59 +       p->step = pts - p->current;
60 +       p->current = pts;
61 +       p->autostep--;
62 +       p->have_step = 1;
63 +    } else if(p->have_step) {
64 +       p->current += p->step;
65 +       pts = p->current;
66 +    } else {
67 +       pts = MP_NOPTS_VALUE;
68 +    }
69 +    return vf_next_put_image(vf, src, pts);
70 +}
71 +
72 +static void uninit(vf_instance_t *vf)
73 +{
74 +    free(vf->priv);
75 +}
76 +
77 +static int parse_args(struct vf_priv_s *p, const char *args)
78 +{
79 +    int pos;
80 +    double num, denom = 1;
81 +    int iarg;
82 +
83 +    while(*args != 0) {
84 +       pos = 0;
85 +       if(sscanf(args, "print%n", &pos) == 0 && pos > 0) {
86 +           p->print = 1;
87 +       } else if(sscanf(args, "fps=%lf%n/%lf%n", &num, &pos, &denom, &pos) >= 1
88 +           && pos > 0) {
89 +           p->step = denom / num;
90 +           p->have_step = 1;
91 +       } else if(sscanf(args, "start=%lf%n", &num, &pos) >= 1 && pos > 0) {
92 +           p->current = num;
93 +       } else if(sscanf(args, "autostart=%d%n", &iarg, &pos) == 1 && pos > 0) {
94 +           p->autostart = iarg;
95 +       } else if(sscanf(args, "autofps=%d%n", &iarg, &pos) == 1 && pos > 0) {
96 +           p->autostep = iarg;
97 +       } else {
98 +           mp_msg(MSGT_VFILTER, MSGL_FATAL,
99 +               "fixpts: unknown suboption: %s\n", args);
100 +           return 0;
101 +       }
102 +       args += pos;
103 +       if(*args == ':')
104 +           args++;
105 +    }
106 +    return 1;
107 +}
108 +
109 +static int open(vf_instance_t *vf, char *args)
110 +{
111 +    struct vf_priv_s *p;
112 +    struct vf_priv_s ptmp = {
113 +       .current = 0,
114 +       .step = 0,
115 +       .autostart = 0,
116 +       .autostep = 0,
117 +       .have_step = 0,
118 +       .print = 0,
119 +    };
120 +
121 +    if(!parse_args(&ptmp, args == NULL ? "" : args))
122 +       return 0;
123 +
124 +    vf->put_image = put_image;
125 +    vf->uninit = uninit;
126 +    vf->priv = p = malloc(sizeof(struct vf_priv_s));
127 +    *p = ptmp;
128 +    p->current = -p->step;
129 +
130 +    return 1;
131 +}
132 +
133 +vf_info_t vf_info_fixpts = {
134 +  "Fix presentation timestamps",
135 +  "fixpts",
136 +  "Nicolas George",
137 +  "",
138 +  &open,
139 +  NULL
140 +};
141 diff -ur mplayer-1.0_rc2_p27725-orig/cfg-mencoder.h mplayer-1.0_rc2_p27725/cfg-mencoder.h
142 --- mplayer-1.0_rc2_p27725-orig/cfg-mencoder.h  2008-08-12 09:30:37.000000000 -0500
143 +++ mplayer-1.0_rc2_p27725/cfg-mencoder.h       2008-12-17 14:07:37.000000000 -0600
144 @@ -213,6 +213,9 @@
145         
146         {"odml", &write_odml, CONF_TYPE_FLAG, CONF_GLOBAL, 0, 1, NULL},
147         {"noodml", &write_odml, CONF_TYPE_FLAG, CONF_GLOBAL, 1, 0, NULL},
148 +
149 +       {"keep-pts", &keep_pts, CONF_TYPE_FLAG, 0, 0, 1, NULL},
150 +       {"nokeep-pts", &keep_pts, CONF_TYPE_FLAG, 0, 1, 0, NULL},
151         
152         // info header strings
153         {"info", info_conf, CONF_TYPE_SUBCONFIG, CONF_GLOBAL, 0, 0, NULL},
154 diff -ur mplayer-1.0_rc2_p27725-orig/DOCS/man/en/mplayer.1 mplayer-1.0_rc2_p27725/DOCS/man/en/mplayer.1
155 --- mplayer-1.0_rc2_p27725-orig/DOCS/man/en/mplayer.1   2008-10-06 20:04:15.000000000 -0500
156 +++ mplayer-1.0_rc2_p27725/DOCS/man/en/mplayer.1        2008-12-17 14:07:42.000000000 -0600
157 @@ -7171,6 +7171,48 @@
158  Threshold below which a pixel value is considered black (default: 32).
159  .RE
160  .
161 +.TP
162 +.B fixpts[=options]
163 +Fixes the presentation timestamps (PTS) of the frames.
164 +By default, the PTS passed to the next filter is dropped, but the following
165 +options can change that:
166 +.RSs
167 +.IPs print
168 +Print the incoming PTS.
169 +.IPs fps=<fps>
170 +Specify a frame per second value.
171 +.IPs start=<pts>
172 +Specify an initial value for the PTS.
173 +.IPs autostart=<n>
174 +Uses the 
175 +.IR n th
176 +incoming PTS as the initial PTS.
177 +All previous pts are kept, so setting a huge value or \-1 keeps the PTS
178 +intact.
179 +.IPs autofps=<n>
180 +Uses the 
181 +.IR n th
182 +incoming PTS after the end of autostart to determine the framerate.
183 +.RE
184 +.sp 1
185 +.RS
186 +.I EXAMPLE:
187 +.RE
188 +.PD 0
189 +.RSs
190 +.IPs "\-vf fixpts=fps=24000/1001,ass,fixpts"
191 +Generates a new sequence of PTS, uses it for ASS subtitles, then drops it.
192 +Generating a new sequence is useful when the timestamps are reset during the
193 +program; this is frequent on DVDs.
194 +Dropping it may be necessary to avoid confusing encoders.
195 +.RE
196 +.PD 1
197 +.sp 1
198 +.RS
199 +.I NOTE:
200 +Using this filter together with any sort of seeking (including -ss and EDLs)
201 +may make demons fly out of your nose.
202 +.RE
203  .
204  .
205  .SH "GENERAL ENCODING OPTIONS (MENCODER ONLY)"
206 @@ -7293,6 +7335,14 @@
207  Do not write OpenDML index for AVI files >1GB.
208  .
209  .TP
210 +.B \-keep\-pts
211 +Send the original presentation timestamp (PTS) down the filter and encoder
212 +chain.
213 +This may cause incorrect output ("badly interleaved") if the original PTS
214 +are wrong or the framerate is changed, but can be necessary for certain
215 +filters (such as ASS).
216 +.
217 +.TP
218  .B \-noskip
219  Do not skip frames.
220  .
221 diff -ur mplayer-1.0_rc2_p27725-orig/libass/ass_cache.c mplayer-1.0_rc2_p27725/libass/ass_cache.c
222 --- mplayer-1.0_rc2_p27725-orig/libass/ass_cache.c      2008-05-28 15:17:52.000000000 -0500
223 +++ mplayer-1.0_rc2_p27725/libass/ass_cache.c   2008-12-17 14:07:45.000000000 -0600
224 @@ -291,6 +291,39 @@
225         free(value);
226  }
227  
228 +static int glyph_compare(void* key1, void* key2, size_t key_size) {
229 +       glyph_hash_key_t* a = key1;
230 +       glyph_hash_key_t* b = key2;
231 +       return
232 +               a->font == b->font &&
233 +               a->size == b->size &&
234 +               a->ch == b->ch &&
235 +               a->bold == b->bold &&
236 +               a->italic == b->italic &&
237 +               a->scale_x == b->scale_x &&
238 +               a->scale_y == b->scale_y &&
239 +               a->advance.x == b->advance.x &&
240 +               a->advance.y == b->advance.y &&
241 +               a->outline == b->outline;
242 +}
243 +
244 +static unsigned glyph_hash(void* buf, size_t len)
245 +{
246 +       glyph_hash_key_t* g = buf;
247 +       unsigned hval = FNV1_32A_INIT;
248 +       hval = fnv_32a_buf(&g->font, sizeof(g->font), hval);
249 +       hval = fnv_32a_buf(&g->size, sizeof(g->size), hval);
250 +       hval = fnv_32a_buf(&g->ch, sizeof(g->ch), hval);
251 +       hval = fnv_32a_buf(&g->bold, sizeof(g->bold), hval);
252 +       hval = fnv_32a_buf(&g->italic, sizeof(g->italic), hval);
253 +       hval = fnv_32a_buf(&g->scale_x, sizeof(g->scale_x), hval);
254 +       hval = fnv_32a_buf(&g->scale_y, sizeof(g->scale_y), hval);
255 +       hval = fnv_32a_buf(&g->advance.x, sizeof(g->advance.x), hval);
256 +       hval = fnv_32a_buf(&g->advance.y, sizeof(g->advance.y), hval);
257 +       hval = fnv_32a_buf(&g->outline, sizeof(g->outline), hval);
258 +       return hval;
259 +}
260 +
261  void* cache_add_glyph(glyph_hash_key_t* key, glyph_hash_val_t* val)
262  {
263         return hashmap_insert(glyph_cache, key, val);
264 @@ -311,7 +344,9 @@
265         glyph_cache = hashmap_init(sizeof(glyph_hash_key_t),
266                                    sizeof(glyph_hash_val_t),
267                                    0xFFFF + 13,
268 -                                  glyph_hash_dtor, NULL, NULL);
269 +                                  glyph_hash_dtor,
270 +                                  glyph_compare,
271 +                                  glyph_hash);
272  }
273  
274  void ass_glyph_cache_done(void)
275 diff -ur mplayer-1.0_rc2_p27725-orig/libmpcodecs/vf.c mplayer-1.0_rc2_p27725/libmpcodecs/vf.c
276 --- mplayer-1.0_rc2_p27725-orig/libmpcodecs/vf.c        2008-08-12 09:30:35.000000000 -0500
277 +++ mplayer-1.0_rc2_p27725/libmpcodecs/vf.c     2008-12-17 14:07:37.000000000 -0600
278 @@ -99,6 +99,7 @@
279  extern const vf_info_t vf_info_blackframe;
280  extern const vf_info_t vf_info_geq;
281  extern const vf_info_t vf_info_ow;
282 +extern const vf_info_t vf_info_fixpts;
283  
284  // list of available filters:
285  static const vf_info_t* const filter_list[]={
286 @@ -191,6 +192,7 @@
287      &vf_info_yadif,
288      &vf_info_blackframe,
289      &vf_info_ow,
290 +    &vf_info_fixpts,
291      NULL
292  };
293  
294 diff -ur mplayer-1.0_rc2_p27725-orig/Makefile mplayer-1.0_rc2_p27725/Makefile
295 --- mplayer-1.0_rc2_p27725-orig/Makefile        2008-10-06 20:04:16.000000000 -0500
296 +++ mplayer-1.0_rc2_p27725/Makefile     2008-12-17 14:07:37.000000000 -0600
297 @@ -125,6 +125,7 @@
298                libmpcodecs/vf_field.c \
299                libmpcodecs/vf_fil.c \
300                libmpcodecs/vf_filmdint.c \
301 +              libmpcodecs/vf_fixpts.c \
302                libmpcodecs/vf_flip.c \
303                libmpcodecs/vf_format.c \
304                libmpcodecs/vf_framestep.c \
305 diff -ur mplayer-1.0_rc2_p27725-orig/mencoder.c mplayer-1.0_rc2_p27725/mencoder.c
306 --- mplayer-1.0_rc2_p27725-orig/mencoder.c      2008-08-12 09:30:37.000000000 -0500
307 +++ mplayer-1.0_rc2_p27725/mencoder.c   2008-12-17 14:07:45.000000000 -0600
308 @@ -198,6 +198,7 @@
309  
310  int auto_expand=1;
311  int encode_duplicates=1;
312 +int keep_pts=0;
313  
314  // infos are empty by default
315  char *info_name=NULL;
316 @@ -361,6 +362,44 @@
317  
318  static muxer_t* muxer=NULL;
319  
320 +void add_subtitles(char *filename, float fps, int silent)
321 +{
322 +    sub_data *subd;
323 +#ifdef CONFIG_ASS
324 +    ass_track_t *asst = 0;
325 +#endif
326 +
327 +    if (filename == NULL) return;
328 +
329 +    subd = sub_read_file(filename, fps);
330 +#ifdef CONFIG_ASS
331 +    if (ass_enabled)
332 +#ifdef CONFIG_ICONV
333 +        asst = ass_read_file(ass_library, filename, sub_cp);
334 +#else
335 +        asst = ass_read_file(ass_library, filename, 0);
336 +#endif
337 +    if (ass_enabled && subd && !asst)
338 +        asst = ass_read_subdata(ass_library, subd, fps);
339 +
340 +    if (!asst && !subd && !silent)
341 +#else
342 +    if(!subd && !silent) 
343 +#endif
344 +        mp_msg(MSGT_CPLAYER, MSGL_ERR, MSGTR_CantLoadSub,
345 +               filename_recode(filename));
346
347 +#ifdef CONFIG_ASS
348 +    if (!asst && !subd) return;
349 +    ass_track = asst;
350 +#else
351 +    if (!subd) return;
352 +#endif
353 +    mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_FILE_SUB_FILENAME=%s\n",
354 +          filename_recode(filename));
355 +    subdata = subd;
356 +}
357 +
358  extern void print_wave_header(WAVEFORMATEX *h, int verbose_level);
359  
360  int main(int argc,char* argv[]){
361 @@ -562,6 +601,10 @@
362    m_entry_set_options(mconfig,&filelist[curfile]);
363    filename = filelist[curfile].name;
364   
365 +#ifdef CONFIG_ASS
366 +  ass_library = ass_init();
367 +#endif
368 +
369    if(!filename){
370         mp_msg(MSGT_CPLAYER, MSGL_FATAL, MSGTR_MissingFilename);
371         mencoder_exit(1,NULL);
372 @@ -685,26 +728,6 @@
373      }
374    }
375  
376 -// after reading video params we should load subtitles because
377 -// we know fps so now we can adjust subtitles time to ~6 seconds AST
378 -// check .sub
379 -//  current_module="read_subtitles_file";
380 -  if(sub_name && sub_name[0]){
381 -    subdata=sub_read_file(sub_name[0], sh_video->fps);
382 -    if(!subdata) mp_msg(MSGT_CPLAYER,MSGL_ERR,MSGTR_CantLoadSub,sub_name[0]);
383 -  } else
384 -  if(sub_auto && filename) { // auto load sub file ...
385 -    char **tmp = NULL;
386 -    int i = 0;
387 -    char *psub = get_path( "sub/" );
388 -    tmp = sub_filenames((psub ? psub : ""), filename);
389 -    free(psub);
390 -    subdata=sub_read_file(tmp[0], sh_video->fps);
391 -    while (tmp[i])
392 -      free(tmp[i++]);
393 -    free(tmp);
394 -  }
395 -
396  // set up video encoder:
397  
398  if (!curfile) { // curfile is non zero when a second file is opened
399 @@ -885,12 +908,72 @@
400      ve = sh_video->vfilter;
401    } else sh_video->vfilter = ve;
402      // append 'expand' filter, it fixes stride problems and renders osd:
403 +#ifdef CONFIG_ASS
404 +    if (auto_expand && !ass_enabled) { /* we do not want both */
405 +#else
406      if (auto_expand) {
407 +#endif
408        char* vf_args[] = { "osd", "1", NULL };
409        sh_video->vfilter=vf_open_filter(sh_video->vfilter,"expand",vf_args);
410      }
411 +
412 +#ifdef CONFIG_ASS
413 +  if(ass_enabled) {
414 +    int i;
415 +    int insert = 1;
416 +    if (vf_settings)
417 +      for (i = 0; vf_settings[i].name; ++i)
418 +        if (strcmp(vf_settings[i].name, "ass") == 0) {
419 +          insert = 0;
420 +          break;
421 +        }
422 +    if (insert) {
423 +      extern vf_info_t vf_info_ass;
424 +      vf_info_t* libass_vfs[] = {&vf_info_ass, NULL};
425 +      char* vf_arg[] = {"auto", "1", NULL};
426 +      vf_instance_t* vf_ass = vf_open_plugin(libass_vfs,sh_video->vfilter,"ass",vf_arg);
427 +      if (vf_ass)
428 +        sh_video->vfilter=(void*)vf_ass;
429 +      else
430 +        mp_msg(MSGT_CPLAYER,MSGL_ERR, "ASS: cannot add video filter\n");
431 +    }
432 +    if (!keep_pts) {
433 +      keep_pts = 1;
434 +      mp_msg(MSGT_MENCODER, MSGL_WARN, "Warning: -ass implies -keep-pts, "
435 +       "which may cause \"badly interleaved\" files.\n");
436 +    }
437 +  }
438 +#endif
439 +
440      sh_video->vfilter=append_filters(sh_video->vfilter);
441  
442 +#ifdef CONFIG_ASS
443 +  if (ass_enabled)
444 +    ((vf_instance_t *)sh_video->vfilter)->control(sh_video->vfilter, VFCTRL_INIT_EOSD, ass_library);
445 +#endif
446 +
447 +// after reading video params we should load subtitles because
448 +// we know fps so now we can adjust subtitles time to ~6 seconds AST
449 +// check .sub
450 +//  current_module="read_subtitles_file";
451 +  if(sub_name && sub_name[0]){
452 +    for (i = 0; sub_name[i] != NULL; ++i) 
453 +        add_subtitles (sub_name[i], sh_video->fps, 0); 
454 +  } else
455 +  if(sub_auto && filename) { // auto load sub file ...
456 +    char **tmp = NULL;
457 +    int i = 0;
458 +    char *psub = get_path( "sub/" );
459 +    tmp = sub_filenames((psub ? psub : ""), filename);
460 +    free(psub);
461 +    while (tmp[i])
462 +    {
463 +      add_subtitles (tmp[i], sh_video->fps, 0);
464 +      free(tmp[i++]);
465 +    }
466 +    free(tmp);
467 +  }
468 +
469      mp_msg(MSGT_CPLAYER,MSGL_INFO,"==========================================================================\n");
470      init_best_video_codec(sh_video,video_codec_list,video_fm_list);
471      mp_msg(MSGT_CPLAYER,MSGL_INFO,"==========================================================================\n");
472 @@ -1346,7 +1429,8 @@
473      // decode_video will callback down to ve_*.c encoders, through the video filters
474      {void *decoded_frame = decode_video(sh_video,frame_data.start,frame_data.in_size,
475        skip_flag>0 && (!sh_video->vfilter || ((vf_instance_t *)sh_video->vfilter)->control(sh_video->vfilter, VFCTRL_SKIP_NEXT_FRAME, 0) != CONTROL_TRUE), MP_NOPTS_VALUE);
476 -    blit_frame = decoded_frame && filter_video(sh_video, decoded_frame, MP_NOPTS_VALUE);}
477 +    blit_frame = decoded_frame && filter_video(sh_video, decoded_frame,
478 +       keep_pts ? sh_video->pts : MP_NOPTS_VALUE);}
479      
480      if (sh_video->vf_initialized < 0) mencoder_exit(1, NULL);
481      
482 Only in mplayer-1.0_rc2_p27725: mencoder.c.orig