changeset 21077:7f3cccd16b26

Reorganize code to move more things out of main().
author uau
date Mon, 20 Nov 2006 09:12:07 +0000
parents e11d06eec202
children 31943f2cad55
files libmpdemux/stheader.h mplayer.c
diffstat 2 files changed, 95 insertions(+), 88 deletions(-) [+]
line wrap: on
line diff
--- a/libmpdemux/stheader.h	Mon Nov 20 01:31:15 2006 +0000
+++ b/libmpdemux/stheader.h	Mon Nov 20 09:12:07 2006 +0000
@@ -66,6 +66,8 @@
   // timing (mostly for mpeg):
   double pts;     // predicted/interpolated PTS of the current frame
   double i_pts;   // PTS for the _next_ I/P frame
+  float next_frame_time;
+  double last_pts;
   double buffered_pts[20];
   int num_buffered_pts;
   // output format: (set by demuxer)
--- a/mplayer.c	Mon Nov 20 01:31:15 2006 +0000
+++ b/mplayer.c	Mon Nov 20 09:12:07 2006 +0000
@@ -3331,6 +3331,10 @@
   if (sh_video->codec)
     mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_VIDEO_CODEC=%s\n", sh_video->codec->name);
 
+  sh_video->last_pts = MP_NOPTS_VALUE;
+  sh_video->num_buffered_pts = 0;
+  sh_video->next_frame_time = 0;
+
   if(auto_quality>0){
     // Auto quality option enabled
     output_quality=get_video_quality_max(sh_video);
@@ -3351,6 +3355,82 @@
   return 0;
 }
 
