r25241 - in trunk: cmdutils.c cmdutils.h ffplay.c
Author: astrange Date: Tue Sep 28 04:05:12 2010 New Revision: 25241 Log: Extract timestamp correction code from ffplay.c to cmdutils.c Modified: trunk/cmdutils.c trunk/cmdutils.h trunk/ffplay.c Modified: trunk/cmdutils.c ============================================================================== --- trunk/cmdutils.c Tue Sep 28 02:33:21 2010 (r25240) +++ trunk/cmdutils.c Tue Sep 28 04:05:12 2010 (r25241) @@ -677,3 +677,30 @@ int read_file(const char *filename, char 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 = 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; +} Modified: trunk/cmdutils.h ============================================================================== --- trunk/cmdutils.h Tue Sep 28 02:33:21 2010 (r25240) +++ trunk/cmdutils.h Tue Sep 28 04:05:12 2010 (r25241) @@ -226,4 +226,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. 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 */ Modified: trunk/ffplay.c ============================================================================== --- trunk/ffplay.c Tue Sep 28 02:33:21 2010 (r25240) +++ trunk/ffplay.c Tue Sep 28 04:05:12 2010 (r25241) @@ -207,10 +207,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 @@ -1286,7 +1283,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; } @@ -1565,8 +1562,7 @@ static int get_video_frame(VideoState *i 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; @@ -1583,26 +1579,19 @@ static int get_video_frame(VideoState *i 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 (decoder_reorder_pts == -1) { + *pts = guess_correct_pts(&is->pts_ctx, frame->reordered_opaque, 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; - is->last_pts_for_fault_detection= frame->reordered_opaque; + + 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){
On Tue, Sep 28, 2010 at 04:05:12AM +0200, astrange wrote:
Log: Extract timestamp correction code from ffplay.c to cmdutils.c
--- trunk/cmdutils.h Tue Sep 28 02:33:21 2010 (r25240) +++ trunk/cmdutils.h Tue Sep 28 04:05:12 2010 (r25241) @@ -226,4 +226,28 @@ int read_yesno(void); + +/** + * Resets the state of the PtsCorrectionContext. + */ +void init_pts_correction(PtsCorrectionContext *ctx);
ctx is left undocumented.
+/** + * 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
nit: This could be more readable aligned, i.e. * @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);
ctx is left undocumented. Diego
On Sep 28, 2010, at 3:05 PM, Diego Biurrun wrote:
On Tue, Sep 28, 2010 at 04:05:12AM +0200, astrange wrote:
Log: Extract timestamp correction code from ffplay.c to cmdutils.c
--- trunk/cmdutils.h Tue Sep 28 02:33:21 2010 (r25240) +++ trunk/cmdutils.h Tue Sep 28 04:05:12 2010 (r25241) @@ -226,4 +226,28 @@ int read_yesno(void); + +/** + * Resets the state of the PtsCorrectionContext. + */ +void init_pts_correction(PtsCorrectionContext *ctx);
ctx is left undocumented.
I never liked the idea of "@param ctx the context", it hardly adds anything to the documentation. But I can add it if you want.
[..]
On Tue, Sep 28, 2010 at 03:16:31PM -0400, Alexander Strange wrote:
On Sep 28, 2010, at 3:05 PM, Diego Biurrun wrote:
On Tue, Sep 28, 2010 at 04:05:12AM +0200, astrange wrote:
Log: Extract timestamp correction code from ffplay.c to cmdutils.c
--- trunk/cmdutils.h Tue Sep 28 02:33:21 2010 (r25240) +++ trunk/cmdutils.h Tue Sep 28 04:05:12 2010 (r25241) @@ -226,4 +226,28 @@ int read_yesno(void); + +/** + * Resets the state of the PtsCorrectionContext. + */ +void init_pts_correction(PtsCorrectionContext *ctx);
ctx is left undocumented.
I never liked the idea of "@param ctx the context", it hardly adds anything to the documentation. But I can add it if you want.
It avoids a Doxygen warning. Some day, if our hearts stay pure, we might get the number of Doxygen warnings under control and they might actually become useful. Diego
participants (3)
-
astrange@ithinksw.com -
diego@biurrun.de -
subversion@mplayerhq.hu