Ticket #1401: ass_support_for_mencoder_with_embeddedfonts.patch
| File ass_support_for_mencoder_with_embeddedfonts.patch, 14.4 KB (added by , 18 years ago) |
|---|
-
libmpcodecs/vf_fixpts.c
1 /* 2 Copyright (C) 2007 Nicolas George <nicolas.george@normalesup.org> 3 4 This program is free software; you can redistribute it and/or modify 5 it under the terms of the GNU General Public License as published by 6 the Free Software Foundation; either version 2 of the License, or 7 (at your option) any later version. 8 9 This program is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU General Public License for more details. 13 14 You should have received a copy of the GNU General Public License 15 along with this program; if not, write to the Free Software 16 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 */ 18 19 #include <stdio.h> 20 #include <stdlib.h> 21 #include <string.h> 22 #include <inttypes.h> 23 24 #include "config.h" 25 #include "mp_msg.h" 26 #include "help_mp.h" 27 28 #include "img_format.h" 29 #include "mp_image.h" 30 #include "vf.h" 31 32 struct vf_priv_s { 33 double current; 34 double step; 35 int autostart; 36 int autostep; 37 unsigned have_step: 1; 38 unsigned print: 1; 39 }; 40 41 static int put_image(vf_instance_t *vf, mp_image_t *src, double pts) 42 { 43 struct vf_priv_s *p = vf->priv; 44 45 if(p->print) { 46 if(pts == MP_NOPTS_VALUE) 47 printf("PTS: undef\n"); 48 else 49 printf("PTS: %f\n", pts); 50 } 51 if(pts != MP_NOPTS_VALUE && p->autostart != 0) { 52 p->current = pts; 53 if(p->autostart > 0) 54 p->autostart--; 55 } else if(pts != MP_NOPTS_VALUE && p->autostep > 0) { 56 p->step = pts - p->current; 57 p->current = pts; 58 p->autostep--; 59 p->have_step = 1; 60 } else if(p->have_step) { 61 p->current += p->step; 62 pts = p->current; 63 } else { 64 pts = MP_NOPTS_VALUE; 65 } 66 return vf_next_put_image(vf, src, pts); 67 } 68 69 static void uninit(vf_instance_t *vf) 70 { 71 free(vf->priv); 72 } 73 74 static int parse_args(struct vf_priv_s *p, const char *args) 75 { 76 int pos; 77 double num, denom = 1; 78 int iarg; 79 80 while(*args != 0) { 81 pos = 0; 82 if(sscanf(args, "print%n", &pos) == 0 && pos > 0) { 83 p->print = 1; 84 } else if(sscanf(args, "fps=%lf%n/%lf%n", &num, &pos, &denom, &pos) >= 1 85 && pos > 0) { 86 p->step = denom / num; 87 p->have_step = 1; 88 } else if(sscanf(args, "start=%lf%n", &num, &pos) >= 1 && pos > 0) { 89 p->current = num; 90 } else if(sscanf(args, "autostart=%d%n", &iarg, &pos) == 1 && pos > 0) { 91 p->autostart = iarg; 92 } else if(sscanf(args, "autofps=%d%n", &iarg, &pos) == 1 && pos > 0) { 93 p->autostep = iarg; 94 } else { 95 mp_msg(MSGT_VFILTER, MSGL_FATAL, 96 "fixpts: unknown suboption: %s\n", args); 97 return 0; 98 } 99 args += pos; 100 if(*args == ':') 101 args++; 102 } 103 return 1; 104 } 105 106 static int open(vf_instance_t *vf, char *args) 107 { 108 struct vf_priv_s *p; 109 struct vf_priv_s ptmp = { 110 .current = 0, 111 .step = 0, 112 .autostart = 0, 113 .autostep = 0, 114 .have_step = 0, 115 .print = 0, 116 }; 117 118 if(!parse_args(&ptmp, args == NULL ? "" : args)) 119 return 0; 120 121 vf->put_image = put_image; 122 vf->uninit = uninit; 123 vf->priv = p = malloc(sizeof(struct vf_priv_s)); 124 *p = ptmp; 125 p->current = -p->step; 126 127 return 1; 128 } 129 130 vf_info_t vf_info_fixpts = { 131 "Fix presentation timestamps", 132 "fixpts", 133 "Nicolas George", 134 "", 135 &open, 136 NULL 137 }; -
libmpcodecs/vf.c
99 99 extern const vf_info_t vf_info_blackframe; 100 100 extern const vf_info_t vf_info_geq; 101 101 extern const vf_info_t vf_info_ow; 102 extern const vf_info_t vf_info_fixpts; 102 103 103 104 // list of available filters: 104 105 static const vf_info_t* const filter_list[]={ … … 191 192 &vf_info_yadif, 192 193 &vf_info_blackframe, 193 194 &vf_info_ow, 195 &vf_info_fixpts, 194 196 NULL 195 197 }; 196 198 -
Makefile
125 125 libmpcodecs/vf_field.c \ 126 126 libmpcodecs/vf_fil.c \ 127 127 libmpcodecs/vf_filmdint.c \ 128 libmpcodecs/vf_fixpts.c \ 128 129 libmpcodecs/vf_flip.c \ 129 130 libmpcodecs/vf_format.c \ 130 131 libmpcodecs/vf_framestep.c \ -
cfg-mencoder.h
213 213 214 214 {"odml", &write_odml, CONF_TYPE_FLAG, CONF_GLOBAL, 0, 1, NULL}, 215 215 {"noodml", &write_odml, CONF_TYPE_FLAG, CONF_GLOBAL, 1, 0, NULL}, 216 217 {"keep-pts", &keep_pts, CONF_TYPE_FLAG, 0, 0, 1, NULL}, 218 {"nokeep-pts", &keep_pts, CONF_TYPE_FLAG, 0, 1, 0, NULL}, 216 219 217 220 // info header strings 218 221 {"info", info_conf, CONF_TYPE_SUBCONFIG, CONF_GLOBAL, 0, 0, NULL}, -
DOCS/man/en/mplayer.1
7190 7190 Threshold below which a pixel value is considered black (default: 32). 7191 7191 .RE 7192 7192 . 7193 .TP 7194 .B fixpts[=options] 7195 Fixes the presentation timestamps (PTS) of the frames. 7196 By default, the PTS passed to the next filter is dropped, but the following 7197 options can change that: 7198 .RSs 7199 .IPs print 7200 Print the incoming PTS. 7201 .IPs fps=<fps> 7202 Specify a frame per second value. 7203 .IPs start=<pts> 7204 Specify an initial value for the PTS. 7205 .IPs autostart=<n> 7206 Uses the 7207 .IR n th 7208 incoming PTS as the initial PTS. 7209 All previous pts are kept, so setting a huge value or \-1 keeps the PTS 7210 intact. 7211 .IPs autofps=<n> 7212 Uses the 7213 .IR n th 7214 incoming PTS after the end of autostart to determine the framerate. 7215 .RE 7216 .sp 1 7217 .RS 7218 .I EXAMPLE: 7219 .RE 7220 .PD 0 7221 .RSs 7222 .IPs "\-vf fixpts=fps=24000/1001,ass,fixpts" 7223 Generates a new sequence of PTS, uses it for ASS subtitles, then drops it. 7224 Generating a new sequence is useful when the timestamps are reset during the 7225 program; this is frequent on DVDs. 7226 Dropping it may be necessary to avoid confusing encoders. 7227 .RE 7228 .PD 1 7229 .sp 1 7230 .RS 7231 .I NOTE: 7232 Using this filter together with any sort of seeking (including -ss and EDLs) 7233 may make demons fly out of your nose. 7234 .RE 7193 7235 . 7194 7236 . 7195 7237 .SH "GENERAL ENCODING OPTIONS (MENCODER ONLY)" … … 7312 7354 Do not write OpenDML index for AVI files >1GB. 7313 7355 . 7314 7356 .TP 7357 .B \-keep\-pts 7358 Send the original presentation timestamp (PTS) down the filter and encoder 7359 chain. 7360 This may cause incorrect output ("badly interleaved") if the original PTS 7361 are wrong or the framerate is changed, but can be necessary for certain 7362 filters (such as ASS). 7363 . 7364 .TP 7315 7365 .B \-noskip 7316 7366 Do not skip frames. 7317 7367 . -
libass/ass_cache.c
291 291 free(value); 292 292 } 293 293 294 static int glyph_compare(void* key1, void* key2, size_t key_size) { 295 glyph_hash_key_t* a = key1; 296 glyph_hash_key_t* b = key2; 297 return 298 a->font == b->font && 299 a->size == b->size && 300 a->ch == b->ch && 301 a->bold == b->bold && 302 a->italic == b->italic && 303 a->scale_x == b->scale_x && 304 a->scale_y == b->scale_y && 305 a->advance.x == b->advance.x && 306 a->advance.y == b->advance.y && 307 a->outline == b->outline; 308 } 309 310 static unsigned glyph_hash(void* buf, size_t len) 311 { 312 glyph_hash_key_t* g = buf; 313 unsigned hval = FNV1_32A_INIT; 314 hval = fnv_32a_buf(&g->font, sizeof(g->font), hval); 315 hval = fnv_32a_buf(&g->size, sizeof(g->size), hval); 316 hval = fnv_32a_buf(&g->ch, sizeof(g->ch), hval); 317 hval = fnv_32a_buf(&g->bold, sizeof(g->bold), hval); 318 hval = fnv_32a_buf(&g->italic, sizeof(g->italic), hval); 319 hval = fnv_32a_buf(&g->scale_x, sizeof(g->scale_x), hval); 320 hval = fnv_32a_buf(&g->scale_y, sizeof(g->scale_y), hval); 321 hval = fnv_32a_buf(&g->advance.x, sizeof(g->advance.x), hval); 322 hval = fnv_32a_buf(&g->advance.y, sizeof(g->advance.y), hval); 323 hval = fnv_32a_buf(&g->outline, sizeof(g->outline), hval); 324 return hval; 325 } 326 294 327 void* cache_add_glyph(glyph_hash_key_t* key, glyph_hash_val_t* val) 295 328 { 296 329 return hashmap_insert(glyph_cache, key, val); … … 311 344 glyph_cache = hashmap_init(sizeof(glyph_hash_key_t), 312 345 sizeof(glyph_hash_val_t), 313 346 0xFFFF + 13, 314 glyph_hash_dtor, NULL, NULL); 347 glyph_hash_dtor, 348 glyph_compare, 349 glyph_hash); 315 350 } 316 351 317 352 void ass_glyph_cache_done(void) -
mencoder.c
198 198 199 199 int auto_expand=1; 200 200 int encode_duplicates=1; 201 int keep_pts=0; 201 202 202 203 // infos are empty by default 203 204 char *info_name=NULL; … … 361 362 362 363 static muxer_t* muxer=NULL; 363 364 365 void add_subtitles(char *filename, float fps, int silent) 366 { 367 sub_data *subd; 368 #ifdef CONFIG_ASS 369 ass_track_t *asst = 0; 370 #endif 371 372 if (filename == NULL) return; 373 374 subd = sub_read_file(filename, fps); 375 #ifdef CONFIG_ASS 376 if (ass_enabled) 377 #ifdef CONFIG_ICONV 378 asst = ass_read_file(ass_library, filename, sub_cp); 379 #else 380 asst = ass_read_file(ass_library, filename, 0); 381 #endif 382 if (ass_enabled && subd && !asst) 383 asst = ass_read_subdata(ass_library, subd, fps); 384 385 if (!asst && !subd && !silent) 386 #else 387 if(!subd && !silent) 388 #endif 389 mp_msg(MSGT_CPLAYER, MSGL_ERR, MSGTR_CantLoadSub, 390 filename_recode(filename)); 391 392 #ifdef CONFIG_ASS 393 if (!asst && !subd) return; 394 ass_track = asst; 395 #else 396 if (!subd) return; 397 #endif 398 mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_FILE_SUB_FILENAME=%s\n", 399 filename_recode(filename)); 400 subdata = subd; 401 } 402 364 403 void print_wave_header(WAVEFORMATEX *h, int verbose_level); 365 404 366 405 int main(int argc,char* argv[]){ … … 562 601 m_entry_set_options(mconfig,&filelist[curfile]); 563 602 filename = filelist[curfile].name; 564 603 604 #ifdef CONFIG_ASS 605 ass_library = ass_init(); 606 #endif 607 565 608 if(!filename){ 566 609 mp_msg(MSGT_CPLAYER, MSGL_FATAL, MSGTR_MissingFilename); 567 610 mencoder_exit(1,NULL); … … 685 728 } 686 729 } 687 730 688 // after reading video params we should load subtitles because689 // we know fps so now we can adjust subtitles time to ~6 seconds AST690 // check .sub691 // current_module="read_subtitles_file";692 if(sub_name && sub_name[0]){693 subdata=sub_read_file(sub_name[0], sh_video->fps);694 if(!subdata) mp_msg(MSGT_CPLAYER,MSGL_ERR,MSGTR_CantLoadSub,sub_name[0]);695 } else696 if(sub_auto && filename) { // auto load sub file ...697 char **tmp = NULL;698 int i = 0;699 char *psub = get_path( "sub/" );700 tmp = sub_filenames((psub ? psub : ""), filename);701 free(psub);702 subdata=sub_read_file(tmp[0], sh_video->fps);703 while (tmp[i])704 free(tmp[i++]);705 free(tmp);706 }707 708 731 // set up video encoder: 709 732 710 733 if (!curfile) { // curfile is non zero when a second file is opened … … 882 905 ve = sh_video->vfilter; 883 906 } else sh_video->vfilter = ve; 884 907 // append 'expand' filter, it fixes stride problems and renders osd: 908 #ifdef CONFIG_ASS 909 if (auto_expand && !ass_enabled) { /* we do not want both */ 910 #else 885 911 if (auto_expand) { 912 #endif 886 913 char* vf_args[] = { "osd", "1", NULL }; 887 914 sh_video->vfilter=vf_open_filter(sh_video->vfilter,"expand",vf_args); 888 915 } 916 917 #ifdef CONFIG_ASS 918 if(ass_enabled) { 919 int i; 920 int insert = 1; 921 if (vf_settings) 922 for (i = 0; vf_settings[i].name; ++i) 923 if (strcmp(vf_settings[i].name, "ass") == 0) { 924 insert = 0; 925 break; 926 } 927 if (insert) { 928 extern vf_info_t vf_info_ass; 929 vf_info_t* libass_vfs[] = {&vf_info_ass, NULL}; 930 char* vf_arg[] = {"auto", "1", NULL}; 931 vf_instance_t* vf_ass = vf_open_plugin(libass_vfs,sh_video->vfilter,"ass",vf_arg); 932 if (vf_ass) 933 sh_video->vfilter=(void*)vf_ass; 934 else 935 mp_msg(MSGT_CPLAYER,MSGL_ERR, "ASS: cannot add video filter\n"); 936 } 937 if (!keep_pts) { 938 keep_pts = 1; 939 mp_msg(MSGT_MENCODER, MSGL_WARN, "Warning: -ass implies -keep-pts, " 940 "which may cause \"badly interleaved\" files.\n"); 941 } 942 943 if (ass_library) { 944 for (i = 0; i < demuxer->num_attachments; ++i) { 945 demux_attachment_t* att = demuxer->attachments + i; 946 if (extract_embedded_fonts && 947 att->name && att->type && att->data && att->data_size && 948 (strcmp(att->type, "application/x-truetype-font") == 0 || 949 strcmp(att->type, "application/x-font") == 0)) 950 ass_add_font(ass_library, att->name, att->data, att->data_size); 951 } 952 } 953 } 954 #endif 955 889 956 sh_video->vfilter=append_filters(sh_video->vfilter); 890 957 958 #ifdef CONFIG_ASS 959 if (ass_enabled) 960 ((vf_instance_t *)sh_video->vfilter)->control(sh_video->vfilter, VFCTRL_INIT_EOSD, ass_library); 961 #endif 962 963 // after reading video params we should load subtitles because 964 // we know fps so now we can adjust subtitles time to ~6 seconds AST 965 // check .sub 966 // current_module="read_subtitles_file"; 967 if(sub_name && sub_name[0]){ 968 for (i = 0; sub_name[i] != NULL; ++i) 969 add_subtitles (sub_name[i], sh_video->fps, 0); 970 } else 971 if(sub_auto && filename) { // auto load sub file ... 972 char **tmp = NULL; 973 int i = 0; 974 char *psub = get_path( "sub/" ); 975 tmp = sub_filenames((psub ? psub : ""), filename); 976 free(psub); 977 while (tmp[i]) 978 { 979 add_subtitles (tmp[i], sh_video->fps, 0); 980 free(tmp[i++]); 981 } 982 free(tmp); 983 } 984 891 985 mp_msg(MSGT_CPLAYER,MSGL_INFO,"==========================================================================\n"); 892 986 init_best_video_codec(sh_video,video_codec_list,video_fm_list); 893 987 mp_msg(MSGT_CPLAYER,MSGL_INFO,"==========================================================================\n"); … … 1343 1437 // decode_video will callback down to ve_*.c encoders, through the video filters 1344 1438 {void *decoded_frame = decode_video(sh_video,frame_data.start,frame_data.in_size, 1345 1439 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); 1346 blit_frame = decoded_frame && filter_video(sh_video, decoded_frame, MP_NOPTS_VALUE);} 1440 blit_frame = decoded_frame && filter_video(sh_video, decoded_frame, 1441 keep_pts ? sh_video->pts : MP_NOPTS_VALUE);} 1347 1442 1348 1443 if (sh_video->vf_initialized < 0) mencoder_exit(1, NULL); 1349 1444
