[FFmpeg-devel] [PATCH 1/5] Move timestamp correction code from ffplay to cmdutils
Alexander Strange
astrange
Mon Jul 26 22:16:06 CEST 2010
---
cmdutils.c | 27 +++++++++++++++++++++++++++
cmdutils.h | 24 ++++++++++++++++++++++++
ffplay.c | 31 ++++++-------------------------
3 files changed, 57 insertions(+), 25 deletions(-)
diff --git a/cmdutils.c b/cmdutils.c
index 978b73c..cd0b194 100644
--- a/cmdutils.c
+++ b/cmdutils.c
@@ -663,3 +663,30 @@ int read_file(const char *filename, char **bufptr, size_t *size)
fclose(f);
return 0;
}
+
+void init_pts_correction(PtsCorrectionContext *ctx)
+{
+ ctx->num_faulty_pts = ctx->num_faulty_dts = 0;
+ ctx->last_pts = ctx->last_dts = AV_NOPTS_VALUE;
+}
+
+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;
+}
diff --git a/cmdutils.h b/cmdutils.h
index d48abab..f2ad34a 100644
--- a/cmdutils.h
+++ b/cmdutils.h
@@ -220,4 +220,28 @@ int read_yesno(void);
*/
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.
+ *
+ * @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 Whichever of pts or dts is more correct; will not be less than
+ * or equal to the previous value. May be AV_NOPTS_VALUE.
+ */
+int64_t guess_correct_pts(PtsCorrectionContext *ctx, int64_t pts, int64_t dts);
+
#endif /* FFMPEG_CMDUTILS_H */
diff --git a/ffplay.c b/ffplay.c
index 4f254df..e352392 100644
--- a/ffplay.c
+++ b/ffplay.c
@@ -203,10 +203,7 @@ typedef struct VideoState {
char filename[1024];
int width, height, xleft, ytop;
- int64_t faulty_pts;
- int64_t faulty_dts;
- int64_t last_dts_for_fault_detection;
- int64_t last_pts_for_fault_detection;
+ PtsCorrectionContext pts_ctx;
#if CONFIG_AVFILTER
AVFilterContext *out_video_filter; ///<the last filter in the video chain
@@ -1282,7 +1279,7 @@ retry:
if (is->audio_st && is->video_st)
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",
- 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);
last_time = cur_time;
}
@@ -1498,8 +1495,7 @@ static int get_video_frame(VideoState *is, AVFrame *frame, int64_t *pts, AVPacke
is->video_current_pos= -1;
SDL_UnlockMutex(is->pictq_mutex);
- is->last_dts_for_fault_detection=
- is->last_pts_for_fault_detection= INT64_MIN;
+ init_pts_correction(&is->pts_ctx);
is->frame_last_pts= AV_NOPTS_VALUE;
is->frame_last_delay = 0;
is->frame_timer = (double)av_gettime() / 1000000.0;
@@ -1516,26 +1512,11 @@ static int get_video_frame(VideoState *is, AVFrame *frame, int64_t *pts, AVPacke
pkt);
if (got_picture) {
- if(pkt->dts != AV_NOPTS_VALUE){
- is->faulty_dts += pkt->dts <= is->last_dts_for_fault_detection;
- is->last_dts_for_fault_detection= pkt->dts;
- }
- if(frame->reordered_opaque != AV_NOPTS_VALUE){
- is->faulty_pts += frame->reordered_opaque <= is->last_pts_for_fault_detection;
- is->last_pts_for_fault_detection= frame->reordered_opaque;
- }
+ *pts = guess_correct_pts(&is->pts_ctx, frame->reordered_opaque, pkt->dts);
+ if (*pts == AV_NOPTS_VALUE)
+ *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)
// break;
if (got_picture){
--
1.7.1.1
More information about the ffmpeg-devel
mailing list