# HG changeset patch # User uau # Date 1163507360 0 # Node ID bfb6eacd9c4a4d204d5867155900fe45ec75a518 # Parent b875b84a511ea6396a9ea6e6c78e7108ec3d0758 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). diff -r b875b84a511e -r bfb6eacd9c4a libmpcodecs/dec_video.c --- 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; } diff -r b875b84a511e -r bfb6eacd9c4a libmpcodecs/dec_video.h --- 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); diff -r b875b84a511e -r bfb6eacd9c4a mencoder.c --- 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, diff -r b875b84a511e -r bfb6eacd9c4a mplayer.c --- 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){