summaryrefslogtreecommitdiffstats
path: root/mplayer.c
diff options
context:
space:
mode:
authorUoti Urpala <uau@glyph.nonexistent.invalid>2010-12-13 21:12:49 +0200
committerUoti Urpala <uau@glyph.nonexistent.invalid>2010-12-13 21:12:49 +0200
commit188fbb6622cdc0429f7f966e239354cc054cd077 (patch)
treedb7f2b7d9338c48a6069afbc5b8a37e03febc5dd /mplayer.c
parent387326e54b7dbc4d1eac96c5e114b9ff6f33f608 (diff)
downloadmpv-188fbb6622cdc0429f7f966e239354cc054cd077.tar.bz2
mpv-188fbb6622cdc0429f7f966e239354cc054cd077.tar.xz
core: move central play loop to a separate function
Diffstat (limited to 'mplayer.c')
-rw-r--r--mplayer.c576
1 files changed, 287 insertions, 289 deletions
diff --git a/mplayer.c b/mplayer.c
index 4707936447..16726c7b0a 100644
--- a/mplayer.c
+++ b/mplayer.c
@@ -3027,6 +3027,291 @@ int seek_chapter(struct MPContext *mpctx, int chapter, double *seek_pts,
return chapter;
}
+
+static void run_playloop(struct MPContext *mpctx)
+{
+ struct MPOpts *opts = &mpctx->opts;
+ float aq_sleep_time = 0;
+
+ if (opts->chapterrange[1] > 0) {
+ int cur_chapter = get_current_chapter(mpctx);
+ if (cur_chapter!=-1 && cur_chapter + 1 > opts->chapterrange[1])
+ mpctx->stop_play = PT_NEXT_ENTRY;
+ }
+
+ if (!mpctx->sh_audio && mpctx->d_audio->sh) {
+ mpctx->sh_audio = mpctx->d_audio->sh;
+ mpctx->sh_audio->ds = mpctx->d_audio;
+ reinit_audio_chain(mpctx);
+ }
+
+/*========================== PLAY AUDIO ============================*/
+
+ if (mpctx->sh_audio && !mpctx->paused
+ && (!mpctx->restart_playback || !mpctx->sh_video))
+ if (!fill_audio_out_buffers(mpctx))
+ // at eof, all audio at least written to ao
+ if (!mpctx->sh_video)
+ mpctx->stop_play = AT_END_OF_FILE;
+
+
+ if (!mpctx->sh_video) {
+ // handle audio-only case:
+ double a_pos = 0;
+ // sh_audio can be NULL due to video stream switching
+ // TODO: handle this better
+ if (mpctx->sh_audio)
+ a_pos = playing_audio_pts(mpctx);
+
+ print_status(mpctx, a_pos, false);
+
+ 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_osd_msg(mpctx);
+ } else {
+
+/*========================== PLAY VIDEO ============================*/
+
+ vo_pts = mpctx->sh_video->timer * 90000.0;
+ vo_fps = mpctx->sh_video->fps;
+
+ bool blit_frame = mpctx->video_out->frame_loaded;
+ if (!blit_frame) {
+ double frame_time = update_video(mpctx);
+ blit_frame = mpctx->video_out->frame_loaded;
+ mp_dbg(MSGT_AVSYNC, MSGL_DBG2, "*** ftime=%5.3f ***\n", frame_time);
+ if (mpctx->sh_video->vf_initialized < 0) {
+ mp_tmsg(MSGT_CPLAYER, MSGL_FATAL,
+ "\nFATAL: Could not initialize video filters (-vf) "
+ "or video output (-vo).\n");
+ mpctx->stop_play = PT_NEXT_ENTRY;
+ return;
+ }
+ if (blit_frame) {
+ struct sh_video *sh_video = mpctx->sh_video;
+ update_subtitles(mpctx, &mpctx->opts, sh_video, sh_video->pts,
+ mpctx->video_offset, mpctx->d_sub, 0);
+ update_teletext(sh_video, mpctx->demuxer, 0);
+ update_osd_msg(mpctx);
+ struct vf_instance *vf = mpctx->sh_video->vfilter;
+ vf->control(vf, VFCTRL_DRAW_EOSD, NULL);
+ vf->control(vf, VFCTRL_DRAW_OSD, mpctx->osd);
+ vo_osd_changed(0);
+ }
+ if (frame_time < 0)
+ mpctx->stop_play = AT_END_OF_FILE;
+ else if (!mpctx->restart_playback) {
+ mpctx->time_frame += frame_time / opts->playback_speed;
+ adjust_sync(mpctx, frame_time);
+ }
+ }
+ if (mpctx->timeline) {
+ struct timeline_part *next =
+ mpctx->timeline + mpctx->timeline_part + 1;
+ if (mpctx->sh_video->pts >= next->start
+ || mpctx->stop_play == AT_END_OF_FILE
+ && mpctx->timeline_part + 1 < mpctx->num_timeline_parts) {
+ seek(mpctx, next->start, SEEK_ABSOLUTE);
+ return;
+ }
+ }
+
+// ==========================================================================
+
+ current_module = "vo_check_events";
+ vo_check_events(mpctx->video_out);
+
+#ifdef CONFIG_X11
+ if (stop_xscreensaver) {
+ current_module = "stop_xscreensaver";
+ xscreensaver_heartbeat(mpctx->x11_state);
+ }
+#endif
+ if (heartbeat_cmd) {
+ static unsigned last_heartbeat;
+ unsigned now = GetTimerMS();
+ if (now - last_heartbeat > 30000) {
+ last_heartbeat = now;
+ system(heartbeat_cmd);
+ }
+ }
+
+ bool frame_time_remaining = sleep_until_update(mpctx,
+ &mpctx->time_frame,
+ &aq_sleep_time);
+
+//====================== FLIP PAGE (VIDEO BLT): =========================
+
+ current_module = "flip_page";
+ if (!frame_time_remaining && blit_frame) {
+ unsigned int t2 = GetTimer();
+ unsigned int pts_us = mpctx->last_time + mpctx->time_frame * 1e6;
+ int duration = -1;
+ double pts2 = mpctx->video_out->next_pts2;
+ if (pts2 != MP_NOPTS_VALUE && opts->correct_pts
+ && !mpctx->restart_playback) {
+ // expected A/V sync correction is ignored
+ double diff = (pts2 - mpctx->sh_video->pts);
+ diff /= opts->playback_speed;
+ if (mpctx->time_frame < 0)
+ diff += mpctx->time_frame;
+ if (diff < 0)
+ diff = 0;
+ if (diff > 10)
+ diff = 10;
+ duration = diff * 1e6;
+ }
+ vo_flip_page(mpctx->video_out, pts_us | 1, duration);
+
+ mpctx->last_vo_flip_duration = (GetTimer() - t2) * 0.000001;
+ vout_time_usage += mpctx->last_vo_flip_duration;
+ if (mpctx->video_out->driver->flip_page_timed) {
+ // No need to adjust sync based on flip speed
+ mpctx->last_vo_flip_duration = 0;
+ // For print_status - VO call finishing early is OK for sync
+ mpctx->time_frame -= get_relative_time(mpctx);
+ }
+ if (mpctx->restart_playback) {
+ mpctx->syncing_audio = true;
+ if (mpctx->sh_audio && !mpctx->paused)
+ fill_audio_out_buffers(mpctx);
+ mpctx->restart_playback = false;
+ mpctx->time_frame = 0;
+ get_relative_time(mpctx);
+ }
+ print_status(mpctx, MP_NOPTS_VALUE, true);
+ } else
+ print_status(mpctx, MP_NOPTS_VALUE, false);
+
+//============================ Auto QUALITY ============================
+
+/*Output quality adjustments:*/
+ if (opts->auto_quality > 0) {
+ current_module = "autoq";
+ if (output_quality < opts->auto_quality && aq_sleep_time > 0)
+ ++output_quality;
+ else
+ if (output_quality>1 && aq_sleep_time<0)
+ --output_quality;
+ else if (output_quality>0 && aq_sleep_time<-0.050f) // 50ms
+ output_quality = 0;
+ set_video_quality(mpctx->sh_video, output_quality);
+ }
+
+ if (!frame_time_remaining && blit_frame) {
+ if (play_n_frames >= 0) {
+ --play_n_frames;
+ if (play_n_frames <= 0)
+ mpctx->stop_play = PT_NEXT_ENTRY;
+ }
+ if (mpctx->step_frames > 0) {
+ mpctx->step_frames--;
+ if (mpctx->step_frames == 0)
+ pause_player(mpctx);
+ }
+ }
+
+// FIXME: add size based support for -endpos
+ if (end_at.type == END_AT_TIME &&
+ !frame_time_remaining && end_at.pos <= mpctx->sh_video->pts)
+ mpctx->stop_play = PT_NEXT_ENTRY;
+
+ } // end if(mpctx->sh_video)
+
+#ifdef CONFIG_DVDNAV
+ if (mpctx->stream->type == STREAMTYPE_DVDNAV) {
+ nav_highlight_t hl;
+ mp_dvdnav_get_highlight(mpctx->stream, &hl);
+ if (!vo_spudec || !spudec_apply_palette_crop(vo_spudec, hl.palette, hl.sx, hl.sy, hl.ex, hl.ey)) {
+ osd_set_nav_box(hl.sx, hl.sy, hl.ex, hl.ey);
+ vo_osd_changed(OSDTYPE_DVDNAV);
+ } else {
+ osd_set_nav_box(0, 0, 0, 0);
+ vo_osd_changed(OSDTYPE_DVDNAV);
+ vo_osd_changed(OSDTYPE_SPU);
+ }
+
+ if (mp_dvdnav_stream_has_changed(mpctx->stream)) {
+ double ar = -1.0;
+ if (mpctx->sh_video &&
+ stream_control(mpctx->demuxer->stream,
+ STREAM_CTRL_GET_ASPECT_RATIO, &ar)
+ != STREAM_UNSUPPORTED)
+ mpctx->sh_video->stream_aspect = ar;
+ }
+ }
+#endif
+
+//================= Keyboard events, SEEKing ====================
+
+ current_module = "key_events";
+
+ while (1) {
+ mp_cmd_t *cmd;
+ while ((cmd = mp_input_get_cmd(mpctx->input, 0, 0)) != NULL) {
+ run_command(mpctx, cmd);
+ mp_cmd_free(cmd);
+ if (mpctx->stop_play)
+ break;
+ if (mpctx->rel_seek_secs || mpctx->abs_seek_pos) {
+ cmd = mp_input_get_cmd(mpctx->input, 0, 1);
+ /* Allow seek commands to be combined, but execute the real seek
+ * before processing other commands */
+ if (!cmd || cmd->id != MP_CMD_SEEK)
+ break;
+ }
+ }
+ if (!mpctx->paused || mpctx->stop_play || mpctx->rel_seek_secs
+ || mpctx->abs_seek_pos)
+ break;
+ if (mpctx->sh_video) {
+ update_osd_msg(mpctx);
+ int hack = vo_osd_changed(0);
+ vo_osd_changed(hack);
+ if (hack) {
+ if (redraw_osd(mpctx->sh_video, mpctx->osd) < 0) {
+ add_step_frame(mpctx);
+ break;
+ } else
+ vo_osd_changed(0);
+ }
+ }
+ pause_loop(mpctx);
+ }
+
+// handle -sstep
+ if (step_sec > 0 && !mpctx->paused) {
+ mpctx->osd_function = OSD_FFW;
+ mpctx->rel_seek_secs += step_sec;
+ }
+
+ edl_update(mpctx);
+
+ /* Looping. */
+ if (mpctx->stop_play==AT_END_OF_FILE && opts->loop_times>=0) {
+ mp_msg(MSGT_CPLAYER, MSGL_V, "loop_times = %d\n", opts->loop_times);
+
+ if (opts->loop_times>1)
+ opts->loop_times--;
+ else if (opts->loop_times==1)
+ opts->loop_times = -1;
+ play_n_frames = play_n_frames_mf;
+ mpctx->stop_play = 0;
+ mpctx->abs_seek_pos = SEEK_ABSOLUTE;
+ mpctx->rel_seek_secs = seek_to_sec;
+ }
+
+ if (mpctx->rel_seek_secs || mpctx->abs_seek_pos) {
+ seek(mpctx, mpctx->rel_seek_secs, mpctx->abs_seek_pos);
+
+ mpctx->rel_seek_secs = 0;
+ mpctx->abs_seek_pos = 0;
+ }
+}
+
+
static int find_ordered_chapter_sources(struct MPContext *mpctx,
struct content_source *sources,
int num_sources,
@@ -4127,8 +4412,6 @@ if (verbose)
opts->term_osd = 0;
{
-int frame_time_remaining=0; // flag
-int blit_frame=0;
// Make sure old OSD does not stay around,
// e.g. with -fixed-vo and same-resolution files
@@ -4240,293 +4523,8 @@ if (mpctx->stream->type == STREAMTYPE_DVDNAV) {
vo_control(mpctx->video_out, mpctx->paused ? VOCTRL_PAUSE : VOCTRL_RESUME,
NULL);
-while(!mpctx->stop_play){
- float aq_sleep_time=0;
-
-if (opts->chapterrange[1] > 0) {
- int cur_chapter = get_current_chapter(mpctx);
- if(cur_chapter!=-1 && cur_chapter+1 > opts->chapterrange[1])
- goto goto_next_file;
-}
-
-if(!mpctx->sh_audio && mpctx->d_audio->sh) {
- mpctx->sh_audio = mpctx->d_audio->sh;
- mpctx->sh_audio->ds = mpctx->d_audio;
- reinit_audio_chain(mpctx);
-}
-
-/*========================== PLAY AUDIO ============================*/
-
-if (mpctx->sh_audio && !mpctx->paused
- && (!mpctx->restart_playback || !mpctx->sh_video))
- if (!fill_audio_out_buffers(mpctx))
- // at eof, all audio at least written to ao
- if (!mpctx->sh_video)
- mpctx->stop_play = AT_END_OF_FILE;
-
-
-if(!mpctx->sh_video) {
- // handle audio-only case:
- double a_pos=0;
- // sh_audio can be NULL due to video stream switching
- // TODO: handle this better
- if (mpctx->sh_audio)
- a_pos = playing_audio_pts(mpctx);
-
- print_status(mpctx, a_pos, false);
-
- 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_osd_msg(mpctx);
-
-} else {
-
-/*========================== PLAY VIDEO ============================*/
-
- vo_pts=mpctx->sh_video->timer*90000.0;
- vo_fps=mpctx->sh_video->fps;
-
- blit_frame = mpctx->video_out->frame_loaded;
- if (!blit_frame) {
- double frame_time = update_video(mpctx);
- blit_frame = mpctx->video_out->frame_loaded;
- mp_dbg(MSGT_AVSYNC,MSGL_DBG2,"*** ftime=%5.3f ***\n",frame_time);
- if (mpctx->sh_video->vf_initialized < 0) {
- mp_tmsg(MSGT_CPLAYER,MSGL_FATAL, "\nFATAL: Could not initialize video filters (-vf) or video output (-vo).\n");
- mpctx->stop_play = PT_NEXT_ENTRY;
- goto goto_next_file;
- }
- if (blit_frame) {
- struct sh_video *sh_video = mpctx->sh_video;
- update_subtitles(mpctx, &mpctx->opts, sh_video, sh_video->pts,
- mpctx->video_offset, mpctx->d_sub, 0);
- update_teletext(sh_video, mpctx->demuxer, 0);
- update_osd_msg(mpctx);
- struct vf_instance *vf = mpctx->sh_video->vfilter;
- vf->control(vf, VFCTRL_DRAW_EOSD, NULL);
- vf->control(vf, VFCTRL_DRAW_OSD, mpctx->osd);
- vo_osd_changed(0);
- }
- if (frame_time < 0)
- mpctx->stop_play = AT_END_OF_FILE;
- else if (!mpctx->restart_playback) {
- mpctx->time_frame += frame_time / opts->playback_speed;
- adjust_sync(mpctx, frame_time);
- }
- }
- if (mpctx->timeline) {
- struct timeline_part *next = mpctx->timeline + mpctx->timeline_part + 1;
- if (mpctx->sh_video->pts >= next->start
- || mpctx->stop_play == AT_END_OF_FILE
- && mpctx->timeline_part + 1 < mpctx->num_timeline_parts) {
- seek(mpctx, next->start, SEEK_ABSOLUTE);
- continue;
- }
- }
-
-// ==========================================================================
-
-// current_module="draw_osd";
-// if(vo_config_count) mpctx->video_out->draw_osd();
-
- current_module="vo_check_events";
- vo_check_events(mpctx->video_out);
-
-#ifdef CONFIG_X11
- if (stop_xscreensaver) {
- current_module = "stop_xscreensaver";
- xscreensaver_heartbeat(mpctx->x11_state);
- }
-#endif
- if (heartbeat_cmd) {
- static unsigned last_heartbeat;
- unsigned now = GetTimerMS();
- if (now - last_heartbeat > 30000) {
- last_heartbeat = now;
- system(heartbeat_cmd);
- }
- }
-
- frame_time_remaining = sleep_until_update(mpctx, &mpctx->time_frame, &aq_sleep_time);
-
-//====================== FLIP PAGE (VIDEO BLT): =========================
-
- current_module="flip_page";
- if (!frame_time_remaining && blit_frame) {
- unsigned int t2=GetTimer();
- unsigned int pts_us = mpctx->last_time + mpctx->time_frame * 1e6;
- int duration = -1;
- double pts2 = mpctx->video_out->next_pts2;
- if (pts2 != MP_NOPTS_VALUE && opts->correct_pts
- && !mpctx->restart_playback) {
- // expected A/V sync correction is ignored
- double diff = (pts2 - mpctx->sh_video->pts);
- diff /= opts->playback_speed;
- if (mpctx->time_frame < 0)
- diff += mpctx->time_frame;
- if (diff < 0)
- diff = 0;
- if (diff > 10)
- diff = 10;
- duration = diff * 1e6;
- }
- vo_flip_page(mpctx->video_out, pts_us|1, duration);
-
- mpctx->last_vo_flip_duration = (GetTimer() - t2) * 0.000001;
- vout_time_usage += mpctx->last_vo_flip_duration;
- if (mpctx->video_out->driver->flip_page_timed) {
- // No need to adjust sync based on flip speed
- mpctx->last_vo_flip_duration = 0;
- // For print_status - VO call finishing early is OK for sync
- mpctx->time_frame -= get_relative_time(mpctx);
- }
- if (mpctx->restart_playback) {
- mpctx->syncing_audio = true;
- if (mpctx->sh_audio && !mpctx->paused)
- fill_audio_out_buffers(mpctx);
- mpctx->restart_playback = false;
- mpctx->time_frame = 0;
- get_relative_time(mpctx);
- }
- print_status(mpctx, MP_NOPTS_VALUE, true);
- }
- else
- print_status(mpctx, MP_NOPTS_VALUE, false);
-
-//============================ Auto QUALITY ============================
-
-/*Output quality adjustments:*/
-if (opts->auto_quality > 0) {
- current_module="autoq";
-// float total=0.000001f * (GetTimer()-aq_total_time);
-// if (output_quality < opts->auto_quality && aq_sleep_time > 0.05f * total)
- if (output_quality < opts->auto_quality && aq_sleep_time > 0)
- ++output_quality;
- else
-// if(output_quality>0 && aq_sleep_time<-0.05f*total)
- if(output_quality>1 && aq_sleep_time<0)
- --output_quality;
- else
- if(output_quality>0 && aq_sleep_time<-0.050f) // 50ms
- output_quality=0;
-// printf("total: %8.6f sleep: %8.6f q: %d\n",(0.000001f*aq_total_time),aq_sleep_time,output_quality);
- set_video_quality(mpctx->sh_video,output_quality);
-}
-
- if (!frame_time_remaining && blit_frame) {
- if (play_n_frames >= 0) {
- --play_n_frames;
- if (play_n_frames <= 0)
- mpctx->stop_play = PT_NEXT_ENTRY;
- }
- if (mpctx->step_frames > 0) {
- mpctx->step_frames--;
- if (mpctx->step_frames == 0)
- pause_player(mpctx);
- }
- }
-
-
-// FIXME: add size based support for -endpos
- if (end_at.type == END_AT_TIME &&
- !frame_time_remaining && end_at.pos <= mpctx->sh_video->pts)
- mpctx->stop_play = PT_NEXT_ENTRY;
-
-} // end if(mpctx->sh_video)
-
-#ifdef CONFIG_DVDNAV
- if (mpctx->stream->type == STREAMTYPE_DVDNAV) {
- nav_highlight_t hl;
- mp_dvdnav_get_highlight (mpctx->stream, &hl);
- if (!vo_spudec || !spudec_apply_palette_crop(vo_spudec, hl.palette, hl.sx, hl.sy, hl.ex, hl.ey)) {
- osd_set_nav_box (hl.sx, hl.sy, hl.ex, hl.ey);
- vo_osd_changed (OSDTYPE_DVDNAV);
- } else {
- osd_set_nav_box(0, 0, 0, 0);
- vo_osd_changed(OSDTYPE_DVDNAV);
- vo_osd_changed(OSDTYPE_SPU);
- }
-
- if (mp_dvdnav_stream_has_changed(mpctx->stream)) {
- double ar = -1.0;
- if (mpctx->sh_video &&
- stream_control (mpctx->demuxer->stream,
- STREAM_CTRL_GET_ASPECT_RATIO, &ar)
- != STREAM_UNSUPPORTED)
- mpctx->sh_video->stream_aspect = ar;
- }
- }
-#endif
-
-//================= Keyboard events, SEEKing ====================
-
- current_module="key_events";
-
-{
- while (1) {
- mp_cmd_t* cmd;
- while ((cmd = mp_input_get_cmd(mpctx->input, 0, 0)) != NULL) {
- run_command(mpctx, cmd);
- mp_cmd_free(cmd);
- if (mpctx->stop_play)
- break;
- if (mpctx->rel_seek_secs || mpctx->abs_seek_pos) {
- cmd = mp_input_get_cmd(mpctx->input, 0, 1);
- /* Allow seek commands to be combined, but execute the real seek
- * before processing other commands */
- if (!cmd || cmd->id != MP_CMD_SEEK)
- break;
- }
- }
- if (!mpctx->paused || mpctx->stop_play || mpctx->rel_seek_secs
- || mpctx->abs_seek_pos)
- break;
- if (mpctx->sh_video) {
- update_osd_msg(mpctx);
- int hack = vo_osd_changed(0);
- vo_osd_changed(hack);
- if (hack) {
- if (redraw_osd(mpctx->sh_video, mpctx->osd) < 0) {
- add_step_frame(mpctx);
- break;
- }
- else
- vo_osd_changed(0);
- }
- }
- pause_loop(mpctx);
- }
-}
-
-// handle -sstep
-if (step_sec > 0 && !mpctx->paused) {
- mpctx->osd_function=OSD_FFW;
- mpctx->rel_seek_secs+=step_sec;
-}
-
- edl_update(mpctx);
-
- /* Looping. */
- if(mpctx->stop_play==AT_END_OF_FILE && opts->loop_times>=0) {
- mp_msg(MSGT_CPLAYER,MSGL_V,"loop_times = %d\n", opts->loop_times);
-
- if(opts->loop_times>1) opts->loop_times--; else
- if(opts->loop_times==1) opts->loop_times=-1;
- play_n_frames=play_n_frames_mf;
- mpctx->stop_play=0;
- mpctx->abs_seek_pos=SEEK_ABSOLUTE; mpctx->rel_seek_secs=seek_to_sec;
- }
-
-if(mpctx->rel_seek_secs || mpctx->abs_seek_pos){
- seek(mpctx, mpctx->rel_seek_secs, mpctx->abs_seek_pos);
-
- mpctx->rel_seek_secs=0;
- mpctx->abs_seek_pos=0;
-}
-
-} // while(!mpctx->stop_play)
+ while (!mpctx->stop_play)
+ run_playloop(mpctx);
mp_msg(MSGT_GLOBAL,MSGL_V,"EOF code: %d \n",mpctx->stop_play);