diff -NurpabB mplayer-export-2010-08-20/libavcodec/h264.c mplayer-export-2010-08-20-h264-timing/libavcodec/h264.c --- mplayer-export-2010-08-20/libavcodec/h264.c 2010-07-05 16:36:03.000000000 +0200 +++ mplayer-export-2010-08-20-h264-timing/libavcodec/h264.c 2010-08-21 12:31:30.000000000 +0200 @@ -3022,6 +3022,8 @@ static int decode_frame(AVCodecContext * if (cur->field_poc[0]==INT_MAX || cur->field_poc[1]==INT_MAX) { /* Wait for second field. */ *data_size = 0; + ff_print_debug_info(s, pict); + return -2; } else { cur->interlaced_frame = 0; diff -NurpabB mplayer-export-2010-08-20/libmpcodecs/dec_video.c mplayer-export-2010-08-20-h264-timing/libmpcodecs/dec_video.c --- mplayer-export-2010-08-20/libmpcodecs/dec_video.c 2010-06-03 22:59:40.000000000 +0200 +++ mplayer-export-2010-08-20-h264-timing/libmpcodecs/dec_video.c 2010-08-21 12:24:32.000000000 +0200 @@ -386,14 +386,23 @@ int init_best_video_codec(sh_video_t *sh } void *decode_video(sh_video_t *sh_video, unsigned char *start, int in_size, - int drop_frame, double pts) + int drop_frame, double pts, int *real) { mp_image_t *mpi = NULL; unsigned int t = GetTimer(); unsigned int t2; double tt; - if (correct_pts && pts != MP_NOPTS_VALUE) { + *real = 1; + mpi = mpvdec->decode(sh_video, start, in_size, drop_frame); + + //------------------------ frame decoded. -------------------- + + if (mpi && mpi->type == MP_IMGTYPE_NULL) { + *real = 0; + mpi = NULL; + } + else if (correct_pts && pts != MP_NOPTS_VALUE) { if (sh_video->num_buffered_pts == sizeof(sh_video->buffered_pts) / sizeof(double)) mp_msg(MSGT_DECVIDEO, MSGL_ERR, "Too many buffered pts\n"); @@ -409,10 +418,6 @@ void *decode_video(sh_video_t *sh_video, } } - mpi = mpvdec->decode(sh_video, start, in_size, drop_frame); - - //------------------------ frame decoded. -------------------- - #if HAVE_MMX // some codecs are broken, and doesn't restore MMX state :( // it happens usually with broken/damaged files. diff -NurpabB mplayer-export-2010-08-20/libmpcodecs/dec_video.h mplayer-export-2010-08-20-h264-timing/libmpcodecs/dec_video.h --- mplayer-export-2010-08-20/libmpcodecs/dec_video.h 2010-06-18 19:03:13.000000000 +0200 +++ mplayer-export-2010-08-20-h264-timing/libmpcodecs/dec_video.h 2010-08-21 12:24:32.000000000 +0200 @@ -29,7 +29,7 @@ void vfm_help(void); int init_best_video_codec(sh_video_t *sh_video, char** video_codec_list, char** video_fm_list); void uninit_video(sh_video_t *sh_video); -void *decode_video(sh_video_t *sh_video, unsigned char *start, int in_size, int drop_frame, double pts); +void *decode_video(sh_video_t *sh_video, unsigned char *start, int in_size, int drop_frame, double pts, int *real); int filter_video(sh_video_t *sh_video, void *frame, double pts); int get_video_quality_max(sh_video_t *sh_video); diff -NurpabB mplayer-export-2010-08-20/libmpcodecs/mp_image.h mplayer-export-2010-08-20-h264-timing/libmpcodecs/mp_image.h --- mplayer-export-2010-08-20/libmpcodecs/mp_image.h 2010-05-27 12:08:30.000000000 +0200 +++ mplayer-export-2010-08-20-h264-timing/libmpcodecs/mp_image.h 2010-08-21 12:24:32.000000000 +0200 @@ -86,6 +86,8 @@ #define MP_IMGTYPE_IPB 4 // Upper 16 bits give desired buffer number, -1 means get next available #define MP_IMGTYPE_NUMBERED 5 +// Doesn't need any buffer, dummy image +#define MP_IMGTYPE_NULL 6 #define MP_MAX_PLANES 4 diff -NurpabB mplayer-export-2010-08-20/libmpcodecs/vd_ffmpeg.c mplayer-export-2010-08-20-h264-timing/libmpcodecs/vd_ffmpeg.c --- mplayer-export-2010-08-20/libmpcodecs/vd_ffmpeg.c 2010-07-01 22:43:20.000000000 +0200 +++ mplayer-export-2010-08-20-h264-timing/libmpcodecs/vd_ffmpeg.c 2010-08-21 12:32:48.000000000 +0200 @@ -796,6 +796,7 @@ static mp_image_t *decode(sh_video_t *sh AVFrame *pic= ctx->pic; AVCodecContext *avctx = ctx->avctx; mp_image_t *mpi=NULL; + static mp_image_t mympi; int dr1= ctx->do_dr1; AVPacket pkt; @@ -826,7 +827,7 @@ static mp_image_t *decode(sh_video_t *sh ret = avcodec_decode_video2(avctx, pic, &got_picture, &pkt); dr1= ctx->do_dr1; - if(ret<0) mp_msg(MSGT_DECVIDEO, MSGL_WARN, "Error while decoding frame!\n"); + if(ret == -1) mp_msg(MSGT_DECVIDEO, MSGL_WARN, "Error while decoding frame!\n"); //printf("repeat: %d\n", pic->repeat_pict); //-- vstats generation while(lavc_param_vstats){ // always one time loop @@ -901,6 +902,10 @@ static mp_image_t *decode(sh_video_t *sh } //-- + if (ret == -2) { + mympi.type = MP_IMGTYPE_NULL; + return &mympi; // non-displayable first field only + } if(!got_picture) return NULL; // skipped image if(init_vo(sh, avctx->pix_fmt) < 0) return NULL; diff -NurpabB mplayer-export-2010-08-20/mencoder.c mplayer-export-2010-08-20-h264-timing/mencoder.c --- mplayer-export-2010-08-20/mencoder.c 2010-08-16 12:33:33.000000000 +0200 +++ mplayer-export-2010-08-20-h264-timing/mencoder.c 2010-08-21 12:24:32.000000000 +0200 @@ -462,8 +462,9 @@ static int slowseek(float end_pts, demux if (sh_video->pts >= end_pts) done = 1; if (vfilter) { + int real; int softskip = (vfilter->control(vfilter, VFCTRL_SKIP_NEXT_FRAME, 0) == CONTROL_TRUE); - void *decoded_frame = 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, &real); if (decoded_frame) filter_video(sh_video, decoded_frame, MP_NOPTS_VALUE); } @@ -1530,8 +1531,9 @@ case VCODEC_FRAMENO: break; default: // decode_video will callback down to ve_*.c encoders, through the video filters - {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); + {int real; + 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, &real); blit_frame = decoded_frame && filter_video(sh_video, decoded_frame, MP_NOPTS_VALUE);} if (sh_video->vf_initialized < 0) mencoder_exit(1, NULL); diff -NurpabB mplayer-export-2010-08-20/mplayer.c mplayer-export-2010-08-20-h264-timing/mplayer.c --- mplayer-export-2010-08-20/mplayer.c 2010-08-16 12:33:33.000000000 +0200 +++ mplayer-export-2010-08-20-h264-timing/mplayer.c 2010-08-21 12:24:32.000000000 +0200 @@ -1806,10 +1806,12 @@ static int generate_video_frame(sh_video int in_size; int hit_eof=0; double pts; + static int was_frame = 0; while (1) { int drop_frame = check_framedrop(sh_video->frametime); void *decoded_frame; + int real; current_module = "decode video"; // XXX Time used in this call is not counted in any performance // timer now, OSD is not updated correctly for filter-added frames @@ -1826,15 +1828,16 @@ static int generate_video_frame(sh_video if (in_size > max_framesize) max_framesize = in_size; current_module = "decode video"; - decoded_frame = decode_video(sh_video, start, in_size, drop_frame, pts); + decoded_frame = decode_video(sh_video, start, in_size, drop_frame, pts, &real); if (decoded_frame) { + was_frame = 1; update_subtitles(sh_video, sh_video->pts, mpctx->d_sub, 0); update_teletext(sh_video, mpctx->demuxer, 0); update_osd_msg(); current_module = "filter video"; if (filter_video(sh_video, decoded_frame, sh_video->pts)) break; - } else if (drop_frame) + } else if (was_frame && drop_frame) // disable framedropping at the very first frame return -1; if (hit_eof) return 0; @@ -2381,7 +2384,9 @@ static double update_video(int *blit_fra void *decoded_frame = NULL; int drop_frame=0; int in_size; + int real; + do { current_module = "video_read_frame"; frame_time = sh_video->next_frame_time; in_size = video_read_frame(sh_video, &sh_video->next_frame_time, @@ -2402,15 +2407,7 @@ static double update_video(int *blit_fra 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(frame_time); - update_subtitles(sh_video, sh_video->pts, mpctx->d_sub, 0); - update_teletext(sh_video, mpctx->demuxer, 0); - update_osd_msg(); current_module = "decode_video"; #ifdef CONFIG_DVDNAV decoded_frame = mp_dvdnav_restore_smpi(&in_size,&start,decoded_frame); @@ -2418,11 +2415,41 @@ static double update_video(int *blit_fra if (in_size > 0 && !decoded_frame) #endif decoded_frame = decode_video(sh_video, start, in_size, drop_frame, - sh_video->pts); + sh_video->pts, &real); + + if (real) + { + sh_video->timer += frame_time; + if (sh_video->pts != MP_NOPTS_VALUE) + { + if (sh_video->last_pts != MP_NOPTS_VALUE) + { + double pts = sh_video->last_pts + frame_time; + + // replace PTS if we're not too close and not too far, + // to eliminate rounding errors and to catch up with stream + if (fabs(pts - sh_video->pts) < frame_time * 20 && + fabs(pts - sh_video->pts) * 10 > frame_time) + sh_video->pts = pts; + else + mp_dbg(MSGT_AVSYNC,MSGL_DBG2,"Saved PTS at %6.2f\n", sh_video->pts); + } + sh_video->last_pts = sh_video->pts; + } + if (mpctx->sh_audio) + mpctx->delay -= frame_time; + // video_read_frame can change fps (e.g. for ASF video) + vo_fps = sh_video->fps; + update_subtitles(sh_video, sh_video->pts, mpctx->d_sub, 0); + update_teletext(sh_video, mpctx->demuxer, 0); + update_osd_msg(); + } #ifdef CONFIG_DVDNAV /// save back last still frame for future display mp_dvdnav_save_smpi(in_size,start,decoded_frame); #endif + } while (!real); + current_module = "filter_video"; *blit_frame = (decoded_frame && filter_video(sh_video, decoded_frame, sh_video->pts));