On 08/25/2011 07:45 PM, John Stebbins wrote: > As we discussed on IRC this morning, this makes the value of repeat_pict > returned > by the parsers the same as the value returned by the decoders. > > The parser was returning a value for repeat_pict that was the > actual number of repeats + 1. > > Passes fate with the exception of 1 pre-existing failure > (fate-h264-conformance-mr3_tandberg_b).
Heh, fate passed, but some samples I have that use pulldown didn't play smoothly with avplay. One line fix in compute_frame_duration.
From dd49f30e1fdf33c06f530da102a3e968c1a1bb7c Mon Sep 17 00:00:00 2001 From: John Stebbins <jstebbins@Homer.(none)> Date: Thu, 25 Aug 2011 22:26:14 -0700 Subject: [PATCH] make parsers' repeat_pict consistent with decoders The parser was returning a value for repeat_pict that was the actual number of repeats + 1. --- avconv.c | 4 ++-- libavcodec/h264_parser.c | 25 ++++++++++--------------- libavcodec/mpegvideo_parser.c | 9 +++++---- libavcodec/vc1_parser.c | 19 ++++++++----------- libavformat/utils.c | 4 ++-- 5 files changed, 27 insertions(+), 34 deletions(-) diff --git a/avconv.c b/avconv.c index 57721f8..62951fa 100644 --- a/avconv.c +++ b/avconv.c @@ -1589,7 +1589,7 @@ static int output_packet(InputStream *ist, int ist_index, } ist->next_pts = ist->pts = guess_correct_pts(&ist->pts_ctx, picture.pkt_pts, picture.pkt_dts); if (ist->st->codec->time_base.num != 0) { - int ticks= ist->st->parser ? ist->st->parser->repeat_pict+1 : ist->st->codec->ticks_per_frame; + int ticks= ist->st->parser ? ist->st->parser->repeat_pict+ist->st->codec->ticks_per_frame : ist->st->codec->ticks_per_frame; ist->next_pts += ((int64_t)AV_TIME_BASE * ist->st->codec->time_base.num * ticks) / ist->st->codec->time_base.den; @@ -1620,7 +1620,7 @@ static int output_packet(InputStream *ist, int ist_index, break; case AVMEDIA_TYPE_VIDEO: if (ist->st->codec->time_base.num != 0) { - int ticks= ist->st->parser ? ist->st->parser->repeat_pict+1 : ist->st->codec->ticks_per_frame; + int ticks= ist->st->parser ? ist->st->parser->repeat_pict+ist->st->codec->ticks_per_frame : ist->st->codec->ticks_per_frame; ist->next_pts += ((int64_t)AV_TIME_BASE * ist->st->codec->time_base.num * ticks) / ist->st->codec->time_base.den; diff --git a/libavcodec/h264_parser.c b/libavcodec/h264_parser.c index 5610269..050d30f 100644 --- a/libavcodec/h264_parser.c +++ b/libavcodec/h264_parser.c @@ -119,6 +119,7 @@ static inline int parse_nal_units(AVCodecParserContext *s, /* set some sane default values */ s->pict_type = AV_PICTURE_TYPE_I; s->key_frame = 0; + s->repeat_pict = 0; h->s.avctx= avctx; h->sei_recovery_frame_cnt = -1; @@ -202,31 +203,25 @@ static inline int parse_nal_units(AVCodecParserContext *s, if(h->sps.pic_struct_present_flag) { switch (h->sei_pic_struct) { - case SEI_PIC_STRUCT_TOP_FIELD: - case SEI_PIC_STRUCT_BOTTOM_FIELD: - s->repeat_pict = 0; - break; - case SEI_PIC_STRUCT_FRAME: - case SEI_PIC_STRUCT_TOP_BOTTOM: - case SEI_PIC_STRUCT_BOTTOM_TOP: - s->repeat_pict = 1; - break; case SEI_PIC_STRUCT_TOP_BOTTOM_TOP: case SEI_PIC_STRUCT_BOTTOM_TOP_BOTTOM: - s->repeat_pict = 2; + s->repeat_pict = 1; break; case SEI_PIC_STRUCT_FRAME_DOUBLING: - s->repeat_pict = 3; + s->repeat_pict = 2; break; case SEI_PIC_STRUCT_FRAME_TRIPLING: - s->repeat_pict = 5; + s->repeat_pict = 3; break; + case SEI_PIC_STRUCT_TOP_FIELD: + case SEI_PIC_STRUCT_BOTTOM_FIELD: + case SEI_PIC_STRUCT_FRAME: + case SEI_PIC_STRUCT_TOP_BOTTOM: + case SEI_PIC_STRUCT_BOTTOM_TOP: default: - s->repeat_pict = h->s.picture_structure == PICT_FRAME ? 1 : 0; + s->repeat_pict = 0; break; } - } else { - s->repeat_pict = h->s.picture_structure == PICT_FRAME ? 1 : 0; } return 0; /* no need to evaluate the rest */ diff --git a/libavcodec/mpegvideo_parser.c b/libavcodec/mpegvideo_parser.c index 9688e18..c4fc991 100644 --- a/libavcodec/mpegvideo_parser.c +++ b/libavcodec/mpegvideo_parser.c @@ -85,6 +85,7 @@ static void mpegvideo_extract_headers(AVCodecParserContext *s, avcodec_set_dimensions(avctx, pc->width, pc->height); avctx->time_base.den = pc->frame_rate.den * (frame_rate_ext_n + 1) * 2; avctx->time_base.num = pc->frame_rate.num * (frame_rate_ext_d + 1); + avctx->ticks_per_frame = 2; avctx->codec_id = CODEC_ID_MPEG2VIDEO; avctx->sub_id = 2; /* forces MPEG2 */ } @@ -96,15 +97,15 @@ static void mpegvideo_extract_headers(AVCodecParserContext *s, progressive_frame = buf[4] & (1 << 7); /* check if we must repeat the frame */ - s->repeat_pict = 1; + s->repeat_pict = 0; if (repeat_first_field) { if (pc->progressive_sequence) { if (top_field_first) - s->repeat_pict = 5; + s->repeat_pict = 4; else - s->repeat_pict = 3; + s->repeat_pict = 2; } else if (progressive_frame) { - s->repeat_pict = 2; + s->repeat_pict = 1; } } } diff --git a/libavcodec/vc1_parser.c b/libavcodec/vc1_parser.c index c4c15b3..9f1f9b9 100644 --- a/libavcodec/vc1_parser.c +++ b/libavcodec/vc1_parser.c @@ -74,18 +74,15 @@ static void vc1_extract_headers(AVCodecParserContext *s, AVCodecContext *avctx, else s->pict_type = vpc->v.s.pict_type; - if (avctx->ticks_per_frame > 1){ - // process pulldown flags + // process pulldown flags + // Pulldown flags are only valid when 'broadcast' has been set. + // So ticks_per_frame will be 2 + if (vpc->v.rff){ + // repeat field s->repeat_pict = 1; - // Pulldown flags are only valid when 'broadcast' has been set. - // So ticks_per_frame will be 2 - if (vpc->v.rff){ - // repeat field - s->repeat_pict = 2; - }else if (vpc->v.rptfrm){ - // repeat frames - s->repeat_pict = vpc->v.rptfrm * 2 + 1; - } + }else if (vpc->v.rptfrm){ + // repeat frames + s->repeat_pict = vpc->v.rptfrm * 2; } break; diff --git a/libavformat/utils.c b/libavformat/utils.c index 6077be9..e71537a 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -820,10 +820,10 @@ static void compute_frame_duration(int *pnum, int *pden, AVStream *st, *pnum = st->time_base.num; *pden = st->time_base.den; }else if(st->codec->time_base.num*1000LL > st->codec->time_base.den){ - *pnum = st->codec->time_base.num; + *pnum = st->codec->time_base.num * st->codec->ticks_per_frame; *pden = st->codec->time_base.den; if (pc && pc->repeat_pict) { - *pnum = (*pnum) * (1 + pc->repeat_pict); + *pnum += st->codec->time_base.num * pc->repeat_pict; } //If this codec can be interlaced or progressive then we need a parser to compute duration of a packet //Thus if we have no parser in such case leave duration undefined. -- 1.7.4.1
signature.asc
Description: OpenPGP digital signature
_______________________________________________ libav-devel mailing list libav-devel@libav.org https://lists.libav.org/mailman/listinfo/libav-devel