mirror of
https://github.com/xenia-project/FFmpeg.git
synced 2024-11-24 12:09:55 +00:00
ffplay: if audio or video clock is invalid return NAN
This helps us not to make bad decision (frame dropping, audio compensation) right after seeking when we do not know yet the recent audio or video clock. Signed-off-by: Marton Balint <cus@passwd.hu>
This commit is contained in:
parent
38f649662c
commit
26c208cf0f
20
ffplay.c
20
ffplay.c
@ -176,6 +176,7 @@ typedef struct VideoState {
|
||||
double external_clock_speed; ///< speed of the external clock
|
||||
|
||||
double audio_clock;
|
||||
int audio_clock_serial;
|
||||
double audio_diff_cum; /* used for AV difference average computation */
|
||||
double audio_diff_avg_coef;
|
||||
double audio_diff_threshold;
|
||||
@ -238,6 +239,7 @@ typedef struct VideoState {
|
||||
double video_current_pts_drift; // video_current_pts - time (av_gettime) at which we updated video_current_pts - used to have running video pts
|
||||
int64_t video_current_pos; // current displayed file pos
|
||||
double max_frame_duration; // maximum duration of a frame - above this, we consider the jump a timestamp discontinuity
|
||||
int video_clock_serial;
|
||||
VideoPicture pictq[VIDEO_PICTURE_QUEUE_SIZE];
|
||||
int pictq_size, pictq_rindex, pictq_windex;
|
||||
SDL_mutex *pictq_mutex;
|
||||
@ -1079,6 +1081,8 @@ static void video_display(VideoState *is)
|
||||
/* get the current audio clock value */
|
||||
static double get_audio_clock(VideoState *is)
|
||||
{
|
||||
if (is->audio_clock_serial != is->audioq.serial)
|
||||
return NAN;
|
||||
if (is->paused) {
|
||||
return is->audio_current_pts;
|
||||
} else {
|
||||
@ -1089,6 +1093,8 @@ static double get_audio_clock(VideoState *is)
|
||||
/* get the current video clock value */
|
||||
static double get_video_clock(VideoState *is)
|
||||
{
|
||||
if (is->video_clock_serial != is->videoq.serial)
|
||||
return NAN;
|
||||
if (is->paused) {
|
||||
return is->video_current_pts;
|
||||
} else {
|
||||
@ -1230,7 +1236,7 @@ static double compute_target_delay(double delay, VideoState *is)
|
||||
delay to compute the threshold. I still don't know
|
||||
if it is the best guess */
|
||||
sync_threshold = FFMAX(AV_SYNC_THRESHOLD, delay);
|
||||
if (fabs(diff) < AV_NOSYNC_THRESHOLD) {
|
||||
if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD) {
|
||||
if (diff <= -sync_threshold)
|
||||
delay = 0;
|
||||
else if (diff >= sync_threshold)
|
||||
@ -1281,6 +1287,7 @@ static void update_video_pts(VideoState *is, double pts, int64_t pos, int serial
|
||||
is->video_current_pts_drift = is->video_current_pts - time;
|
||||
is->video_current_pos = pos;
|
||||
is->frame_last_pts = pts;
|
||||
is->video_clock_serial = serial;
|
||||
if (is->videoq.serial == serial)
|
||||
check_external_clock_sync(is, is->video_current_pts);
|
||||
}
|
||||
@ -1677,7 +1684,7 @@ static int get_video_frame(VideoState *is, AVFrame *frame, int64_t *pts, AVPacke
|
||||
double clockdiff = get_video_clock(is) - get_master_clock(is);
|
||||
double dpts = av_q2d(is->video_st->time_base) * *pts;
|
||||
double ptsdiff = dpts - is->frame_last_pts;
|
||||
if (fabs(clockdiff) < AV_NOSYNC_THRESHOLD &&
|
||||
if (!isnan(clockdiff) && fabs(clockdiff) < AV_NOSYNC_THRESHOLD &&
|
||||
ptsdiff > 0 && ptsdiff < AV_NOSYNC_THRESHOLD &&
|
||||
clockdiff + ptsdiff - is->frame_last_filter_delay < 0) {
|
||||
is->frame_last_dropped_pos = pkt->pos;
|
||||
@ -2038,7 +2045,7 @@ static int synchronize_audio(VideoState *is, int nb_samples)
|
||||
|
||||
diff = get_audio_clock(is) - get_master_clock(is);
|
||||
|
||||
if (fabs(diff) < AV_NOSYNC_THRESHOLD) {
|
||||
if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD) {
|
||||
is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;
|
||||
if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {
|
||||
/* not enough measures to have a correct estimate */
|
||||
@ -2224,6 +2231,7 @@ static int audio_decode_frame(VideoState *is)
|
||||
/* if update the audio clock with the pts */
|
||||
if (pkt->pts != AV_NOPTS_VALUE) {
|
||||
is->audio_clock = av_q2d(is->audio_st->time_base)*pkt->pts;
|
||||
is->audio_clock_serial = is->audio_pkt_temp_serial;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2265,7 +2273,7 @@ static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
|
||||
/* Let's assume the audio driver that is used by SDL has two periods. */
|
||||
is->audio_current_pts = is->audio_clock - (double)(2 * is->audio_hw_buf_size + is->audio_write_buf_size) / bytes_per_sec;
|
||||
is->audio_current_pts_drift = is->audio_current_pts - audio_callback_time / 1000000.0;
|
||||
if (is->audioq.serial == is->audio_pkt_temp_serial)
|
||||
if (is->audioq.serial == is->audio_clock_serial)
|
||||
check_external_clock_sync(is, is->audio_current_pts);
|
||||
}
|
||||
|
||||
@ -2851,6 +2859,8 @@ static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
|
||||
update_external_clock_speed(is, 1.0);
|
||||
is->audio_current_pts_drift = -av_gettime() / 1000000.0;
|
||||
is->video_current_pts_drift = is->audio_current_pts_drift;
|
||||
is->audio_clock_serial = -1;
|
||||
is->video_clock_serial = -1;
|
||||
is->av_sync_type = av_sync_type;
|
||||
is->read_tid = SDL_CreateThread(read_thread, is);
|
||||
if (!is->read_tid) {
|
||||
@ -3033,6 +3043,8 @@ static void event_loop(VideoState *cur_stream)
|
||||
stream_seek(cur_stream, pos, incr, 1);
|
||||
} else {
|
||||
pos = get_master_clock(cur_stream);
|
||||
if (isnan(pos))
|
||||
pos = (double)cur_stream->seek_pos / AV_TIME_BASE;
|
||||
pos += incr;
|
||||
if (cur_stream->ic->start_time != AV_NOPTS_VALUE && pos < cur_stream->ic->start_time / (double)AV_TIME_BASE)
|
||||
pos = cur_stream->ic->start_time / (double)AV_TIME_BASE;
|
||||
|
Loading…
Reference in New Issue
Block a user