summaryrefslogtreecommitdiffstats
path: root/mplayer.c
diff options
context:
space:
mode:
authorUoti Urpala <uau@glyph.nonexistent.invalid>2009-01-14 02:51:24 +0200
committerUoti Urpala <uau@glyph.nonexistent.invalid>2009-01-14 03:42:05 +0200
commit38a76f7fdf5c03bc49072b693d7c53b343f2994a (patch)
tree0e8c7e419f8bbfe9ad55beba0fd17b3de94fb386 /mplayer.c
parent1f782eb802e9774bc53103e935eb673c283cf0aa (diff)
downloadmpv-38a76f7fdf5c03bc49072b693d7c53b343f2994a.tar.bz2
mpv-38a76f7fdf5c03bc49072b693d7c53b343f2994a.tar.xz
core: Better -nocorrect-pts pause and filter-added frames handling
Rewrite the -nocorrect-pts frame creation code. The new version always updates the visible frame when seeking while pausing, and supports filter-added frames. It can not time those properly though. Now the handling of filter-added frames in MPlayer always uses the new method independently of the value of correct-pts but MEncoder still expects the old behavior. Add a global variable that is set under MEncoder only and change the filters to choose behavior based on that instead of the correct_pts option.
Diffstat (limited to 'mplayer.c')
-rw-r--r--mplayer.c120
1 files changed, 69 insertions, 51 deletions
diff --git a/mplayer.c b/mplayer.c
index ac53ed4abb..2ece0607ef 100644
--- a/mplayer.c
+++ b/mplayer.c
@@ -87,6 +87,7 @@
#include "input/input.h"
+const int under_mencoder = 0;
int slave_mode=0;
int player_idle_mode=0;
int quiet=0;
@@ -2209,65 +2210,82 @@ err_out:
return 0;
}
-static double update_video(struct MPContext *mpctx, int *blit_frame)
+static double update_video_nocorrect_pts(struct MPContext *mpctx,
+ int *blit_frame)
{
- struct MPOpts *opts = &mpctx->opts;
- sh_video_t * const sh_video = mpctx->sh_video;
- //-------------------- Decode a frame: -----------------------
- double frame_time;
- *blit_frame = 0; // Don't blit if we hit EOF
- sh_video->vfilter->control(sh_video->vfilter, VFCTRL_SET_OSD_OBJ,
- mpctx->osd); // hack for vf_expand
- if (!opts->correct_pts) {
- unsigned char* start=NULL;
- void *decoded_frame = NULL;
- int drop_frame=0;
- int in_size;
-
- current_module = "video_read_frame";
- frame_time = sh_video->next_frame_time;
- in_size = video_read_frame(sh_video, &sh_video->next_frame_time,
- &start, force_fps);
+ struct sh_video *sh_video = mpctx->sh_video;
+ *blit_frame = 0;
+ double frame_time = 0;
+ while (1) {
+ current_module = "filter_video";
+ // In nocorrect-pts mode there is no way to properly time these frames
+ if (vf_output_queued_frame(sh_video->vfilter))
+ break;
+ unsigned char *packet = NULL;
+ frame_time = sh_video->next_frame_time;
+ if (mpctx->update_video_immediately)
+ frame_time = 0;
+ int in_size = video_read_frame(sh_video, &sh_video->next_frame_time,
+ &packet, force_fps);
+ if (in_size < 0) {
#ifdef CONFIG_DVDNAV
- /// wait, still frame or EOF
- if (mpctx->stream->type == STREAMTYPE_DVDNAV && in_size < 0) {
- if (mp_dvdnav_is_eof(mpctx->stream)) return -1;
- if (mpctx->d_video) mpctx->d_video->eof = 0;
- if (mpctx->d_audio) mpctx->d_audio->eof = 0;
- mpctx->stream->eof = 0;
- } else
+ if (mpctx->stream->type == STREAMTYPE_DVDNAV) {
+ if (mp_dvdnav_is_eof(mpctx->stream))
+ return -1;
+ if (mpctx->d_video)
+ mpctx->d_video->eof = 0;
+ if (mpctx->d_audio)
+ mpctx->d_audio->eof = 0;
+ mpctx->stream->eof = 0;
+ } else
#endif
- if (in_size < 0)
- return -1;
- if (in_size > max_framesize)
- max_framesize = in_size; // stats
- sh_video->timer += frame_time;
- if (mpctx->sh_audio)
- mpctx->delay -= frame_time;
- // video_read_frame can change fps (e.g. for ASF video)
- vo_fps = sh_video->fps;
- drop_frame = check_framedrop(mpctx, frame_time);
- update_subtitles(sh_video, mpctx->d_sub, 0);
- update_teletext(sh_video, mpctx->demuxer, 0);
- update_osd_msg(mpctx);
- current_module = "decode_video";
+ return -1;
+ }
+ if (in_size > max_framesize)
+ max_framesize = in_size;
+ sh_video->timer += frame_time;
+ if (mpctx->sh_audio)
+ mpctx->delay -= frame_time;
+ // video_read_frame can change fps (e.g. for ASF video)
+ vo_fps = sh_video->fps;
+ int framedrop_type = check_framedrop(mpctx, frame_time);
+ current_module = "decode video";
+
+ void *decoded_frame;
#ifdef CONFIG_DVDNAV
- decoded_frame = mp_dvdnav_restore_smpi(mpctx, &in_size,&start,
- decoded_frame);
- /// still frame has been reached, no need to decode
- if (in_size > 0 && !decoded_frame)
+ decoded_frame = mp_dvdnav_restore_smpi(mpctx, &in_size, &packet, NULL);
+ if (in_size >= 0 && !decoded_frame)
#endif
- decoded_frame = decode_video(sh_video, start, in_size, drop_frame,
- sh_video->pts);
+ decoded_frame = decode_video(sh_video, packet, in_size, framedrop_type,
+ sh_video->pts);
#ifdef CONFIG_DVDNAV
- /// save back last still frame for future display
- mp_dvdnav_save_smpi(mpctx, in_size, start, decoded_frame);
+ // Save last still frame for future display
+ mp_dvdnav_restore_smpi(mpctx, in_size, packet, decoded_frame);
#endif
- current_module = "filter_video";
- *blit_frame = (decoded_frame && filter_video(sh_video, decoded_frame,
- sh_video->pts,
- mpctx->osd));
+ if (decoded_frame) {
+ // These updates are done here for vf_expand OSD/subtitles
+ update_subtitles(sh_video, mpctx->d_sub, 0);
+ update_teletext(sh_video, mpctx->demuxer, 0);
+ update_osd_msg(mpctx);
+ current_module = "filter video";
+ if (filter_video(sh_video, decoded_frame, sh_video->pts,
+ mpctx->osd))
+ break;
+ }
}
+ *blit_frame = 1;
+ return frame_time;
+}
+
+static double update_video(struct MPContext *mpctx, int *blit_frame)
+{
+ struct sh_video *sh_video = mpctx->sh_video;
+ double frame_time;
+ *blit_frame = 0;
+ sh_video->vfilter->control(sh_video->vfilter, VFCTRL_SET_OSD_OBJ,
+ mpctx->osd); // hack for vf_expand
+ if (!mpctx->opts.correct_pts)
+ return update_video_nocorrect_pts(mpctx, blit_frame);
else {
int res = generate_video_frame(mpctx);
if (!res)