---
 libavcodec/h264.c     |   33 +++++++++++++++++++++++++++++++++
 libavcodec/h264.h     |   22 +++++++++++++++++++++-
 libavcodec/h264_sei.c |   36 ++++++++++++++++++++++++++++++++++++
 3 files changed, 90 insertions(+), 1 deletion(-)

diff --git a/libavcodec/h264.c b/libavcodec/h264.c
index c53ea13..ffb4b1d 100644
--- a/libavcodec/h264.c
+++ b/libavcodec/h264.c
@@ -1912,6 +1912,39 @@ static void decode_postinit(H264Context *h, int 
setup_finished)
         }
     }
 
+    if (h->sei_frame_packing_present) {
+        AVFrameSideData *side_data =
+            av_frame_new_side_data(&cur->f,
+                                   AV_FRAME_DATA_STEREO3D,
+                                   sizeof(AVStereo3D));
+
+        AVStereo3D *stereo_info = (AVStereo3D *)side_data->data;
+        switch (h->frame_packing_arrangement_type) {
+            case SEI_FPA_CHECKERBOARD:
+                stereo_info->type = STEREO_CHECKERS; break;
+            case SEI_FPA_LINE_INTERLEAVED:
+                stereo_info->type = STEREO_LINES; break;
+            case SEI_FPA_COLUMN_INTERLEAVED:
+                stereo_info->type = STEREO_COLUMNS; break;
+            case SEI_FPA_SIDE_BY_SIDE:
+                stereo_info->type = STEREO_SIDEBYSIDE; break;
+            case SEI_FPA_TOP_AND_BOTTOM:
+                stereo_info->type = STEREO_TOPBOTTOM; break;
+            case SEI_FPA_FRAME_ALTERNATE:
+                stereo_info->type = STEREO_FRAMESEQUENCE; break;
+        }
+
+        if (h->content_interpretation_type == 1)
+            stereo_info->order = ORDER_LR;
+        else if (h->content_interpretation_type == 2)
+            stereo_info->order = ORDER_RL;
+        else
+            stereo_info->order = ORDER_NA;
+
+        stereo_info->fullsize = (stereo_info->type == STEREO_FRAMESEQUENCE);
+        stereo_info->anaglyph = ANAGLYPH_NONE;
+    }
+
     // FIXME do something with unavailable reference frames
 
     /* Sort B-frames into display order */
diff --git a/libavcodec/h264.h b/libavcodec/h264.h
index 3ef8420..09e230a 100644
--- a/libavcodec/h264.h
+++ b/libavcodec/h264.h
@@ -123,7 +123,8 @@ typedef enum {
     SEI_BUFFERING_PERIOD            = 0,   ///< buffering period (H.264, D.1.1)
     SEI_TYPE_PIC_TIMING             = 1,   ///< picture timing
     SEI_TYPE_USER_DATA_UNREGISTERED = 5,   ///< unregistered user data
-    SEI_TYPE_RECOVERY_POINT         = 6    ///< recovery point (frame # to 
decoder sync)
+    SEI_TYPE_RECOVERY_POINT         = 6,   ///< recovery point (frame # to 
decoder sync)
+    SEI_TYPE_FRAME_PACKING          = 45,  ///< frame packing arrangement
 } SEI_Type;
 
 /**
@@ -142,6 +143,18 @@ typedef enum {
 } SEI_PicStructType;
 
 /**
+ * type in frame packing arrangement SEI message
+ */
+typedef enum {
+    SEI_FPA_CHECKERBOARD             = 0,  ///<  0: quincux
+    SEI_FPA_LINE_INTERLEAVED         = 1,  ///<  1: line interleaving
+    SEI_FPA_COLUMN_INTERLEAVED       = 2,  ///<  2: column interleaving
+    SEI_FPA_SIDE_BY_SIDE             = 3,  ///<  3: side by side
+    SEI_FPA_TOP_AND_BOTTOM           = 4,  ///<  4: top and bottom
+    SEI_FPA_FRAME_ALTERNATE          = 5,  ///<  5: frame alternate
+} SEI_FramePackingType;
+
+/**
  * Sequence parameter set
  */
 typedef struct SPS {
@@ -586,6 +599,13 @@ typedef struct H264Context {
     int prev_interlaced_frame;
 
     /**
+     * frame_packing_arrangment SEI message
+     */
+    int sei_frame_packing_present;
+    SEI_FramePackingType frame_packing_arrangement_type;
+    int content_interpretation_type;
+
+    /**
      * 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
      * interlaced).
diff --git a/libavcodec/h264_sei.c b/libavcodec/h264_sei.c
index df4c49f..8fd4874 100644
--- a/libavcodec/h264_sei.c
+++ b/libavcodec/h264_sei.c
@@ -42,6 +42,7 @@ void ff_h264_reset_sei(H264Context *h) {
     h->sei_dpb_output_delay         =  0;
     h->sei_cpb_removal_delay        = -1;
     h->sei_buffering_period_present =  0;
+    h->sei_frame_packing_present    =  0;
 }
 
 static int decode_picture_timing(H264Context *h){
@@ -156,6 +157,37 @@ static int decode_buffering_period(H264Context *h){
     return 0;
 }
 
+static int decode_frame_packing_arrangement(H264Context *h){
+    int cancel, quincunx;
+    int content = -1;
+    int type = -1;
+
+    get_ue_golomb(&h->gb);              // frame_packing_arrangement_id
+    cancel = get_bits1(&h->gb);         // 
frame_packing_arrangement_cancel_flag
+    if (cancel == 0) {
+        type = get_bits(&h->gb, 7);     // frame_packing_arrangement_type
+        quincunx = get_bits1(&h->gb);   // quincunx_sampling_flag
+        content = get_bits(&h->gb, 6);  // content_interpretation_type
+
+        // the following skips spatial_flipping_flag frame0_flipped_flag
+        // field_views_flag current_frame_is_frame0_flag
+        // frame0_self_contained_flag frame1_self_contained_flag
+        skip_bits(&h->gb, 6);
+
+        if ( quincunx == 0 && type != 5 )
+            skip_bits(&h->gb, 16);      // frame[01]_grid_position_[xy]
+        skip_bits(&h->gb, 8);           // 
frame_packing_arrangement_reserved_byte
+        get_ue_golomb(&h->gb);          // 
frame_packing_arrangement_repetition_period
+    }
+    skip_bits1(&h->gb);                 // 
frame_packing_arrangement_extension_flag
+
+    h->sei_frame_packing_present = (cancel == 0);
+    h->frame_packing_arrangement_type = type;
+    h->content_interpretation_type = content;
+
+    return 0;
+}
+
 int ff_h264_decode_sei(H264Context *h){
     while (get_bits_left(&h->gb) > 16) {
         int size, type;
@@ -187,6 +219,10 @@ int ff_h264_decode_sei(H264Context *h){
             if(decode_buffering_period(h) < 0)
                 return -1;
             break;
+        case SEI_TYPE_FRAME_PACKING:
+            if(decode_frame_packing_arrangement(h) < 0)
+                return -1;
+            break;
         default:
             skip_bits(&h->gb, 8*size);
         }
-- 
1.7.9.5

_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to