changeset 20902:bfb6eacd9c4a

Update OSD contents only after the correct values for the frame are known. The most visible inaccuracy caused by the previous update location was that the OSD always showed position 0 after seeking with demux_mkv. Split frame decoding and filtering because with -correct-pts the pts value that should be displayed for the frame is only known after decoding but is needed before filtering (during which the OSD is drawn).
author uau
date Tue, 14 Nov 2006 12:29:20 +0000
parents b875b84a511e
children b8d8e7ca7410
files libmpcodecs/dec_video.c libmpcodecs/dec_video.h mencoder.c mplayer.c
diffstat 4 files changed, 32 insertions(+), 19 deletions(-) [+]
line wrap: on
line diff
--- a/libmpcodecs/dec_video.c	Tue Nov 14 11:14:03 2006 +0000
+++ b/libmpcodecs/dec_video.c	Tue Nov 14 12:29:20 2006 +0000
@@ -315,13 +315,11 @@
 
 extern int vo_directrendering;
 
-int decode_video(sh_video_t *sh_video,unsigned char *start,int in_size,int drop_frame, double pts){
-vf_instance_t* vf;
+void *decode_video(sh_video_t *sh_video,unsigned char *start,int in_size,int drop_frame, double pts){
 mp_image_t *mpi=NULL;
 unsigned int t=GetTimer();
 unsigned int t2;
 double tt;
-int ret;
 
  if (correct_pts) {
      int delay = get_current_video_decoder_lag(sh_video);
@@ -373,16 +371,21 @@
 tt = t*0.000001f;
 video_time_usage+=tt;
 
-if(!mpi || drop_frame) return 0; // error / skipped frame
+if(!mpi || drop_frame) return NULL; // error / skipped frame
 
  if (correct_pts) {
      sh_video->num_buffered_pts--;
-     pts = sh_video->buffered_pts[sh_video->num_buffered_pts];
+     sh_video->pts = sh_video->buffered_pts[sh_video->num_buffered_pts];
  }
+ return mpi;
+}
 
-//vo_draw_image(video_out,mpi);
-vf=sh_video->vfilter;
-ret = vf->put_image(vf,mpi, pts); // apply video filters and call the leaf vo/ve
+int filter_video(sh_video_t *sh_video, void *frame, double pts) {
+mp_image_t *mpi = frame;
+unsigned int t2 = GetTimer();
+vf_instance_t *vf = sh_video->vfilter;
+// apply video filters and call the leaf vo/ve
+int ret = vf->put_image(vf,mpi, pts);
 if(ret>0) {
     vf->control(vf,VFCTRL_DRAW_OSD,NULL);
 #ifdef USE_ASS
@@ -391,8 +394,7 @@
 }
 
     t2=GetTimer()-t2;
-    tt=t2*0.000001f;
-    vout_time_usage+=tt;
+    vout_time_usage += t2*0.000001;
 
 return ret;
 }
--- a/libmpcodecs/dec_video.h	Tue Nov 14 11:14:03 2006 +0000
+++ b/libmpcodecs/dec_video.h	Tue Nov 14 12:29:20 2006 +0000
@@ -10,7 +10,8 @@
 extern int init_video(sh_video_t *sh_video,char* codecname,char* vfm,int status);
 extern void uninit_video(sh_video_t *sh_video);
 
-extern int decode_video(sh_video_t *sh_video,unsigned char *start,int in_size,int drop_frame, double pts);
+extern void *decode_video(sh_video_t *sh_video,unsigned char *start,int in_size,int drop_frame, double pts);
+extern int filter_video(sh_video_t *sh_video, void *frame, double pts);
 
 extern int get_video_quality_max(sh_video_t *sh_video);
 extern void set_video_quality(sh_video_t *sh_video,int quality);
--- a/mencoder.c	Tue Nov 14 11:14:03 2006 +0000
+++ b/mencoder.c	Tue Nov 14 12:29:20 2006 +0000
@@ -1322,8 +1322,9 @@
     break;
 default:
     // decode_video will callback down to ve_*.c encoders, through the video filters
-    blit_frame=decode_video(sh_video,frame_data.start,frame_data.in_size,
+    {void *decoded_frame = decode_video(sh_video,frame_data.start,frame_data.in_size,
       skip_flag>0 && (!sh_video->vfilter || ((vf_instance_t *)sh_video->vfilter)->control(sh_video->vfilter, VFCTRL_SKIP_NEXT_FRAME, 0) != CONTROL_TRUE), MP_NOPTS_VALUE);
+    blit_frame = decoded_frame && filter_video(sh_video, decoded_frame, MP_NOPTS_VALUE);}
     
     if (sh_video->vf_inited < 0) mencoder_exit(1, NULL);
     
@@ -1696,7 +1697,9 @@
 
         if (vfilter) {
             int softskip = (vfilter->control(vfilter, VFCTRL_SKIP_NEXT_FRAME, 0) == CONTROL_TRUE);
-            decode_video(sh_video, frame_data->start, frame_data->in_size, !softskip, MP_NOPTS_VALUE);
+            void *decoded_frame = decode_video(sh_video, frame_data->start, frame_data->in_size, !softskip, MP_NOPTS_VALUE);
+	    if (decoded_frame)
+		filter_video(sh_video, decoded_frame, MP_NOPTS_VALUE);
         }
 
         if (print_info) mp_msg(MSGT_MENCODER, MSGL_STATUS,
--- a/mplayer.c	Tue Nov 14 11:14:03 2006 +0000
+++ b/mplayer.c	Tue Nov 14 12:29:20 2006 +0000
@@ -2762,7 +2762,7 @@
     while (1) {
 	current_module = "decode video";
 	// XXX Time used in this call is not counted in any performance
-	// timer now
+	// timer now, OSD is not updated correctly for filter-added frames
 	if (vf_output_queued_frame(sh_video->vfilter))
 	    break;
 	current_module = "video_read_frame";
@@ -2777,8 +2777,13 @@
 	    max_framesize = in_size;
 	if (pts == MP_NOPTS_VALUE)
 	    mp_msg(MSGT_CPLAYER, MSGL_ERR, "pts value from demuxer MISSING\n");
-	if (decode_video(sh_video, start, in_size, 0, pts))
-	    break;
+	current_module = "decode video";
+	void *decoded_frame = decode_video(sh_video, start, in_size, 0, pts);
+	if (decoded_frame) {
+	    update_osd_msg();
+	    if (filter_video(sh_video, decoded_frame, sh_video->pts))
+		break;
+	}
 	if (hit_eof)
 	    return 0;
     }
@@ -4324,6 +4329,7 @@
 
   if(end_at.type == END_AT_TIME && end_at.pos < a_pos)
     eof = PT_NEXT_ENTRY;
+  update_osd_msg();
 
 } else {
 
@@ -4370,7 +4376,10 @@
 	// decode:
 	current_module="decode_video";
 //	printf("Decode! %p  %d  \n",start,in_size);
-	blit_frame=decode_video(sh_video,start,in_size,drop_frame, sh_video->pts);
+	update_osd_msg();
+	void *decoded_frame = decode_video(sh_video,start,in_size,drop_frame, sh_video->pts);
+	blit_frame = (decoded_frame && filter_video(sh_video, decoded_frame,
+						    sh_video->pts));
 	break;
     }
     else while (1) {
@@ -5409,8 +5418,6 @@
 
 //================= Update OSD ====================
   
-  update_osd_msg();
-    
 #ifdef USE_SUB
   // find sub
   if(subdata &&  sh_video && sh_video->pts>0){