diff options
author | Nicolas George <nicolas.george@normalesup.org> | 2011-01-30 20:18:31 +0100 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2011-02-07 19:32:07 +0100 |
commit | 76ad67cae751658ce2d84e83b38a4d673e9e85a3 (patch) | |
tree | fd7a80906aa640e700f427539a9c87dd2d27b5c0 /libavcodec/utils.c | |
parent | 52b2e95cd9f829b83b879a0694173d4ef1558c46 (diff) | |
download | ffmpeg-76ad67cae751658ce2d84e83b38a4d673e9e85a3.tar.gz |
Implement guessed_pts in avcodec_decode_video2
Signed-off-by: Nicolas George <nicolas.george@normalesup.org>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavcodec/utils.c')
-rw-r--r-- | libavcodec/utils.c | 43 |
1 files changed, 42 insertions, 1 deletions
diff --git a/libavcodec/utils.c b/libavcodec/utils.c index e9db33e9d7..2a95975273 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -448,7 +448,7 @@ enum PixelFormat avcodec_default_get_format(struct AVCodecContext *s, const enum void avcodec_get_frame_defaults(AVFrame *pic){ memset(pic, 0, sizeof(AVFrame)); - pic->pts= AV_NOPTS_VALUE; + pic->pts = pic->best_effort_timestamp = AV_NOPTS_VALUE; pic->key_frame= 1; } @@ -538,6 +538,11 @@ int attribute_align_arg avcodec_open(AVCodecContext *avctx, AVCodec *codec) goto free_and_end; } + avctx->pts_correction_num_faulty_pts = + avctx->pts_correction_num_faulty_dts = 0; + avctx->pts_correction_last_pts = + avctx->pts_correction_last_dts = INT64_MIN; + if(avctx->codec->init){ ret = avctx->codec->init(avctx); if (ret < 0) { @@ -608,6 +613,39 @@ int avcodec_encode_subtitle(AVCodecContext *avctx, uint8_t *buf, int buf_size, return ret; } +/** + * Attempt 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 + * AVFrame.pkt_pts + * @param dts the dts field of the decoded AVPacket + * @return one of the input values, may be AV_NOPTS_VALUE + */ +static int64_t guess_correct_pts(AVCodecContext *ctx, + int64_t reordered_pts, int64_t dts) +{ + int64_t pts = AV_NOPTS_VALUE; + + if (dts != AV_NOPTS_VALUE) { + ctx->pts_correction_num_faulty_dts += dts <= ctx->pts_correction_last_dts; + ctx->pts_correction_last_dts = dts; + } + if (reordered_pts != AV_NOPTS_VALUE) { + ctx->pts_correction_num_faulty_pts += reordered_pts <= ctx->pts_correction_last_pts; + ctx->pts_correction_last_pts = reordered_pts; + } + if ((ctx->pts_correction_num_faulty_pts<=ctx->pts_correction_num_faulty_dts || dts == AV_NOPTS_VALUE) + && reordered_pts != AV_NOPTS_VALUE) + pts = reordered_pts; + else + pts = dts; + + return pts; +} + + #if FF_API_VIDEO_OLD int attribute_align_arg avcodec_decode_video(AVCodecContext *avctx, AVFrame *picture, int *got_picture_ptr, @@ -643,6 +681,9 @@ int attribute_align_arg avcodec_decode_video2(AVCodecContext *avctx, AVFrame *pi emms_c(); //needed to avoid an emms_c() call before every return; picture->pkt_dts= avpkt->dts; + picture->best_effort_timestamp = guess_correct_pts(avctx, + picture->pkt_pts, + picture->pkt_dts); if (*got_picture_ptr) avctx->frame_number++; |