mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-03-17 20:17:55 +02:00
Extract timestamp correction code from ffplay.c to cmdutils.c
Originally committed as revision 25241 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
parent
6d19fd5c26
commit
7a8bfa5d67
27
cmdutils.c
27
cmdutils.c
@ -677,3 +677,30 @@ int read_file(const char *filename, char **bufptr, size_t *size)
|
|||||||
fclose(f);
|
fclose(f);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void init_pts_correction(PtsCorrectionContext *ctx)
|
||||||
|
{
|
||||||
|
ctx->num_faulty_pts = ctx->num_faulty_dts = 0;
|
||||||
|
ctx->last_pts = ctx->last_dts = INT64_MIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t guess_correct_pts(PtsCorrectionContext *ctx, int64_t reordered_pts, int64_t dts)
|
||||||
|
{
|
||||||
|
int64_t pts = AV_NOPTS_VALUE;
|
||||||
|
|
||||||
|
if (dts != AV_NOPTS_VALUE) {
|
||||||
|
ctx->num_faulty_dts += dts <= ctx->last_dts;
|
||||||
|
ctx->last_dts = dts;
|
||||||
|
}
|
||||||
|
if (reordered_pts != AV_NOPTS_VALUE) {
|
||||||
|
ctx->num_faulty_pts += reordered_pts <= ctx->last_pts;
|
||||||
|
ctx->last_pts = reordered_pts;
|
||||||
|
}
|
||||||
|
if ((ctx->num_faulty_pts<ctx->num_faulty_dts || dts == AV_NOPTS_VALUE)
|
||||||
|
&& reordered_pts != AV_NOPTS_VALUE)
|
||||||
|
pts = reordered_pts;
|
||||||
|
else
|
||||||
|
pts = dts;
|
||||||
|
|
||||||
|
return pts;
|
||||||
|
}
|
||||||
|
24
cmdutils.h
24
cmdutils.h
@ -226,4 +226,28 @@ int read_yesno(void);
|
|||||||
*/
|
*/
|
||||||
int read_file(const char *filename, char **bufptr, size_t *size);
|
int read_file(const char *filename, char **bufptr, size_t *size);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int64_t num_faulty_pts; /// Number of incorrect PTS values so far
|
||||||
|
int64_t num_faulty_dts; /// Number of incorrect DTS values so far
|
||||||
|
int64_t last_pts; /// PTS of the last frame
|
||||||
|
int64_t last_dts; /// DTS of the last frame
|
||||||
|
} PtsCorrectionContext;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resets the state of the PtsCorrectionContext.
|
||||||
|
*/
|
||||||
|
void init_pts_correction(PtsCorrectionContext *ctx);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempts to guess proper monotonic timestamps for decoded video frames
|
||||||
|
* which might have incorrect times. Input timestamps may wrap around, in
|
||||||
|
* which case the output will as well.
|
||||||
|
*
|
||||||
|
* @param pts The pts field of the decoded AVPacket, as passed through
|
||||||
|
* AVCodecContext.reordered_opaque
|
||||||
|
* @param dts The dts field of the decoded AVPacket
|
||||||
|
* @return One of the input values. May be AV_NOPTS_VALUE.
|
||||||
|
*/
|
||||||
|
int64_t guess_correct_pts(PtsCorrectionContext *ctx, int64_t pts, int64_t dts);
|
||||||
|
|
||||||
#endif /* FFMPEG_CMDUTILS_H */
|
#endif /* FFMPEG_CMDUTILS_H */
|
||||||
|
35
ffplay.c
35
ffplay.c
@ -207,10 +207,7 @@ typedef struct VideoState {
|
|||||||
char filename[1024];
|
char filename[1024];
|
||||||
int width, height, xleft, ytop;
|
int width, height, xleft, ytop;
|
||||||
|
|
||||||
int64_t faulty_pts;
|
PtsCorrectionContext pts_ctx;
|
||||||
int64_t faulty_dts;
|
|
||||||
int64_t last_dts_for_fault_detection;
|
|
||||||
int64_t last_pts_for_fault_detection;
|
|
||||||
|
|
||||||
#if CONFIG_AVFILTER
|
#if CONFIG_AVFILTER
|
||||||
AVFilterContext *out_video_filter; ///<the last filter in the video chain
|
AVFilterContext *out_video_filter; ///<the last filter in the video chain
|
||||||
@ -1286,7 +1283,7 @@ retry:
|
|||||||
if (is->audio_st && is->video_st)
|
if (is->audio_st && is->video_st)
|
||||||
av_diff = get_audio_clock(is) - get_video_clock(is);
|
av_diff = get_audio_clock(is) - get_video_clock(is);
|
||||||
printf("%7.2f A-V:%7.3f s:%3.1f aq=%5dKB vq=%5dKB sq=%5dB f=%"PRId64"/%"PRId64" \r",
|
printf("%7.2f A-V:%7.3f s:%3.1f aq=%5dKB vq=%5dKB sq=%5dB f=%"PRId64"/%"PRId64" \r",
|
||||||
get_master_clock(is), av_diff, FFMAX(is->skip_frames-1, 0), aqsize / 1024, vqsize / 1024, sqsize, is->faulty_dts, is->faulty_pts);
|
get_master_clock(is), av_diff, FFMAX(is->skip_frames-1, 0), aqsize / 1024, vqsize / 1024, sqsize, is->pts_ctx.num_faulty_dts, is->pts_ctx.num_faulty_pts);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
last_time = cur_time;
|
last_time = cur_time;
|
||||||
}
|
}
|
||||||
@ -1565,8 +1562,7 @@ static int get_video_frame(VideoState *is, AVFrame *frame, int64_t *pts, AVPacke
|
|||||||
is->video_current_pos= -1;
|
is->video_current_pos= -1;
|
||||||
SDL_UnlockMutex(is->pictq_mutex);
|
SDL_UnlockMutex(is->pictq_mutex);
|
||||||
|
|
||||||
is->last_dts_for_fault_detection=
|
init_pts_correction(&is->pts_ctx);
|
||||||
is->last_pts_for_fault_detection= INT64_MIN;
|
|
||||||
is->frame_last_pts= AV_NOPTS_VALUE;
|
is->frame_last_pts= AV_NOPTS_VALUE;
|
||||||
is->frame_last_delay = 0;
|
is->frame_last_delay = 0;
|
||||||
is->frame_timer = (double)av_gettime() / 1000000.0;
|
is->frame_timer = (double)av_gettime() / 1000000.0;
|
||||||
@ -1583,26 +1579,19 @@ static int get_video_frame(VideoState *is, AVFrame *frame, int64_t *pts, AVPacke
|
|||||||
pkt);
|
pkt);
|
||||||
|
|
||||||
if (got_picture) {
|
if (got_picture) {
|
||||||
if(pkt->dts != AV_NOPTS_VALUE){
|
if (decoder_reorder_pts == -1) {
|
||||||
is->faulty_dts += pkt->dts <= is->last_dts_for_fault_detection;
|
*pts = guess_correct_pts(&is->pts_ctx, frame->reordered_opaque, pkt->dts);
|
||||||
is->last_dts_for_fault_detection= pkt->dts;
|
} else if (decoder_reorder_pts) {
|
||||||
|
*pts = frame->reordered_opaque;
|
||||||
|
} else {
|
||||||
|
*pts = pkt->dts;
|
||||||
}
|
}
|
||||||
if(frame->reordered_opaque != AV_NOPTS_VALUE){
|
|
||||||
is->faulty_pts += frame->reordered_opaque <= is->last_pts_for_fault_detection;
|
if (*pts == AV_NOPTS_VALUE) {
|
||||||
is->last_pts_for_fault_detection= frame->reordered_opaque;
|
*pts = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( ( decoder_reorder_pts==1
|
|
||||||
|| (decoder_reorder_pts && is->faulty_pts<is->faulty_dts)
|
|
||||||
|| pkt->dts == AV_NOPTS_VALUE)
|
|
||||||
&& frame->reordered_opaque != AV_NOPTS_VALUE)
|
|
||||||
*pts= frame->reordered_opaque;
|
|
||||||
else if(pkt->dts != AV_NOPTS_VALUE)
|
|
||||||
*pts= pkt->dts;
|
|
||||||
else
|
|
||||||
*pts= 0;
|
|
||||||
|
|
||||||
// if (len1 < 0)
|
// if (len1 < 0)
|
||||||
// break;
|
// break;
|
||||||
if (got_picture){
|
if (got_picture){
|
||||||
|
Loading…
x
Reference in New Issue
Block a user