+static double update_video(int *blit_frame)
+{
+    //--------------------  Decode a frame: -----------------------
+    double frame_time;
+    *blit_frame = 0; // Don't blit if we hit EOF
+    if (!correct_pts) {
+	unsigned char* start=NULL;
+	void *decoded_frame;
+	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);
+	if (in_size < 0)
+	    return -1;
+	if (in_size > max_framesize)
+	    max_framesize = in_size; // stats
+	sh_video->timer += frame_time;
+	if (sh_audio)
+	    sh_audio->delay -= frame_time;
+	// video_read_frame can change fps (e.g. for ASF video)
+	vo_fps = sh_video->fps;
+	// check for frame-drop:
+	current_module = "check_framedrop";
+	if (sh_audio && !d_audio->eof) {
+	    static int dropped_frames;
+	    float delay = playback_speed*audio_out->get_delay();
+	    float d = delay-sh_audio->delay;
+	    // we should avoid dropping too many frames in sequence unless we
+	    // are too late. and we allow 100ms A-V delay here:
+	    if (d < -dropped_frames*frame_time-0.100 &&
+				osd_function != OSD_PAUSE) {
+		drop_frame = frame_dropping;
+		++drop_frame_cnt;
+		++dropped_frames;
+	    } else
+		drop_frame = dropped_frames = 0;
+	    ++total_frame_cnt;
+	}
+	update_subtitles();
+	update_osd_msg();
+	current_module = "decode_video";
+	decoded_frame = decode_video(sh_video, start, in_size, drop_frame,
+				     sh_video->pts);
+	current_module = "filter_video";
+	*blit_frame = (decoded_frame && filter_video(sh_video, decoded_frame,
+						    sh_video->pts));
+    }
+    else {
+	if (!generate_video_frame(sh_video, d_video))
+	    return -1;
+	((vf_instance_t *)sh_video->vfilter)->control(sh_video->vfilter,
+					    VFCTRL_GET_PTS, &sh_video->pts);
+	if (sh_video->pts == MP_NOPTS_VALUE) {
+	    mp_msg(MSGT_CPLAYER, MSGL_ERR, "pts after filters MISSING\n");
+	    sh_video->pts = sh_video->last_pts;
+	}
+	if (sh_video->last_pts == MP_NOPTS_VALUE)
+	    sh_video->last_pts= sh_video->pts;
+	else if (sh_video->last_pts >= sh_video->pts) {
+	    sh_video->last_pts = sh_video->pts;
+	    mp_msg(MSGT_CPLAYER, MSGL_WARN, "pts value <= previous");
+	}
+	frame_time = sh_video->pts - sh_video->last_pts;
+	sh_video->last_pts = sh_video->pts;
+	sh_video->timer += frame_time;
+	if(sh_audio)
+	    sh_audio->delay -= frame_time;
+	*blit_frame = 1;
+    }
+    return frame_time;
+}
+
+
 int main(int argc,char* argv[]){
 
 
@@ -4410,12 +4490,8 @@
 //float v_frame=0;    // Video
 float time_frame=0; // Timer
 //float num_frames=0;      // number of frames played
-double last_pts = MP_NOPTS_VALUE;
 int grab_frames=0;
-int drop_frame=0;     // current dropping status
-int dropped_frames=0; // how many frames dropped since last non-dropped frame
-
-float next_frame_time=0;
+
 int frame_time_remaining=0; // flag
 int blit_frame=0;
 int was_paused=0;
@@ -4531,91 +4607,20 @@
 
 /*========================== PLAY VIDEO ============================*/
 
-  float frame_time=next_frame_time;
-
   vo_pts=sh_video->timer*90000.0;
   vo_fps=sh_video->fps;
 
-  if(!frame_time_remaining){
-    //--------------------  Decode a frame: -----------------------
-    blit_frame = 0; // Don't blit if we hit EOF
-    if (!correct_pts) while(1)
-    {   unsigned char* start=NULL;
-	void *decoded_frame;
-	int in_size;
-	// get it!
-	current_module="video_read_frame";
-        in_size=video_read_frame(sh_video,&next_frame_time,&start,force_fps);
-	if(in_size<0){ eof=1; break; }
-	if(in_size>max_framesize) max_framesize=in_size; // stats
-	sh_video->timer+=frame_time;
-	if(sh_audio) sh_audio->delay-=frame_time;
-	time_frame += frame_time / playback_speed;  // for nosound
-	// video_read_frame can change fps (e.g. for ASF video)
-	vo_fps = sh_video->fps;
-	// check for frame-drop:
-	current_module="check_framedrop";
-	if(sh_audio && !d_audio->eof){
-	    float delay=playback_speed*audio_out->get_delay();
-	    float d=delay-sh_audio->delay;
-	    // we should avoid dropping too many frames in sequence unless we
-	    // are too late. and we allow 100ms A-V delay here:
-	    if(d<-dropped_frames*frame_time-0.100 && osd_function != OSD_PAUSE){
-		drop_frame=frame_dropping;
-		++drop_frame_cnt;
-		++dropped_frames;
-	    } else {
-		drop_frame=dropped_frames=0;
-	    }
-	    ++total_frame_cnt;
-	}
-	// decode:
-//	printf("Decode! %p  %d  \n",start,in_size);
-	update_subtitles();
-	update_osd_msg();
-	current_module = "decode_video";
-	decoded_frame = decode_video(sh_video,start,in_size,drop_frame, sh_video->pts);
-	current_module = "filter video";
-	blit_frame = (decoded_frame && filter_video(sh_video, decoded_frame,
-						    sh_video->pts));
-	break;
-    }
-    else while (1) {
-	if (!generate_video_frame(sh_video, d_video)) {
-	    eof = 1;
-	    break;
-	}
-	((vf_instance_t *)sh_video->vfilter)->control(sh_video->vfilter,
-					      VFCTRL_GET_PTS, &sh_video->pts);
-	if (sh_video->pts == MP_NOPTS_VALUE) {
-	    mp_msg(MSGT_CPLAYER, MSGL_ERR, "pts after filters MISSING\n");
-	    sh_video->pts = last_pts;
-	}
-	if (last_pts == MP_NOPTS_VALUE)
-	    last_pts = sh_video->pts;
-	else if (last_pts >= sh_video->pts) {
-	    last_pts = sh_video->pts;
-	    mp_msg(MSGT_CPLAYER, MSGL_WARN, "pts value <= previous");
-	}
-	frame_time = sh_video->pts - last_pts;
-	last_pts = sh_video->pts;
-	sh_video->timer += frame_time;
-	time_frame += frame_time / playback_speed;  // for nosound
-	if(sh_audio)
-	    sh_audio->delay -= frame_time;
-	blit_frame = 1;
-	break;
-    }
-	
-    //------------------------ frame decoded. --------------------
-
-    mp_dbg(MSGT_AVSYNC,MSGL_DBG2,"*** ftime=%5.3f ***\n",frame_time);
-
-    if(sh_video->vf_inited<0){
-	mp_msg(MSGT_CPLAYER,MSGL_FATAL,MSGTR_NotInitializeVOPorVO);
-	eof=1; goto goto_next_file;
-    }
-
+  if (!frame_time_remaining) {
+      double frame_time = update_video(&blit_frame);
+      mp_dbg(MSGT_AVSYNC,MSGL_DBG2,"*** ftime=%5.3f ***\n",frame_time);
+      if (sh_video->vf_inited < 0) {
+	  mp_msg(MSGT_CPLAYER,MSGL_FATAL, MSGTR_NotInitializeVOPorVO);
+	  eof = 1; goto goto_next_file;
+      }
+      if (frame_time < 0)
+	  eof = 1;
+      else
+	  time_frame += frame_time / playback_speed;  // for nosound
   }
 
 // ==========================================================================
@@ -5541,7 +5546,7 @@
          resync_video_stream(sh_video);
          if(vo_config_count) video_out->control(VOCTRL_RESET,NULL);
 	 sh_video->num_buffered_pts = 0;
-	 last_pts = MP_NOPTS_VALUE;
+	 sh_video->last_pts = MP_NOPTS_VALUE;
       }
       
       if(sh_audio){