summaryrefslogtreecommitdiffstats
path: root/mplayer.c
diff options
context:
space:
mode:
authorUoti Urpala <uau@glyph.nonexistent.invalid>2011-01-26 20:42:15 +0200
committerUoti Urpala <uau@glyph.nonexistent.invalid>2011-01-26 20:42:15 +0200
commitf50f34245efa1012855a693558680bcfb7c348e5 (patch)
tree76e8fc186a96fdc1106b5c634d5937e514a06037 /mplayer.c
parentec55a188e4d0232acd50fcabc0a3db3be2b9538e (diff)
parentc9026cb3210205b07e2e068467a18ee40f9259a3 (diff)
downloadmpv-f50f34245efa1012855a693558680bcfb7c348e5.tar.bz2
mpv-f50f34245efa1012855a693558680bcfb7c348e5.tar.xz
Merge branch 'sub'
* sub: sub/OSD: move some related files to sub/ subtitles: options: enable -ass by default subtitles: change default libass rendering style demux_mkv, chapters: change millisecond arithmetic to ns cleanup: rename ass_* functions to mp_ass_* subs: use correct font aspect ratio for libass + converted subs cleanup: some random minor code simplification and cleanup vf_vo: fix EOSD change detection bug sd_ass: remove subreader use, support plaintext markup subtitles: style support for common SubRip tags and MicroDVD core: ordered chapters: fix bad subtitle parameter subs/demux: don't try to enable sub track when creating it subtitles/demux: store duration instead of endpts in demux packets subtitles: add framework for subtitle decoders options: add special -leak-report option subtitles: remove code trying to handle text subs with libavcodec cleanup: move MP_NOPTS_VALUE definition to mpcommon.h subtitles: move global ass_track to struct osd_state core: move most mpcommon.c contents to mplayer.c core: move global "subdata" and "vo_sub_last" to mpctx subtitles: remove sub_last_pts hack options: move -noconfig to option struct, simplify
Diffstat (limited to 'mplayer.c')
-rw-r--r--mplayer.c391
1 files changed, 342 insertions, 49 deletions
diff --git a/mplayer.c b/mplayer.c
index e5c9019ccc..fd7dbc6fab 100644
--- a/mplayer.c
+++ b/mplayer.c
@@ -71,13 +71,19 @@
#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 "sub/av_sub.h"
+#include "libmpcodecs/dec_teletext.h"
+#include "cpudetect.h"
+#include "version.h"
#ifdef CONFIG_X11
#include "libvo/x11_common.h"
@@ -89,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"
@@ -328,7 +334,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
@@ -595,6 +601,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;
@@ -608,6 +623,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";
@@ -624,6 +645,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);
}
@@ -640,6 +662,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;
@@ -868,9 +891,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) {
@@ -890,7 +914,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);
@@ -1067,31 +1091,30 @@ 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) {
+ if (filename == NULL || mpctx->set_of_sub_size >= MAX_SUBTITLE_FILES)
return;
- }
#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);
+ 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;
- }
+ asst = mp_ass_read_subdata(ass_library, subd, fps);
+ sub_free(subd);
+ subd = NULL;
}
}
} else
#endif
- subd = sub_read_file(filename, fps);
+ subd = sub_read_file(filename, fps, &mpctx->opts);
if (!asst && !subd) {
@@ -1102,6 +1125,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));
@@ -1795,6 +1819,209 @@ double playing_audio_pts(struct MPContext *mpctx)
mpctx->audio_out->get_delay();
}
+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;
+ 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);
+ if (vo_spudec) {
+ spudec_reset(vo_spudec);
+ vo_osd_changed(OSDTYPE_SPU);
+ }
+#ifdef CONFIG_FFMPEG
+ if (is_av_sub(type))
+ reset_avsub(sh_sub);
+#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, &timestamp);
+ 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);
+
+ while (d_sub->first) {
+ double subpts = ds_get_next_pts(d_sub) + sub_offset;
+ 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 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, duration);
+#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;
+ }
+ if (sh_sub && sh_sub->active) {
+ sub_decode(sh_sub, mpctx->osd, packet, len, subpts, duration);
+ continue;
+ }
+ if (subpts != 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;
+ 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;
+ }
+ 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);
+ }
+ 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:
@@ -2735,7 +2962,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)
@@ -2756,9 +2983,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);
}
@@ -2769,8 +2995,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) {
@@ -2797,7 +3023,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;
@@ -3108,8 +3334,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 {
@@ -3180,12 +3405,11 @@ 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;
- 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);
@@ -3509,11 +3733,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) {
@@ -3523,12 +3748,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???
@@ -3543,7 +3768,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,
@@ -3574,12 +3799,80 @@ 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. */
#ifndef DISABLE_MAIN
int main(int argc,char* argv[]){
-
+ if (argc > 1 && !strcmp(argv[1], "-leak-report"))
+ talloc_enable_leak_report();
char * mem_ptr;
@@ -3798,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
@@ -4413,14 +4706,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;
}
}
@@ -4643,10 +4936,10 @@ 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;
+mpctx->osd->ass_track = NULL;
if(ass_library)
ass_clear_fonts(ass_library);
#endif