From b26fbeddd85aae6cda93d01335bed5f108a3ff57 Mon Sep 17 00:00:00 2001 From: Uoti Urpala Date: Tue, 11 Jan 2011 17:28:10 +0200 Subject: options: move -noconfig to option struct, simplify --- mplayer.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'mplayer.c') diff --git a/mplayer.c b/mplayer.c index 893ae77694..6565f75904 100644 --- a/mplayer.c +++ b/mplayer.c @@ -869,9 +869,10 @@ static int cfg_include(m_option_t *conf, char *filename) static void parse_cfgfiles(struct MPContext *mpctx, m_config_t* conf) { + struct MPOpts *opts = &mpctx->opts; char *conffile; int conffile_fd; -if (!disable_system_conf && + if (!(opts->noconfig & 2) && m_config_parse_config_file(conf, MPLAYER_CONFDIR "/mplayer.conf") < 0) exit_player(mpctx, EXIT_NONE); if ((conffile = get_path("")) == NULL) { @@ -891,7 +892,7 @@ if ((conffile = get_path("")) == NULL) { write(conffile_fd, default_config, strlen(default_config)); close(conffile_fd); } - if (!disable_user_conf && + if (!(opts->noconfig & 1) && m_config_parse_config_file(conf, conffile) < 0) exit_player(mpctx, EXIT_NONE); free(conffile); -- cgit v1.2.3 From a1692437d0a2cc88a2b3440bbcfb5e6f66cfd90e Mon Sep 17 00:00:00 2001 From: Uoti Urpala Date: Tue, 11 Jan 2011 17:48:45 +0200 Subject: core: move global "subdata" and "vo_sub_last" to mpctx --- mplayer.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'mplayer.c') diff --git a/mplayer.c b/mplayer.c index 6565f75904..567114cfd3 100644 --- a/mplayer.c +++ b/mplayer.c @@ -4415,14 +4415,14 @@ if(vo_spudec==NULL && mpctx->sub_counts[SUB_SOURCE_SUBS] = mpctx->set_of_sub_size; if (select_subtitle(mpctx)) { - if(subdata) + if(mpctx->subdata) switch (stream_dump_type) { - case 3: list_sub_file(subdata); break; - case 4: dump_mpsub(subdata, mpctx->sh_video->fps); break; - case 6: dump_srt(subdata, mpctx->sh_video->fps); break; - case 7: dump_microdvd(subdata, mpctx->sh_video->fps); break; - case 8: dump_jacosub(subdata, mpctx->sh_video->fps); break; - case 9: dump_sami(subdata, mpctx->sh_video->fps); break; + case 3: list_sub_file(mpctx->subdata); break; + case 4: dump_mpsub(mpctx->subdata, mpctx->sh_video->fps); break; + case 6: dump_srt(mpctx->subdata, mpctx->sh_video->fps); break; + case 7: dump_microdvd(mpctx->subdata, mpctx->sh_video->fps); break; + case 8: dump_jacosub(mpctx->subdata, mpctx->sh_video->fps); break; + case 9: dump_sami(mpctx->subdata, mpctx->sh_video->fps); break; } } @@ -4645,8 +4645,8 @@ if(mpctx->set_of_sub_size > 0) { } mpctx->set_of_sub_size = 0; } -vo_sub_last = vo_sub=NULL; -subdata=NULL; +mpctx->vo_sub_last = vo_sub=NULL; +mpctx->subdata=NULL; #ifdef CONFIG_ASS ass_track = NULL; if(ass_library) -- cgit v1.2.3 From 43b1de1dd72a9c2f98b3419626c81c58bbc3cf64 Mon Sep 17 00:00:00 2001 From: Uoti Urpala Date: Wed, 12 Jan 2011 01:37:02 +0200 Subject: core: move most mpcommon.c contents to mplayer.c The contents of mpcommon.c were quite arbitrary; the most common reason to place some functions in this file had been "MEncoder happens to need similar code as MPlayer and we want to share some parts, but we have no clue whatsoever how to organize things in a sensible way, so we'll just dump those parts we want to share in mpcommon.c". As a result of containing an essentially random subset of top-level player functionality the mpcommon.h header required access to central structs and was unsuitable for inclusion in lower-level code, but was nonetheless included there for the mplayer_version symbol. Move almost all contents from mpcommon.c to mplayer.c. mplayer.c is already big and should perhaps be split further, but keeping a few random functions in mpcommon.c would not be an improvement. --- mplayer.c | 314 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 305 insertions(+), 9 deletions(-) (limited to 'mplayer.c') diff --git a/mplayer.c b/mplayer.c index 567114cfd3..091287c1fd 100644 --- a/mplayer.c +++ b/mplayer.c @@ -78,6 +78,11 @@ #include "libvo/font_load.h" #include "libvo/sub.h" +#include "ffmpeg_files/intreadwrite.h" +#include "av_sub.h" +#include "libmpcodecs/dec_teletext.h" +#include "cpudetect.h" +#include "version.h" #ifdef CONFIG_X11 #include "libvo/x11_common.h" @@ -330,6 +335,9 @@ int subcc_enabled=0; int suboverlap_enabled = 1; #include "ass_mp.h" +#ifdef CONFIG_ASS +ASS_Track *ass_track = 0; // current track to render +#endif char* current_module=NULL; // for debugging @@ -1797,6 +1805,230 @@ double playing_audio_pts(struct MPContext *mpctx) mpctx->audio_out->get_delay(); } +static bool is_text_sub(int type) +{ + return type == 't' || type == 'm' || type == 'a'; +} + +static bool is_av_sub(int type) +{ + return type == 'b' || type == 'p' || type == 'x'; +} + +void update_subtitles(struct MPContext *mpctx, double refpts, + double sub_offset, bool reset) +{ + struct MPOpts *opts = &mpctx->opts; + struct sh_video *sh_video = mpctx->sh_video; + struct demux_stream *d_sub = mpctx->d_sub; + double curpts = refpts + sub_delay; + unsigned char *packet=NULL; + int len; + int type = d_sub->sh ? ((sh_sub_t *)d_sub->sh)->type : 'v'; + static subtitle subs; + if (reset) { + sub_clear_text(&subs, MP_NOPTS_VALUE); + if (vo_sub) + set_osd_subtitle(mpctx, NULL); + if (vo_spudec) { + spudec_reset(vo_spudec); + vo_osd_changed(OSDTYPE_SPU); + } +#ifdef CONFIG_FFMPEG + if (is_av_sub(type)) + reset_avsub(d_sub->sh); +#endif + return; + } + // find sub + if (mpctx->subdata) { + if (sub_fps==0) sub_fps = sh_video ? sh_video->fps : 25; + current_module = "find_sub"; + find_sub(mpctx, mpctx->subdata, curpts * + (mpctx->subdata->sub_uses_time ? 100. : sub_fps)); + if (vo_sub) + mpctx->vo_sub_last = vo_sub; + } + + // DVD sub: + if (vobsub_id >= 0 || type == 'v') { + int timestamp; + current_module = "spudec"; + /* Get a sub packet from the DVD or a vobsub */ + while(1) { + // Vobsub + len = 0; + if (vo_vobsub) { + if (curpts >= 0) { + len = vobsub_get_packet(vo_vobsub, curpts, + (void**)&packet, ×tamp); + if (len > 0) { + mp_dbg(MSGT_CPLAYER,MSGL_V,"\rVOB sub: len=%d v_pts=%5.3f v_timer=%5.3f sub=%5.3f ts=%d \n",len,refpts,sh_video->timer,timestamp / 90000.0,timestamp); + } + } + } else { + // DVD sub + len = ds_get_packet_sub(d_sub, (unsigned char**)&packet); + if (len > 0) { + // XXX This is wrong, sh_video->pts can be arbitrarily + // much behind demuxing position. Unfortunately using + // d_video->pts which would have been the simplest + // improvement doesn't work because mpeg specific hacks + // in video.c set d_video->pts to 0. + float x = d_sub->pts - refpts; + if (x > -20 && x < 20) // prevent missing subs on pts reset + timestamp = 90000*d_sub->pts; + else timestamp = 90000*curpts; + mp_dbg(MSGT_CPLAYER, MSGL_V, "\rDVD sub: len=%d " + "v_pts=%5.3f s_pts=%5.3f ts=%d \n", len, + refpts, d_sub->pts, timestamp); + } + } + if (len<=0 || !packet) break; + // create it only here, since with some broken demuxers we might + // type = v but no DVD sub and we currently do not change the + // "original frame size" ever after init, leading to wrong-sized + // PGS subtitles. + if (!vo_spudec) + vo_spudec = spudec_new(NULL); + if (vo_vobsub || timestamp >= 0) + spudec_assemble(vo_spudec, packet, len, timestamp); + } + } else if (is_text_sub(type) || is_av_sub(type) || type == 'd') { + if (type == 'd' && !d_sub->demuxer->teletext) { + tt_stream_props tsp = {0}; + void *ptr = &tsp; + if (teletext_control(NULL, TV_VBI_CONTROL_START, &ptr) == VBI_CONTROL_TRUE) + d_sub->demuxer->teletext = ptr; + } + if (d_sub->non_interleaved) + ds_get_next_pts(d_sub); + + int orig_type = type; + while (d_sub->first) { + double subpts = ds_get_next_pts(d_sub) + sub_offset; + type = orig_type; + if (subpts > curpts) { + // Libass handled subs can be fed to it in advance + if (!opts->ass_enabled || !is_text_sub(type)) + break; + // Try to avoid demuxing whole file at once + if (d_sub->non_interleaved && subpts > curpts + 1) + break; + } + double endpts = d_sub->first->endpts + sub_offset; + len = ds_get_packet_sub(d_sub, &packet); + if (is_av_sub(type)) { +#ifdef CONFIG_FFMPEG + type = decode_avsub(d_sub->sh, &packet, &len, &subpts, &endpts); + if (type <= 0) +#endif + continue; + } + if (type == 'm') { + if (len < 2) continue; + len = FFMIN(len - 2, AV_RB16(packet)); + packet += 2; + } + if (type == 'd') { + if (d_sub->demuxer->teletext) { + uint8_t *p = packet; + p++; + len--; + while (len >= 46) { + int sublen = p[1]; + if (p[0] == 2 || p[0] == 3) + teletext_control(d_sub->demuxer->teletext, + TV_VBI_CONTROL_DECODE_DVB, p + 2); + p += sublen + 2; + len -= sublen + 2; + } + } + continue; + } +#ifdef CONFIG_ASS + if (opts->ass_enabled) { + sh_sub_t* sh = d_sub->sh; + ass_track = sh ? sh->ass_track : NULL; + if (!ass_track) continue; + if (type == 'a') { // ssa/ass subs with libass + ass_process_chunk(ass_track, packet, len, + (long long)(subpts*1000 + 0.5), + (long long)((endpts-subpts)*1000 + 0.5)); + } else { // plaintext subs with libass + if (subpts != MP_NOPTS_VALUE) { + subtitle tmp_subs = {0}; + if (endpts == MP_NOPTS_VALUE) endpts = subpts + 3; + sub_add_text(&tmp_subs, packet, len, endpts); + tmp_subs.start = subpts * 100; + tmp_subs.end = endpts * 100; + ass_process_subtitle(ass_track, &tmp_subs); + sub_clear_text(&tmp_subs, MP_NOPTS_VALUE); + } + } + continue; + } +#endif + if (subpts != MP_NOPTS_VALUE) { + if (endpts == MP_NOPTS_VALUE) + sub_clear_text(&subs, MP_NOPTS_VALUE); + if (type == 'a') { // ssa/ass subs without libass => convert to plaintext + int i; + unsigned char* p = packet; + for (i=0; i < 8 && *p != '\0'; p++) + if (*p == ',') + i++; + if (*p == '\0') /* Broken line? */ + continue; + len -= p - packet; + packet = p; + } + sub_add_text(&subs, packet, len, endpts); + set_osd_subtitle(mpctx, &subs); + } + if (d_sub->non_interleaved) + ds_get_next_pts(d_sub); + } + if (!opts->ass_enabled) + if (sub_clear_text(&subs, curpts)) + set_osd_subtitle(mpctx, &subs); + } + if (vo_spudec) { + spudec_heartbeat(vo_spudec, 90000*curpts); + if (spudec_changed(vo_spudec)) + vo_osd_changed(OSDTYPE_SPU); + } + + current_module=NULL; +} + +static void update_teletext(sh_video_t *sh_video, demuxer_t *demuxer, int reset) +{ + int page_changed; + + if (!demuxer->teletext) + return; + + //Also forcing page update when such ioctl is not supported or call error occured + if(teletext_control(demuxer->teletext,TV_VBI_CONTROL_IS_CHANGED,&page_changed)!=VBI_CONTROL_TRUE) + page_changed=1; + + if(!page_changed) + return; + + if(teletext_control(demuxer->teletext,TV_VBI_CONTROL_GET_VBIPAGE,&vo_osd_teletext_page)!=VBI_CONTROL_TRUE) + vo_osd_teletext_page=NULL; + if(teletext_control(demuxer->teletext,TV_VBI_CONTROL_GET_HALF_PAGE,&vo_osd_teletext_half)!=VBI_CONTROL_TRUE) + vo_osd_teletext_half=0; + if(teletext_control(demuxer->teletext,TV_VBI_CONTROL_GET_MODE,&vo_osd_teletext_mode)!=VBI_CONTROL_TRUE) + vo_osd_teletext_mode=0; + if(teletext_control(demuxer->teletext,TV_VBI_CONTROL_GET_FORMAT,&vo_osd_teletext_format)!=VBI_CONTROL_TRUE) + vo_osd_teletext_format=0; + vo_osd_changed(OSDTYPE_TELETEXT); + + teletext_control(demuxer->teletext,TV_VBI_CONTROL_MARK_UNCHANGED,NULL); +} + static int check_framedrop(struct MPContext *mpctx, double frame_time) { struct MPOpts *opts = &mpctx->opts; // check for frame-drop: @@ -2758,9 +2990,8 @@ static void seek_reset(struct MPContext *mpctx) // be completely wrong (probably 0). mpctx->sh_video->pts = mpctx->d_video->pts + mpctx->video_offset; mpctx->video_pts = mpctx->sh_video->pts; - update_subtitles(mpctx, &mpctx->opts, mpctx->sh_video, - mpctx->sh_video->pts, mpctx->video_offset, - mpctx->d_sub, 1); + update_subtitles(mpctx, mpctx->sh_video->pts, mpctx->video_offset, + true); update_teletext(mpctx->sh_video, mpctx->demuxer, 1); } @@ -2771,8 +3002,8 @@ static void seek_reset(struct MPContext *mpctx) mpctx->sh_audio->a_buffer_len = 0; mpctx->sh_audio->a_out_buffer_len = 0; if (!mpctx->sh_video) - update_subtitles(mpctx, &mpctx->opts, NULL, mpctx->sh_audio->pts, - mpctx->video_offset, mpctx->d_sub, 1); + update_subtitles(mpctx, mpctx->sh_audio->pts, + mpctx->video_offset, true); } if (vo_vobsub && mpctx->sh_video) { @@ -3110,8 +3341,7 @@ static void run_playloop(struct MPContext *mpctx) if (end_at.type == END_AT_TIME && end_at.pos < a_pos) mpctx->stop_play = PT_NEXT_ENTRY; - update_subtitles(mpctx, &mpctx->opts, NULL, a_pos, mpctx->video_offset, - mpctx->d_sub, 0); + update_subtitles(mpctx, a_pos, mpctx->video_offset, false); update_osd_msg(mpctx); } else { @@ -3182,8 +3412,7 @@ static void run_playloop(struct MPContext *mpctx) if (!frame_time_remaining && blit_frame) { struct sh_video *sh_video = mpctx->sh_video; mpctx->video_pts = sh_video->pts; - update_subtitles(mpctx, &mpctx->opts, sh_video, sh_video->pts, - mpctx->video_offset, mpctx->d_sub, 0); + update_subtitles(mpctx, sh_video->pts, mpctx->video_offset, false); update_teletext(sh_video, mpctx->demuxer, 0); update_osd_msg(mpctx); struct vf_instance *vf = sh_video->vfilter; @@ -3576,6 +3805,73 @@ static int read_keys(void *ctx, int fd) return mplayer_get_key(ctx, 0); } +static bool attachment_is_font(struct demux_attachment *att) +{ + if (!att->name || !att->type || !att->data || !att->data_size) + return false; + // match against MIME types + if (strcmp(att->type, "application/x-truetype-font") == 0 + || strcmp(att->type, "application/x-font") == 0) + return true; + // fallback: match against file extension + if (strlen(att->name) > 4) { + char *ext = att->name + strlen(att->name) - 4; + if (strcasecmp(ext, ".ttf") == 0 || strcasecmp(ext, ".ttc") == 0 + || strcasecmp(ext, ".otf") == 0) + return true; + } + return false; +} + +static int select_audio(demuxer_t *demuxer, int audio_id, char *audio_lang) +{ + if (audio_id == -1) + audio_id = demuxer_audio_track_by_lang_and_default(demuxer, audio_lang); + if (audio_id != -1) // -1 (automatic) is the default behaviour of demuxers + demuxer_switch_audio(demuxer, audio_id); + if (audio_id == -2) { // some demuxers don't yet know how to switch to no sound + demuxer->audio->id = -2; + demuxer->audio->sh = NULL; + } + return demuxer->audio->id; +} + +static void print_version(const char* name) +{ + mp_msg(MSGT_CPLAYER, MSGL_INFO, MP_TITLE, name); + + /* Test for CPU capabilities (and corresponding OS support) for optimizing */ + GetCpuCaps(&gCpuCaps); +#if ARCH_X86 + mp_msg(MSGT_CPLAYER, MSGL_V, + "CPUflags: MMX: %d MMX2: %d 3DNow: %d 3DNowExt: %d SSE: %d SSE2: %d SSSE3: %d\n", + gCpuCaps.hasMMX, gCpuCaps.hasMMX2, + gCpuCaps.has3DNow, gCpuCaps.has3DNowExt, + gCpuCaps.hasSSE, gCpuCaps.hasSSE2, gCpuCaps.hasSSSE3); +#if CONFIG_RUNTIME_CPUDETECT + mp_tmsg(MSGT_CPLAYER,MSGL_V, "Compiled with runtime CPU detection.\n"); +#else + mp_tmsg(MSGT_CPLAYER,MSGL_V, "Compiled for x86 CPU with extensions:"); +if (HAVE_MMX) + mp_msg(MSGT_CPLAYER,MSGL_V," MMX"); +if (HAVE_MMX2) + mp_msg(MSGT_CPLAYER,MSGL_V," MMX2"); +if (HAVE_AMD3DNOW) + mp_msg(MSGT_CPLAYER,MSGL_V," 3DNow"); +if (HAVE_AMD3DNOWEXT) + mp_msg(MSGT_CPLAYER,MSGL_V," 3DNowExt"); +if (HAVE_SSE) + mp_msg(MSGT_CPLAYER,MSGL_V," SSE"); +if (HAVE_SSE2) + mp_msg(MSGT_CPLAYER,MSGL_V," SSE2"); +if (HAVE_SSSE3) + mp_msg(MSGT_CPLAYER,MSGL_V," SSSE3"); +if (HAVE_CMOV) + mp_msg(MSGT_CPLAYER,MSGL_V," CMOV"); + mp_msg(MSGT_CPLAYER,MSGL_V,"\n"); +#endif /* CONFIG_RUNTIME_CPUDETECT */ +#endif /* ARCH_X86 */ +} /* This preprocessor directive is a hack to generate a mplayer-nomain.o object * file for some tools to link against. */ -- cgit v1.2.3 From adedee42851d413de87b479340eb015ee33b497b Mon Sep 17 00:00:00 2001 From: Uoti Urpala Date: Wed, 12 Jan 2011 15:15:02 +0200 Subject: subtitles: move global ass_track to struct osd_state --- mplayer.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) (limited to 'mplayer.c') diff --git a/mplayer.c b/mplayer.c index 091287c1fd..f36bb2788f 100644 --- a/mplayer.c +++ b/mplayer.c @@ -335,9 +335,6 @@ int subcc_enabled=0; int suboverlap_enabled = 1; #include "ass_mp.h" -#ifdef CONFIG_ASS -ASS_Track *ass_track = 0; // current track to render -#endif char* current_module=NULL; // for debugging @@ -1949,10 +1946,10 @@ void update_subtitles(struct MPContext *mpctx, double refpts, #ifdef CONFIG_ASS if (opts->ass_enabled) { sh_sub_t* sh = d_sub->sh; - ass_track = sh ? sh->ass_track : NULL; - if (!ass_track) continue; + mpctx->osd->ass_track = sh ? sh->ass_track : NULL; + if (!mpctx->osd->ass_track) continue; if (type == 'a') { // ssa/ass subs with libass - ass_process_chunk(ass_track, packet, len, + ass_process_chunk(mpctx->osd->ass_track, packet, len, (long long)(subpts*1000 + 0.5), (long long)((endpts-subpts)*1000 + 0.5)); } else { // plaintext subs with libass @@ -1962,7 +1959,7 @@ void update_subtitles(struct MPContext *mpctx, double refpts, sub_add_text(&tmp_subs, packet, len, endpts); tmp_subs.start = subpts * 100; tmp_subs.end = endpts * 100; - ass_process_subtitle(ass_track, &tmp_subs); + ass_process_subtitle(mpctx->osd->ass_track, &tmp_subs); sub_clear_text(&tmp_subs, MP_NOPTS_VALUE); } } @@ -3416,7 +3413,7 @@ static void run_playloop(struct MPContext *mpctx) update_teletext(sh_video, mpctx->demuxer, 0); update_osd_msg(mpctx); struct vf_instance *vf = sh_video->vfilter; - vf->control(vf, VFCTRL_DRAW_EOSD, NULL); + vf->control(vf, VFCTRL_DRAW_EOSD, mpctx->osd); vf->control(vf, VFCTRL_DRAW_OSD, mpctx->osd); vo_osd_changed(0); @@ -4944,7 +4941,7 @@ if(mpctx->set_of_sub_size > 0) { mpctx->vo_sub_last = vo_sub=NULL; mpctx->subdata=NULL; #ifdef CONFIG_ASS -ass_track = NULL; +mpctx->osd->ass_track = NULL; if(ass_library) ass_clear_fonts(ass_library); #endif -- cgit v1.2.3 From ac79632ded16b62e0abf10f1cd319fba20bc0024 Mon Sep 17 00:00:00 2001 From: Uoti Urpala Date: Fri, 14 Jan 2011 14:05:22 +0200 Subject: subtitles: remove code trying to handle text subs with libavcodec The avsub implementation tries to fall back to MPlayer's other text subtitle decoding if libavcodec returns text as the 'decoded' subtitle. The code implementing this is buggy, and as far as I can see it should not be triggered normally (libavcodec decoding is only used for xvid, pgs and dvb subtitles, and for those libavcodec should return bitmaps). Remove the buggy code (don't try to support non-bitmap results) and simplify things a bit. --- mplayer.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'mplayer.c') diff --git a/mplayer.c b/mplayer.c index f36bb2788f..382fe2a6f5 100644 --- a/mplayer.c +++ b/mplayer.c @@ -1901,10 +1901,8 @@ void update_subtitles(struct MPContext *mpctx, double refpts, if (d_sub->non_interleaved) ds_get_next_pts(d_sub); - int orig_type = type; while (d_sub->first) { double subpts = ds_get_next_pts(d_sub) + sub_offset; - type = orig_type; if (subpts > curpts) { // Libass handled subs can be fed to it in advance if (!opts->ass_enabled || !is_text_sub(type)) @@ -1917,10 +1915,9 @@ void update_subtitles(struct MPContext *mpctx, double refpts, len = ds_get_packet_sub(d_sub, &packet); if (is_av_sub(type)) { #ifdef CONFIG_FFMPEG - type = decode_avsub(d_sub->sh, &packet, &len, &subpts, &endpts); - if (type <= 0) + decode_avsub(d_sub->sh, packet, len, subpts, endpts); #endif - continue; + continue; } if (type == 'm') { if (len < 2) continue; -- cgit v1.2.3 From 8636eb77c5f9f1e49a12e3e1653fe4c2e8e0bfc3 Mon Sep 17 00:00:00 2001 From: Uoti Urpala Date: Sat, 15 Jan 2011 22:26:27 +0200 Subject: options: add special -leak-report option Add a special option "-leak-report" that enables talloc leak reporting. It only works if it's given as the first argument. The code abuses the CONF_TYPE_PRINT option type to make main option parsing ignore the option. The parser incorrectly consumed the following commandline argument as a "parameter" for options of this type when they had the flag to not exit after printing the message. Fix this. It makes no difference for any previously existing option I think. --- mplayer.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'mplayer.c') diff --git a/mplayer.c b/mplayer.c index 382fe2a6f5..59ce629300 100644 --- a/mplayer.c +++ b/mplayer.c @@ -3871,7 +3871,8 @@ if (HAVE_CMOV) * file for some tools to link against. */ #ifndef DISABLE_MAIN int main(int argc,char* argv[]){ - + if (argc > 1 && !strcmp(argv[1], "-leak-report")) + talloc_enable_leak_report(); char * mem_ptr; -- cgit v1.2.3 From e990fb2ffeaa786339895c8f3b3f104ef536bf39 Mon Sep 17 00:00:00 2001 From: Uoti Urpala Date: Sun, 16 Jan 2011 20:03:08 +0200 Subject: subtitles: add framework for subtitle decoders Add a framework for subtitle decoder modules that work more like audio/video decoders do, and change libass rendering of demuxed subtitles to use the new framework. The old subtitle code is messy, with details specific to handling particular subtitle types spread over high-level code. This should make it easier to clean things up and fix some bugs/limitations. --- mplayer.c | 60 ++++++++++++++++++++++++++++++------------------------------ 1 file changed, 30 insertions(+), 30 deletions(-) (limited to 'mplayer.c') diff --git a/mplayer.c b/mplayer.c index 59ce629300..ecdc4e11af 100644 --- a/mplayer.c +++ b/mplayer.c @@ -72,6 +72,7 @@ #include "libavutil/avstring.h" #include "subreader.h" +#include "sub/dec_sub.h" #include "mp_osd.h" #include "libvo/video_out.h" @@ -601,6 +602,15 @@ static void mp_dvdnav_context_free(MPContext *ctx){ } #endif +static void uninit_subs(struct demuxer *demuxer) +{ + for (int i = 0; i < MAX_S_STREAMS; i++) { + struct sh_sub *sh = demuxer->s_streams[i]; + if (sh && sh->initialized) + sub_uninit(sh); + } +} + void uninit_player(struct MPContext *mpctx, unsigned int mask){ mask &= mpctx->initialized_flags; @@ -614,6 +624,12 @@ void uninit_player(struct MPContext *mpctx, unsigned int mask){ mpctx->mixer.afilter = NULL; } + if (mask & INITIALIZED_SUB) { + mpctx->initialized_flags &= ~INITIALIZED_SUB; + if (mpctx->d_sub->sh) + sub_switchoff(mpctx->d_sub->sh, mpctx->osd); + } + if(mask&INITIALIZED_VCODEC){ mpctx->initialized_flags&=~INITIALIZED_VCODEC; current_module="uninit_vcodec"; @@ -630,6 +646,7 @@ void uninit_player(struct MPContext *mpctx, unsigned int mask){ if (mpctx->num_sources) { mpctx->demuxer = mpctx->sources[0].demuxer; for (int i = 1; i < mpctx->num_sources; i++) { + uninit_subs(mpctx->sources[i].demuxer); free_stream(mpctx->sources[i].stream); free_demuxer(mpctx->sources[i].demuxer); } @@ -646,6 +663,7 @@ void uninit_player(struct MPContext *mpctx, unsigned int mask){ mpctx->video_offset = 0; if(mpctx->demuxer){ mpctx->stream=mpctx->demuxer->stream; + uninit_subs(mpctx->demuxer); free_demuxer(mpctx->demuxer); } mpctx->demuxer=NULL; @@ -1802,11 +1820,6 @@ double playing_audio_pts(struct MPContext *mpctx) mpctx->audio_out->get_delay(); } -static bool is_text_sub(int type) -{ - return type == 't' || type == 'm' || type == 'a'; -} - static bool is_av_sub(int type) { return type == 'b' || type == 'p' || type == 'x'; @@ -1821,9 +1834,12 @@ void update_subtitles(struct MPContext *mpctx, double refpts, double curpts = refpts + sub_delay; unsigned char *packet=NULL; int len; - int type = d_sub->sh ? ((sh_sub_t *)d_sub->sh)->type : 'v'; + struct sh_sub *sh_sub = d_sub->sh; + int type = sh_sub ? sh_sub->type : 'v'; static subtitle subs; if (reset) { + if (sh_sub) + sub_reset(sh_sub, mpctx->osd); sub_clear_text(&subs, MP_NOPTS_VALUE); if (vo_sub) set_osd_subtitle(mpctx, NULL); @@ -1833,7 +1849,7 @@ void update_subtitles(struct MPContext *mpctx, double refpts, } #ifdef CONFIG_FFMPEG if (is_av_sub(type)) - reset_avsub(d_sub->sh); + reset_avsub(sh_sub); #endif return; } @@ -1915,7 +1931,7 @@ void update_subtitles(struct MPContext *mpctx, double refpts, len = ds_get_packet_sub(d_sub, &packet); if (is_av_sub(type)) { #ifdef CONFIG_FFMPEG - decode_avsub(d_sub->sh, packet, len, subpts, endpts); + decode_avsub(sh_sub, packet, len, subpts, endpts); #endif continue; } @@ -1940,29 +1956,13 @@ void update_subtitles(struct MPContext *mpctx, double refpts, } continue; } -#ifdef CONFIG_ASS - if (opts->ass_enabled) { - sh_sub_t* sh = d_sub->sh; - mpctx->osd->ass_track = sh ? sh->ass_track : NULL; - if (!mpctx->osd->ass_track) continue; - if (type == 'a') { // ssa/ass subs with libass - ass_process_chunk(mpctx->osd->ass_track, packet, len, - (long long)(subpts*1000 + 0.5), - (long long)((endpts-subpts)*1000 + 0.5)); - } else { // plaintext subs with libass - if (subpts != MP_NOPTS_VALUE) { - subtitle tmp_subs = {0}; - if (endpts == MP_NOPTS_VALUE) endpts = subpts + 3; - sub_add_text(&tmp_subs, packet, len, endpts); - tmp_subs.start = subpts * 100; - tmp_subs.end = endpts * 100; - ass_process_subtitle(mpctx->osd->ass_track, &tmp_subs); - sub_clear_text(&tmp_subs, MP_NOPTS_VALUE); - } - } + if (sh_sub && sh_sub->active) { + double duration = -1; + if (endpts != MP_NOPTS_VALUE) + duration = endpts - subpts; + sub_decode(sh_sub, mpctx->osd, packet, len, subpts, duration); continue; } -#endif if (subpts != MP_NOPTS_VALUE) { if (endpts == MP_NOPTS_VALUE) sub_clear_text(&subs, MP_NOPTS_VALUE); @@ -3024,7 +3024,7 @@ static bool timeline_set_part(struct MPContext *mpctx, int i) mpctx->video_offset = n->start - n->source_start; if (n->source == p->source) return false; - uninit_player(mpctx, INITIALIZED_VCODEC | (mpctx->opts.fixed_vo && mpctx->opts.video_id != -2 ? 0 : INITIALIZED_VO) | INITIALIZED_AO | INITIALIZED_ACODEC); + uninit_player(mpctx, INITIALIZED_VCODEC | (mpctx->opts.fixed_vo && mpctx->opts.video_id != -2 ? 0 : INITIALIZED_VO) | INITIALIZED_AO | INITIALIZED_ACODEC | INITIALIZED_SUB); mpctx->demuxer = n->source->demuxer; mpctx->d_video = mpctx->demuxer->video; mpctx->d_audio = mpctx->demuxer->audio; -- cgit v1.2.3 From 8e7dae173d07533e1de46fad7bb2f834febe27cf Mon Sep 17 00:00:00 2001 From: Uoti Urpala Date: Sun, 16 Jan 2011 20:51:48 +0200 Subject: subtitles/demux: store duration instead of endpts in demux packets --- mplayer.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'mplayer.c') diff --git a/mplayer.c b/mplayer.c index ecdc4e11af..c09fa7ada9 100644 --- a/mplayer.c +++ b/mplayer.c @@ -1927,11 +1927,11 @@ void update_subtitles(struct MPContext *mpctx, double refpts, if (d_sub->non_interleaved && subpts > curpts + 1) break; } - double endpts = d_sub->first->endpts + sub_offset; + double duration = d_sub->first->duration; len = ds_get_packet_sub(d_sub, &packet); if (is_av_sub(type)) { #ifdef CONFIG_FFMPEG - decode_avsub(sh_sub, packet, len, subpts, endpts); + decode_avsub(sh_sub, packet, len, subpts, duration); #endif continue; } @@ -1957,14 +1957,11 @@ void update_subtitles(struct MPContext *mpctx, double refpts, continue; } if (sh_sub && sh_sub->active) { - double duration = -1; - if (endpts != MP_NOPTS_VALUE) - duration = endpts - subpts; sub_decode(sh_sub, mpctx->osd, packet, len, subpts, duration); continue; } if (subpts != MP_NOPTS_VALUE) { - if (endpts == MP_NOPTS_VALUE) + if (duration < 0) sub_clear_text(&subs, MP_NOPTS_VALUE); if (type == 'a') { // ssa/ass subs without libass => convert to plaintext int i; @@ -1977,6 +1974,9 @@ void update_subtitles(struct MPContext *mpctx, double refpts, len -= p - packet; packet = p; } + double endpts = MP_NOPTS_VALUE; + if (subpts != MP_NOPTS_VALUE && duration >= 0) + endpts = subpts + duration; sub_add_text(&subs, packet, len, endpts); set_osd_subtitle(mpctx, &subs); } -- cgit v1.2.3 From d5eaf6a820d73181f07de3387cd1c115a49648f5 Mon Sep 17 00:00:00 2001 From: Uoti Urpala Date: Sun, 16 Jan 2011 21:16:47 +0200 Subject: core: ordered chapters: fix bad subtitle parameter mp_property_do() takes the value to set a property to through a pointer. The calling code used '&mpctx->global_sub_pos' as the pointer; however that variable could be changed during the mp_property_do() call. Use a pointer to a copy of the original value instead. I think this only caused problems if you switched subtitle tracks from a real one to "disabled" and then switched to a timeline part from another source. --- mplayer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'mplayer.c') diff --git a/mplayer.c b/mplayer.c index c09fa7ada9..69e4dcd0fb 100644 --- a/mplayer.c +++ b/mplayer.c @@ -2963,7 +2963,7 @@ static void reinit_decoders(struct MPContext *mpctx) { reinit_video_chain(mpctx); reinit_audio_chain(mpctx); - mp_property_do("sub", M_PROPERTY_SET, &mpctx->global_sub_pos, mpctx); + mp_property_do("sub", M_PROPERTY_SET, &(int){mpctx->global_sub_pos}, mpctx); } static void seek_reset(struct MPContext *mpctx) -- cgit v1.2.3 From 4284cf9ef050044619c773b195f0eb941f922e88 Mon Sep 17 00:00:00 2001 From: Uoti Urpala Date: Wed, 19 May 2010 01:05:25 +0300 Subject: subtitles: style support for common SubRip tags and MicroDVD MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SubRip subtitles have no "official" spec for any styling support, but various tags are in common use; previous code filtered out text between <> to remove HTML-style tags. Add support for those tags and for MicroDVD subtitle styling. The style display is implemented by converting the subtitles to the ASS subtitle format and displaying them with libass, so libass needs to be enabled. Original patch by Clément Bœsch . --- mplayer.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'mplayer.c') diff --git a/mplayer.c b/mplayer.c index 69e4dcd0fb..1c41e35f9d 100644 --- a/mplayer.c +++ b/mplayer.c @@ -1105,7 +1105,7 @@ void add_subtitles(struct MPContext *mpctx, char *filename, float fps, int noerr asst = ass_read_stream(ass_library, filename, 0); #endif if (!asst) { - subd = sub_read_file(filename, fps); + subd = sub_read_file(filename, fps, &mpctx->opts); if (subd) { asst = ass_read_subdata(ass_library, subd, fps); if (asst) { @@ -1116,7 +1116,7 @@ void add_subtitles(struct MPContext *mpctx, char *filename, float fps, int noerr } } else #endif - subd = sub_read_file(filename, fps); + subd = sub_read_file(filename, fps, &mpctx->opts); if (!asst && !subd) { -- cgit v1.2.3 From 8612c771fcb7321a2d6e0ba79f6f3cf26ee7f70c Mon Sep 17 00:00:00 2001 From: Uoti Urpala Date: Wed, 19 Jan 2011 18:00:22 +0200 Subject: cleanup: some random minor code simplification and cleanup --- mplayer.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'mplayer.c') diff --git a/mplayer.c b/mplayer.c index 1c41e35f9d..00d568b359 100644 --- a/mplayer.c +++ b/mplayer.c @@ -1093,9 +1093,8 @@ void add_subtitles(struct MPContext *mpctx, char *filename, float fps, int noerr sub_data *subd = NULL; struct ass_track *asst = NULL; - if (filename == NULL || mpctx->set_of_sub_size >= MAX_SUBTITLE_FILES) { + if (filename == NULL || mpctx->set_of_sub_size >= MAX_SUBTITLE_FILES) return; - } #ifdef CONFIG_ASS if (opts->ass_enabled) { @@ -1108,10 +1107,8 @@ void add_subtitles(struct MPContext *mpctx, char *filename, float fps, int noerr subd = sub_read_file(filename, fps, &mpctx->opts); if (subd) { asst = ass_read_subdata(ass_library, subd, fps); - if (asst) { - sub_free(subd); - subd = NULL; - } + sub_free(subd); + subd = NULL; } } } else -- cgit v1.2.3 From 966340b31a7bc53e922118da1cd4783d6a06483d Mon Sep 17 00:00:00 2001 From: Uoti Urpala Date: Wed, 19 Jan 2011 20:13:48 +0200 Subject: subs: use correct font aspect ratio for libass + converted subs Rendering of ASS subtitles tries to be bug compatible with VSFilter and stretches fonts when the video is anamorphic (some scripts try to compensate for this VSFilter behavior, so trying to render them "correctly" would give the wrong result). However this behavior is not appropriate for subtitles we converted to ASS format ourselves for libass rendering, as they certainly don't have VSFilter bug workarounds. Change the code to use different behavior for "native" ASS tracks and converted ones. It's questionable whether the VSFilter-compatible behavior is appropriate for external .ass files either, as there could be anamorphic and non-anamorphic versions of the same video and the bug-compatible behavior can only be correct for one alternative at most. However it's probably better to keep it as a default at least, so that extracting a muxed subtitle track and using that does not give behavior different from the original muxed one. The aspect ratio setting is per ASS_Renderer, and changing it resets libass caches. For that reason this commit adds separate renderer instances to use for the "correct" and "VSFilter bug compatible" cases. --- mplayer.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'mplayer.c') diff --git a/mplayer.c b/mplayer.c index 00d568b359..90e454961a 100644 --- a/mplayer.c +++ b/mplayer.c @@ -1092,6 +1092,7 @@ void add_subtitles(struct MPContext *mpctx, char *filename, float fps, int noerr struct MPOpts *opts = &mpctx->opts; sub_data *subd = NULL; struct ass_track *asst = NULL; + bool is_native_ass = false; if (filename == NULL || mpctx->set_of_sub_size >= MAX_SUBTITLE_FILES) return; @@ -1103,6 +1104,7 @@ void add_subtitles(struct MPContext *mpctx, char *filename, float fps, int noerr #else asst = ass_read_stream(ass_library, filename, 0); #endif + is_native_ass = asst; if (!asst) { subd = sub_read_file(filename, fps, &mpctx->opts); if (subd) { @@ -1124,6 +1126,7 @@ void add_subtitles(struct MPContext *mpctx, char *filename, float fps, int noerr mpctx->set_of_ass_tracks[mpctx->set_of_sub_size] = asst; mpctx->set_of_subtitles[mpctx->set_of_sub_size] = subd; + mpctx->track_was_native_ass[mpctx->set_of_sub_size] = is_native_ass; mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_FILE_SUB_ID=%d\n", mpctx->set_of_sub_size); mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_FILE_SUB_FILENAME=%s\n", filename_recode(filename)); -- cgit v1.2.3 From a248c2c7a137517061e6271f22b84d43bcd7191d Mon Sep 17 00:00:00 2001 From: Uoti Urpala Date: Thu, 20 Jan 2011 18:47:18 +0200 Subject: cleanup: rename ass_* functions to mp_ass_* The various ass_* functions were created when libass was part of the MPlayer tree and the distinction between MPlayer-specific and other functions was less clear. Now that libass is a clearly separate library, using the same ass_* namespace for player functions is ugly. Rename the functions to use mp_ass_ prefix instead. --- mplayer.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'mplayer.c') diff --git a/mplayer.c b/mplayer.c index 90e454961a..a72b014349 100644 --- a/mplayer.c +++ b/mplayer.c @@ -1100,15 +1100,15 @@ void add_subtitles(struct MPContext *mpctx, char *filename, float fps, int noerr #ifdef CONFIG_ASS if (opts->ass_enabled) { #ifdef CONFIG_ICONV - asst = ass_read_stream(ass_library, filename, sub_cp); + asst = mp_ass_read_stream(ass_library, filename, sub_cp); #else - asst = ass_read_stream(ass_library, filename, 0); + asst = mp_ass_read_stream(ass_library, filename, 0); #endif is_native_ass = asst; if (!asst) { subd = sub_read_file(filename, fps, &mpctx->opts); if (subd) { - asst = ass_read_subdata(ass_library, subd, fps); + asst = mp_ass_read_subdata(ass_library, subd, fps); sub_free(subd); subd = NULL; } @@ -4091,7 +4091,7 @@ if(!codecs_file || !parse_codec_cfg(codecs_file)){ #endif #ifdef CONFIG_ASS - ass_library = ass_init(); + ass_library = mp_ass_init(); #endif #ifdef HAVE_RTC -- cgit v1.2.3 From 304cafd31dfaeee853e138a460b7ba82e65ed420 Mon Sep 17 00:00:00 2001 From: Uoti Urpala Date: Mon, 24 Jan 2011 00:29:01 +0200 Subject: demux_mkv, chapters: change millisecond arithmetic to ns demux_mkv kept various integer timestamps in millisecond units. Matroska timestamp arithmetic is however specified in nanoseconds (even though files typically use 1 ms precision), and using ms units instead of that only made things more complex. Based on the demux_mkv example the general demuxer-level chapter structure also used ms units. Change the demux_mkv arithmetic and demuxer chapter structures to use nanoseconds instead. This also fixes a seeking problem in demux_mkv with files using a TimecodeScale other than the usual 1000000 (confusion between ms and TimecodeScale*ns units). --- mplayer.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'mplayer.c') diff --git a/mplayer.c b/mplayer.c index a72b014349..1d8b74892c 100644 --- a/mplayer.c +++ b/mplayer.c @@ -3734,11 +3734,12 @@ static void build_ordered_chapter_timeline(struct MPContext *mpctx) * specify chapter end times that are one frame too early; * we don't want to try seeking over a one frame gap. */ int64_t join_diff = c->start - starttime - prev_part_offset; - if (part_count == 0 || FFABS(join_diff) > opts->chapter_merge_threshold + if (part_count == 0 + || FFABS(join_diff) > opts->chapter_merge_threshold * 1000000 || sources + j != timeline[part_count - 1].source) { timeline[part_count].source = sources + j; - timeline[part_count].start = starttime / 1000.; - timeline[part_count].source_start = c->start / 1000.; + timeline[part_count].start = starttime / 1e9; + timeline[part_count].source_start = c->start / 1e9; prev_part_offset = c->start - starttime; part_count++; } else if (part_count > 0 && join_diff) { @@ -3748,12 +3749,12 @@ static void build_ordered_chapter_timeline(struct MPContext *mpctx) "offset %d ms.\n", i, (int) join_diff); starttime += join_diff; } - chapters[num_chapters].start = starttime / 1000.; + chapters[num_chapters].start = starttime / 1e9; chapters[num_chapters].name = talloc_strdup(chapters, c->name); starttime += c->end - c->start; num_chapters++; } - timeline[part_count].start = starttime / 1000.; + timeline[part_count].start = starttime / 1e9; if (!part_count) { // None of the parts come from the file itself??? @@ -3768,7 +3769,7 @@ static void build_ordered_chapter_timeline(struct MPContext *mpctx) timeline[part_count].start); if (missing_time) mp_msg(MSGT_CPLAYER, MSGL_ERR, "There are %.3f seconds missing " - "from the timeline!\n", missing_time / 1000.); + "from the timeline!\n", missing_time / 1e9); mp_msg(MSGT_CPLAYER, MSGL_V, "Source files:\n"); for (int i = 0; i < num_sources; i++) mp_msg(MSGT_CPLAYER, MSGL_V, "%d: %s\n", i, -- cgit v1.2.3 From c9026cb3210205b07e2e068467a18ee40f9259a3 Mon Sep 17 00:00:00 2001 From: Uoti Urpala Date: Wed, 26 Jan 2011 19:40:52 +0200 Subject: sub/OSD: move some related files to sub/ --- mplayer.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'mplayer.c') diff --git a/mplayer.c b/mplayer.c index 1d8b74892c..5618bd4777 100644 --- a/mplayer.c +++ b/mplayer.c @@ -71,16 +71,16 @@ #include "libavutil/avstring.h" -#include "subreader.h" +#include "sub/subreader.h" #include "sub/dec_sub.h" #include "mp_osd.h" #include "libvo/video_out.h" -#include "libvo/font_load.h" -#include "libvo/sub.h" +#include "sub/font_load.h" +#include "sub/sub.h" #include "ffmpeg_files/intreadwrite.h" -#include "av_sub.h" +#include "sub/av_sub.h" #include "libmpcodecs/dec_teletext.h" #include "cpudetect.h" #include "version.h" @@ -95,8 +95,8 @@ #include "edl.h" -#include "spudec.h" -#include "vobsub.h" +#include "sub/spudec.h" +#include "sub/vobsub.h" #include "osdep/getch2.h" #include "osdep/timer.h" @@ -335,7 +335,7 @@ char *vobsub_name=NULL; int subcc_enabled=0; int suboverlap_enabled = 1; -#include "ass_mp.h" +#include "sub/ass_mp.h" char* current_module=NULL; // for debugging -- cgit v1.2.3