From 63036e3ae9496bcfc852dcc15fcb02f5b7deabba Mon Sep 17 00:00:00 2001
From: Yusuke Nakamura <muken.the.vfrmaniac@gmail.com>
Date: Tue, 9 Apr 2013 16:46:29 +0900
Subject: [PATCH 4/4] h264_parser: Set field_order.

---
 libavcodec/h264.c        |   10 +++++-----
 libavcodec/h264.h        |    2 ++
 libavcodec/h264_parser.c |   45 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 52 insertions(+), 5 deletions(-)

diff --git a/libavcodec/h264.c b/libavcodec/h264.c
index 6721365..bdf0482 100644
--- a/libavcodec/h264.c
+++ b/libavcodec/h264.c
@@ -2585,7 +2585,7 @@ static void implicit_weight_table(H264Context *h, int field)
 /**
  * instantaneous decoder refresh.
  */
-static void idr(H264Context *h)
+void ff_idr(H264Context *h)
 {
     ff_h264_remove_all_refs(h);
     h->prev_frame_num        = 0;
@@ -2602,7 +2602,7 @@ static void flush_change(H264Context *h)
         h->last_pocs[i] = INT_MIN;
     h->outputed_poc = h->next_outputed_poc = INT_MIN;
     h->prev_interlaced_frame = 1;
-    idr(h);
+    ff_idr(h);
     if (h->cur_pic_ptr)
         h->cur_pic_ptr->reference = 0;
     h->first_field = 0;
@@ -2643,7 +2643,7 @@ static void flush_dpb(AVCodecContext *avctx)
     h->parse_context.last_index        = 0;
 }
 
-static int init_poc(H264Context *h)
+int ff_init_poc(H264Context *h)
 {
     const int max_frame_num = 1 << h->sps.log2_max_frame_num;
     int field_poc[2];
@@ -3487,7 +3487,7 @@ static int decode_slice_header(H264Context *h, H264Context *h0)
             h->delta_poc[1] = get_se_golomb(&h->gb);
     }
 
-    init_poc(h);
+    ff_init_poc(h);
 
     if (h->pps.redundant_pic_cnt_present)
         h->redundant_pic_count = get_ue_golomb(&h->gb);
@@ -4444,7 +4444,7 @@ again:
                     buf_index = -1;
                     goto end;
                 }
-                idr(h); // FIXME ensure we don't lose some frames if there is reordering
+                ff_idr(h); // FIXME ensure we don't lose some frames if there is reordering
             case NAL_SLICE:
                 init_get_bits(&hx->gb, ptr, bit_length);
                 hx->intra_gb_ptr        =
diff --git a/libavcodec/h264.h b/libavcodec/h264.h
index f5246fe..0da710f 100644
--- a/libavcodec/h264.h
+++ b/libavcodec/h264.h
@@ -946,5 +946,7 @@ static av_always_inline int get_dct8x8_allowed(H264Context *h)
 }
 
 void ff_h264_draw_horiz_band(H264Context *h, int y, int height);
+void ff_idr(H264Context *h);
+int ff_init_poc(H264Context *h);
 
 #endif /* AVCODEC_H264_H */
diff --git a/libavcodec/h264_parser.c b/libavcodec/h264_parser.c
index 3c98c84..71e698a 100644
--- a/libavcodec/h264_parser.c
+++ b/libavcodec/h264_parser.c
@@ -115,6 +115,7 @@ static inline int parse_nal_units(AVCodecParserContext *s,
     unsigned int slice_type;
     int state = -1;
     const uint8_t *ptr;
+    Picture cur_pic;
 
     /* set some sane default values */
     s->pict_type = AV_PICTURE_TYPE_I;
@@ -161,8 +162,11 @@ static inline int parse_nal_units(AVCodecParserContext *s,
             break;
         case NAL_IDR_SLICE:
             s->key_frame = 1;
+            ff_idr(h);
             /* fall through */
         case NAL_SLICE:
+            h->cur_pic_ptr = &cur_pic;
+
             get_ue_golomb(&h->gb);  // skip first_mb_in_slice
             slice_type = get_ue_golomb_31(&h->gb);
             s->pict_type = golomb_to_pict_type[slice_type % 5];
@@ -200,6 +204,24 @@ static inline int parse_nal_units(AVCodecParserContext *s,
                 }
             }
 
+            if (h->nal_unit_type == NAL_IDR_SLICE)
+                get_ue_golomb(&h->gb); /* idr_pic_id */
+            if (h->sps.poc_type == 0) {
+                h->poc_lsb = get_bits(&h->gb, h->sps.log2_max_poc_lsb);
+
+                if (h->pps.pic_order_present == 1 && h->picture_structure == PICT_FRAME)
+                    h->delta_poc_bottom = get_se_golomb(&h->gb);
+            }
+
+            if (h->sps.poc_type == 1 && !h->sps.delta_pic_order_always_zero_flag) {
+                h->delta_poc[0] = get_se_golomb(&h->gb);
+
+                if (h->pps.pic_order_present == 1 && h->picture_structure == PICT_FRAME)
+                    h->delta_poc[1] = get_se_golomb(&h->gb);
+            }
+
+            ff_init_poc(h);
+
             if(h->sps.pic_struct_present_flag) {
                 switch (h->sei_pic_struct) {
                     case SEI_PIC_STRUCT_TOP_FIELD:
@@ -225,10 +247,33 @@ static inline int parse_nal_units(AVCodecParserContext *s,
                         s->repeat_pict = h->picture_structure == PICT_FRAME ? 1 : 0;
                         break;
                 }
+
+                switch (h->sei_pic_struct) {
+                    case SEI_PIC_STRUCT_TOP_FIELD:
+                    case SEI_PIC_STRUCT_TOP_BOTTOM:
+                    case SEI_PIC_STRUCT_TOP_BOTTOM_TOP:
+                        s->field_order = AV_FIELD_TT;
+                        break;
+                    case SEI_PIC_STRUCT_BOTTOM_FIELD:
+                    case SEI_PIC_STRUCT_BOTTOM_TOP:
+                    case SEI_PIC_STRUCT_BOTTOM_TOP_BOTTOM:
+                        s->field_order = AV_FIELD_BB;
+                        break;
+                    default:
+                        s->field_order = AV_FIELD_PROGRESSIVE;
+                        break;
+                }
             } else {
                 s->repeat_pict = h->picture_structure == PICT_FRAME ? 1 : 0;
+
+                if (h->picture_structure != PICT_FRAME)
+                    s->field_order = h->picture_structure == PICT_TOP_FIELD ? AV_FIELD_TT : AV_FIELD_BB;
+                else
+                    s->field_order = cur_pic.field_poc[0] < cur_pic.field_poc[1] ? AV_FIELD_TT :
+                                     cur_pic.field_poc[0] > cur_pic.field_poc[1] ? AV_FIELD_BB : AV_FIELD_PROGRESSIVE;
             }
 
+            h->cur_pic_ptr = NULL;
             return 0; /* no need to evaluate the rest */
         }
         buf += consumed;
-- 
1.7.7.msysgit.1

