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

Attachment: signature.asc
Description: OpenPGP digital signature

_______________________________________________
libav-devel mailing list
libav-devel@libav.org
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to