From b19d493f2b9b59e50547c6ccb0d4d68c29267923 Mon Sep 17 00:00:00 2001
From: Haruhiko Yamagata <h.yamagata@nifty.com>
Date: Tue, 9 Jun 2009 21:16:40 +0000
Subject: [PATCH] Add field prev_interlaced_frame to H264Context to be able to
 flag soft telecine progressive.

Patch by Haruhiko Yamagata, h D yamagata A nifty D com

Originally committed as revision 19141 to svn://svn.ffmpeg.org/ffmpeg/trunk
---
 libavcodec/h264.c | 27 +++++++++++++++++++++------
 libavcodec/h264.h |  8 ++++++++
 2 files changed, 29 insertions(+), 6 deletions(-)

diff --git a/libavcodec/h264.c b/libavcodec/h264.c
index f2e785b9fc5..d269795d45e 100644
--- a/libavcodec/h264.c
+++ b/libavcodec/h264.c
@@ -3153,6 +3153,7 @@ static void flush_dpb(AVCodecContext *avctx){
         h->delayed_pic[i]= NULL;
     }
     h->outputed_poc= INT_MIN;
+    h->prev_interlaced_frame = 1;
     idr(h);
     if(h->s.current_picture_ptr)
         h->s.current_picture_ptr->reference= 0;
@@ -3807,6 +3808,7 @@ static int decode_slice_header(H264Context *h, H264Context *h0){
         if (MPV_common_init(s) < 0)
             return -1;
         s->first_field = 0;
+        h->prev_interlaced_frame = 1;
 
         init_scan_tables(h);
         alloc_tables(h);
@@ -7789,18 +7791,29 @@ static int decode_frame(AVCodecContext *avctx,
             *data_size = 0;
 
         } else {
+            cur->interlaced_frame = 0;
             cur->repeat_pict = 0;
 
             /* Signal interlacing information externally. */
             /* Prioritize picture timing SEI information over used decoding process if it exists. */
-            if (h->sei_ct_type & 3)
-                cur->interlaced_frame = (h->sei_ct_type & (1<<1)) != 0;
-            else
-                cur->interlaced_frame = FIELD_OR_MBAFF_PICTURE;
 
             if(h->sps.pic_struct_present_flag){
                 switch (h->sei_pic_struct)
                 {
+                case SEI_PIC_STRUCT_FRAME:
+                    break;
+                case SEI_PIC_STRUCT_TOP_FIELD:
+                case SEI_PIC_STRUCT_BOTTOM_FIELD:
+                    cur->interlaced_frame = 1;
+                    break;
+                case SEI_PIC_STRUCT_TOP_BOTTOM:
+                case SEI_PIC_STRUCT_BOTTOM_TOP:
+                    if (FIELD_OR_MBAFF_PICTURE)
+                        cur->interlaced_frame = 1;
+                    else
+                        // try to flag soft telecine progressive
+                        cur->interlaced_frame = h->prev_interlaced_frame;
+                    break;
                 case SEI_PIC_STRUCT_TOP_BOTTOM_TOP:
                 case SEI_PIC_STRUCT_BOTTOM_TOP_BOTTOM:
                     // Signal the possibility of telecined film externally (pic_struct 5,6)
@@ -7809,18 +7822,20 @@ static int decode_frame(AVCodecContext *avctx,
                     break;
                 case SEI_PIC_STRUCT_FRAME_DOUBLING:
                     // Force progressive here, as doubling interlaced frame is a bad idea.
-                    cur->interlaced_frame = 0;
                     cur->repeat_pict = 2;
                     break;
                 case SEI_PIC_STRUCT_FRAME_TRIPLING:
-                    cur->interlaced_frame = 0;
                     cur->repeat_pict = 4;
                     break;
                 }
+
+                if ((h->sei_ct_type & 3) && h->sei_pic_struct <= SEI_PIC_STRUCT_BOTTOM_TOP)
+                    cur->interlaced_frame = (h->sei_ct_type & (1<<1)) != 0;
             }else{
                 /* Derive interlacing flag from used decoding process. */
                 cur->interlaced_frame = FIELD_OR_MBAFF_PICTURE;
             }
+            h->prev_interlaced_frame = cur->interlaced_frame;
 
             if (cur->field_poc[0] != cur->field_poc[1]){
                 /* Derive top_field_first from field pocs. */
diff --git a/libavcodec/h264.h b/libavcodec/h264.h
index b58d86a67d4..fa348a201fb 100644
--- a/libavcodec/h264.h
+++ b/libavcodec/h264.h
@@ -503,6 +503,14 @@ typedef struct H264Context{
      */
     SEI_PicStructType sei_pic_struct;
 
+    /**
+     * Complement sei_pic_struct
+     * SEI_PIC_STRUCT_TOP_BOTTOM and SEI_PIC_STRUCT_BOTTOM_TOP indicate interlaced frames.
+     * However, soft telecined frames may have these values.
+     * This is used in an attempt to flag soft telecine progressive.
+     */
+    int prev_interlaced_frame;
+
     /**
      * Bit set of clock types for fields/frames in picture timing SEI message.
      * For each found ct_type, appropriate bit is set (e.g., bit 1 for
-- 
GitLab