static double update_video(int *blit_frame)
{
sh_video_t * const sh_video = mpctx->sh_video;
//-------------------- 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 = NULL;
int drop_frame=0;
int in_size;
int full_frame;
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,
&start, force_fps);
#ifdef CONFIG_DVDNAV
/// wait, still frame or EOF
if (mpctx->stream->type == STREAMTYPE_DVDNAV && in_size < 0) {
if (mp_dvdnav_is_eof(mpctx->stream))
return -1;
if (mpctx->d_video)
mpctx->d_video->eof = 0;
if (mpctx->d_audio)
mpctx->d_audio->eof = 0;
mpctx->stream->eof = 0;
} else
#endif
if (in_size < 0)
return -1;
if (in_size > max_framesize)
max_framesize = in_size; // stats
drop_frame = check_framedrop(frame_time);
current_module = "decode_video";
#ifdef CONFIG_DVDNAV
full_frame = 1;
decoded_frame = mp_dvdnav_restore_smpi(&in_size,&start,decoded_frame);
/// still frame has been reached, no need to decode
if (in_size > 0 && !decoded_frame)
#endif
decoded_frame = decode_video(sh_video, start, in_size, drop_frame,
sh_video->pts, &full_frame);
if (full_frame) {
sh_video->timer += frame_time;
// Time-based PTS recalculation.
// The key to maintaining A-V sync is to not touch PTS until the proper frame is reached
if (sh_video->pts != MP_NOPTS_VALUE) {
if (sh_video->last_pts != MP_NOPTS_VALUE) {
double pts = sh_video->last_pts + frame_time;
double ptsdiff = fabs(pts - sh_video->pts);
// Allow starting PTS recalculation at the appropriate frame only
mpctx->framestep_found |= (ptsdiff <= frame_time * 1.5);
// replace PTS only if we're not too close and not too far
// and a correctly timed frame has been found, otherwise
// keep pts to eliminate rounding errors or catch up with stream
if (ptsdiff > frame_time * 20)
mpctx->framestep_found = 0;
if (ptsdiff * 10 > frame_time && mpctx->framestep_found)
sh_video->pts = pts;
else
mp_dbg(MSGT_AVSYNC,MSGL_DBG2,"Keeping 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
full_frame=1;/*赋值为1跳出do...while循环*/
} while (!full_frame);
current_module = "filter_video";
*blit_frame = (decoded_frame && filter_video(sh_video, decoded_frame,
sh_video->pts));
}
else {
int res = generate_video_frame(sh_video, mpctx->d_video);
if (!res)
return -1;
#if 0 //we need not get pts from vfilter
((vf_instance_t *)sh_video->vfilter)->control(sh_video->vfilter,
VFCTRL_GET_PTS, &sh_video->pts);
#endif
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) {
// make a guess whether this is some kind of discontinuity
// we should jump along with or some wron timestamps we
// should replace instead
if (sh_video->pts < sh_video->last_pts - 20 * sh_video->frametime)
sh_video->last_pts = sh_video->pts;
else
sh_video->pts = sh_video->last_pts + sh_video->frametime;
mp_msg(MSGT_CPLAYER, MSGL_V, "pts value < previous\n");
}
frame_time = sh_video->pts - sh_video->last_pts;
if (!frame_time)
frame_time = sh_video->frametime;
sh_video->last_pts = sh_video->pts;
sh_video->timer += frame_time;
if(mpctx->sh_audio)
mpctx->delay -= frame_time;
*blit_frame = res > 0;
}
frame_time经过打印一直是0,所以要让它跳出do...while循环,需要手动将它赋值为1
return frame_time;
}