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);