[MPlayer-cvslog] r32056 - in trunk: libmpcodecs/dec_video.c libmpcodecs/dec_video.h mencoder.c mplayer.c
cehoyos
subversion at mplayerhq.hu
Tue Sep 7 18:20:52 CEST 2010
Author: cehoyos
Date: Tue Sep 7 18:20:52 2010
New Revision: 32056
Log:
Improve A/V sync when not using -correct-pts.
This fixes at least playing PAFF streams with the native ts demuxer.
(Breaks the non-standard -demuxer lavf -nocorrect-pts.)
Patch by Pásztor Szilárd, bartosteka freemail hu
Modified:
trunk/libmpcodecs/dec_video.c
trunk/libmpcodecs/dec_video.h
trunk/mencoder.c
trunk/mplayer.c
Modified: trunk/libmpcodecs/dec_video.c
==============================================================================
--- trunk/libmpcodecs/dec_video.c Tue Sep 7 18:14:56 2010 (r32055)
+++ trunk/libmpcodecs/dec_video.c Tue Sep 7 18:20:52 2010 (r32056)
@@ -388,7 +388,7 @@ 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 *full_frame)
{
mp_image_t *mpi = NULL;
unsigned int t = GetTimer();
@@ -406,6 +406,9 @@ void *decode_video(sh_video_t *sh_video,
mpi = NULL;
}
+ if (full_frame)
+ *full_frame = got_picture;
+
delay = get_current_video_decoder_lag(sh_video);
if (correct_pts && pts != MP_NOPTS_VALUE
&& (got_picture || sh_video->num_buffered_pts < delay)) {
Modified: trunk/libmpcodecs/dec_video.h
==============================================================================
--- trunk/libmpcodecs/dec_video.h Tue Sep 7 18:14:56 2010 (r32055)
+++ trunk/libmpcodecs/dec_video.h Tue Sep 7 18:20:52 2010 (r32056)
@@ -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 *full_frame);
int filter_video(sh_video_t *sh_video, void *frame, double pts);
int get_video_quality_max(sh_video_t *sh_video);
Modified: trunk/mencoder.c
==============================================================================
--- trunk/mencoder.c Tue Sep 7 18:14:56 2010 (r32055)
+++ trunk/mencoder.c Tue Sep 7 18:20:52 2010 (r32056)
@@ -464,7 +464,7 @@ static int slowseek(float end_pts, demux
if (vfilter) {
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, NULL);
if (decoded_frame)
filter_video(sh_video, decoded_frame, MP_NOPTS_VALUE);
}
@@ -1535,7 +1535,7 @@ default:
(!sh_video->vfilter ||
((vf_instance_t *)sh_video->vfilter)->control(sh_video->vfilter, VFCTRL_SKIP_NEXT_FRAME, 0) != CONTROL_TRUE);
void *decoded_frame = decode_video(sh_video,frame_data.start,frame_data.in_size,
- drop_frame, MP_NOPTS_VALUE);
+ drop_frame, MP_NOPTS_VALUE, NULL);
blit_frame = decoded_frame && filter_video(sh_video, decoded_frame, MP_NOPTS_VALUE);}
if (sh_video->vf_initialized < 0) mencoder_exit(1, NULL);
Modified: trunk/mplayer.c
==============================================================================
--- trunk/mplayer.c Tue Sep 7 18:14:56 2010 (r32055)
+++ trunk/mplayer.c Tue Sep 7 18:20:52 2010 (r32056)
@@ -1827,7 +1827,7 @@ 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, NULL);
if (decoded_frame) {
update_subtitles(sh_video, sh_video->pts, mpctx->d_sub, 0);
update_teletext(sh_video, mpctx->demuxer, 0);
@@ -2381,7 +2381,9 @@ static double update_video(int *blit_fra
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,
@@ -2402,27 +2404,56 @@ 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
+ 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);
+ 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
+ } while (!full_frame);
+
current_module = "filter_video";
*blit_frame = (decoded_frame && filter_video(sh_video, decoded_frame,
sh_video->pts));
@@ -2452,28 +2483,6 @@ static double update_video(int *blit_fra
frame_time = sh_video->pts - sh_video->last_pts;
sh_video->last_pts = sh_video->pts;
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;
*blit_frame = res > 0;
@@ -2662,6 +2671,7 @@ static int seek(MPContext *mpctx, double
mpctx->num_buffered_frames = 0;
mpctx->delay = 0;
mpctx->time_frame = 0;
+ mpctx->framestep_found = 0;
// Not all demuxers set d_video->pts during seek, so this value
// (which is used by at least vobsub and edl code below) may
// be completely wrong (probably 0).
@@ -3711,6 +3721,7 @@ if(verbose) term_osd = 0;
int frame_time_remaining=0; // flag
int blit_frame=0;
mpctx->num_buffered_frames=0;
+mpctx->framestep_found=0;
// Make sure old OSD does not stay around,
// e.g. with -fixed-vo and same-resolution files
More information about the MPlayer-cvslog
mailing list