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 [email protected] https://lists.libav.org/mailman/listinfo/libav-devel
