Mercurial > mplayer.hg
comparison mencoder.c @ 30807:82dd2fbdb772
Enable ASS/SSA subtitle support in mencoder
Enable ASS/SSA rendering through libass in mencoder. This duplicates a
bit of code (to parse font attachments, for example). Additionally, add
a filter "fixpts" that generates PTS, simulating fixed fps. PTS
generated by this filter are then used for subtitle timing.
Original patch by Nicolas George. (nicolas.george normalesup.org)
author | greg |
---|---|
date | Fri, 05 Mar 2010 23:13:08 +0000 |
parents | 7ac542b9ca24 |
children | 977fd535cc9d |
comparison
equal
deleted
inserted
replaced
30806:5e7d1ade0858 | 30807:82dd2fbdb772 |
---|---|
368 interrupted=2; /* 1 means error */ | 368 interrupted=2; /* 1 means error */ |
369 } | 369 } |
370 | 370 |
371 static muxer_t* muxer=NULL; | 371 static muxer_t* muxer=NULL; |
372 | 372 |
373 void add_subtitles(char *filename, float fps, int silent) | |
374 { | |
375 sub_data *subd; | |
376 #ifdef CONFIG_ASS | |
377 ass_track_t *asst = 0; | |
378 #endif | |
379 | |
380 if (!filename) return; | |
381 | |
382 subd = sub_read_file(filename, fps); | |
383 #ifdef CONFIG_ASS | |
384 if (ass_enabled) | |
385 #ifdef CONFIG_ICONV | |
386 asst = ass_read_file(ass_library, filename, sub_cp); | |
387 #else | |
388 asst = ass_read_file(ass_library, filename, 0); | |
389 #endif | |
390 if (ass_enabled && subd && !asst) | |
391 asst = ass_read_subdata(ass_library, subd, fps); | |
392 | |
393 if (!asst && !subd && !silent) | |
394 #else | |
395 if (!subd && !silent) | |
396 #endif | |
397 mp_msg(MSGT_CPLAYER, MSGL_ERR, MSGTR_CantLoadSub, | |
398 filename_recode(filename)); | |
399 | |
400 #ifdef CONFIG_ASS | |
401 if (!asst && !subd) return; | |
402 ass_track = asst; | |
403 #else | |
404 if (!subd) return; | |
405 #endif | |
406 mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_FILE_SUB_FILENAME=%s\n", | |
407 filename_recode(filename)); | |
408 subdata = subd; | |
409 } | |
410 | |
411 void print_wave_header(WAVEFORMATEX *h, int verbose_level); | |
412 | |
373 int main(int argc,char* argv[]){ | 413 int main(int argc,char* argv[]){ |
374 | 414 |
375 stream_t* stream=NULL; | 415 stream_t* stream=NULL; |
376 stream_t* ostream=NULL; | 416 stream_t* ostream=NULL; |
377 demuxer_t* demuxer=NULL; | 417 demuxer_t* demuxer=NULL; |
525 play_next_file: | 565 play_next_file: |
526 m_config_push(mconfig); | 566 m_config_push(mconfig); |
527 m_entry_set_options(mconfig,&filelist[curfile]); | 567 m_entry_set_options(mconfig,&filelist[curfile]); |
528 filename = filelist[curfile].name; | 568 filename = filelist[curfile].name; |
529 | 569 |
570 #ifdef CONFIG_ASS | |
571 ass_library = ass_init(); | |
572 #endif | |
573 | |
530 if(!filename){ | 574 if(!filename){ |
531 mp_msg(MSGT_CPLAYER, MSGL_FATAL, MSGTR_MissingFilename); | 575 mp_msg(MSGT_CPLAYER, MSGL_FATAL, MSGTR_MissingFilename); |
532 mencoder_exit(1,NULL); | 576 mencoder_exit(1,NULL); |
533 } | 577 } |
534 stream=open_stream(filename,0,&file_format); | 578 stream=open_stream(filename,0,&file_format); |
654 // limits are taken from libaf/af_resample.c | 698 // limits are taken from libaf/af_resample.c |
655 if (new_srate < 8000) new_srate = 8000; | 699 if (new_srate < 8000) new_srate = 8000; |
656 if (new_srate > 192000) new_srate = 192000; | 700 if (new_srate > 192000) new_srate = 192000; |
657 playback_speed = (float)new_srate / (float)sh_audio->samplerate; | 701 playback_speed = (float)new_srate / (float)sh_audio->samplerate; |
658 } | 702 } |
659 } | |
660 | |
661 // after reading video params we should load subtitles because | |
662 // we know fps so now we can adjust subtitles time to ~6 seconds AST | |
663 // check .sub | |
664 // current_module="read_subtitles_file"; | |
665 if(sub_name && sub_name[0]){ | |
666 subdata=sub_read_file(sub_name[0], sh_video->fps); | |
667 if(!subdata) mp_msg(MSGT_CPLAYER,MSGL_ERR,MSGTR_CantLoadSub,sub_name[0]); | |
668 } else | |
669 if(sub_auto && filename) { // auto load sub file ... | |
670 char **tmp = NULL; | |
671 int i = 0; | |
672 char *psub = get_path( "sub/" ); | |
673 tmp = sub_filenames((psub ? psub : ""), filename); | |
674 free(psub); | |
675 subdata=sub_read_file(tmp[0], sh_video->fps); | |
676 while (tmp[i]) | |
677 free(tmp[i++]); | |
678 free(tmp); | |
679 } | 703 } |
680 | 704 |
681 // set up video encoder: | 705 // set up video encoder: |
682 | 706 |
683 if (!curfile) { // curfile is non zero when a second file is opened | 707 if (!curfile) { // curfile is non zero when a second file is opened |
855 mencoder_exit(1,NULL); | 879 mencoder_exit(1,NULL); |
856 } | 880 } |
857 ve = sh_video->vfilter; | 881 ve = sh_video->vfilter; |
858 } else sh_video->vfilter = ve; | 882 } else sh_video->vfilter = ve; |
859 // append 'expand' filter, it fixes stride problems and renders osd: | 883 // append 'expand' filter, it fixes stride problems and renders osd: |
884 #ifdef CONFIG_ASS | |
885 if (auto_expand && !ass_enabled) { /* we do not want both */ | |
886 #else | |
860 if (auto_expand) { | 887 if (auto_expand) { |
888 #endif | |
861 char* vf_args[] = { "osd", "1", NULL }; | 889 char* vf_args[] = { "osd", "1", NULL }; |
862 sh_video->vfilter=vf_open_filter(sh_video->vfilter,"expand",vf_args); | 890 sh_video->vfilter=vf_open_filter(sh_video->vfilter,"expand",vf_args); |
863 } | 891 } |
892 | |
893 #ifdef CONFIG_ASS | |
894 if(ass_enabled) { | |
895 int i; | |
896 int insert = 1; | |
897 if (vf_settings) | |
898 for (i = 0; vf_settings[i].name; ++i) | |
899 if (strcmp(vf_settings[i].name, "ass") == 0) { | |
900 insert = 0; | |
901 break; | |
902 } | |
903 if (insert) { | |
904 extern vf_info_t vf_info_ass; | |
905 vf_info_t* libass_vfs[] = {&vf_info_ass, NULL}; | |
906 char* vf_arg[] = {"auto", "1", NULL}; | |
907 vf_instance_t* vf_ass = vf_open_plugin(libass_vfs,sh_video->vfilter,"ass",vf_arg); | |
908 if (vf_ass) | |
909 sh_video->vfilter=(void*)vf_ass; | |
910 else | |
911 mp_msg(MSGT_CPLAYER,MSGL_ERR, "ASS: cannot add video filter\n"); | |
912 } | |
913 | |
914 if (ass_library) { | |
915 for (i = 0; i < demuxer->num_attachments; ++i) { | |
916 demux_attachment_t* att = demuxer->attachments + i; | |
917 if (extract_embedded_fonts && | |
918 att->name && att->type && att->data && att->data_size && | |
919 (strcmp(att->type, "application/x-truetype-font") == 0 || | |
920 strcmp(att->type, "application/x-font") == 0)) | |
921 ass_add_font(ass_library, att->name, att->data, att->data_size); | |
922 } | |
923 } | |
924 } | |
925 #endif | |
926 | |
864 sh_video->vfilter=append_filters(sh_video->vfilter); | 927 sh_video->vfilter=append_filters(sh_video->vfilter); |
928 | |
929 #ifdef CONFIG_ASS | |
930 if (ass_enabled) | |
931 ((vf_instance_t *)sh_video->vfilter)->control(sh_video->vfilter, VFCTRL_INIT_EOSD, ass_library); | |
932 #endif | |
933 | |
934 // after reading video params we should load subtitles because | |
935 // we know fps so now we can adjust subtitles time to ~6 seconds AST | |
936 // check .sub | |
937 if(sub_name && sub_name[0]){ | |
938 for (i = 0; sub_name[i] != NULL; ++i) | |
939 add_subtitles (sub_name[i], sh_video->fps, 0); | |
940 } else | |
941 if(sub_auto && filename) { // auto load sub file ... | |
942 char **tmp = NULL; | |
943 int i = 0; | |
944 char *psub = get_path( "sub/" ); | |
945 tmp = sub_filenames((psub ? psub : ""), filename); | |
946 free(psub); | |
947 while (tmp[i]) | |
948 { | |
949 add_subtitles (tmp[i], sh_video->fps, 0); | |
950 free(tmp[i++]); | |
951 } | |
952 free(tmp); | |
953 } | |
865 | 954 |
866 mp_msg(MSGT_CPLAYER,MSGL_INFO,"==========================================================================\n"); | 955 mp_msg(MSGT_CPLAYER,MSGL_INFO,"==========================================================================\n"); |
867 init_best_video_codec(sh_video,video_codec_list,video_fm_list); | 956 init_best_video_codec(sh_video,video_codec_list,video_fm_list); |
868 mp_msg(MSGT_CPLAYER,MSGL_INFO,"==========================================================================\n"); | 957 mp_msg(MSGT_CPLAYER,MSGL_INFO,"==========================================================================\n"); |
869 if(!sh_video->initialized) mencoder_exit(1,NULL); | 958 if(!sh_video->initialized) mencoder_exit(1,NULL); |