---
 libavcodec/hevc.h      |    6 ++++++
 libavcodec/hevc_refs.c |   53 ++++++++++++++++++++++++++++++++++++++++++++++++
 libavcodec/hevc_sei.c  |   15 +++++++++-----
 3 files changed, 69 insertions(+), 5 deletions(-)

diff --git a/libavcodec/hevc.h b/libavcodec/hevc.h
index ab95035..d19f312 100644
--- a/libavcodec/hevc.h
+++ b/libavcodec/hevc.h
@@ -920,6 +920,12 @@ typedef struct HEVCContext {
 
     int nal_length_size;    ///< Number of bytes used for nal length (1, 2 or 
4)
     int nuh_layer_id;
+
+    /** frame packing arrangement variables */
+    int sei_frame_packing_present;
+    int frame_packing_arrangement_type;
+    int content_interpretation_type;
+    int quincunx_subsampling;
 } HEVCContext;
 
 int ff_hevc_decode_short_term_rps(HEVCContext *s, ShortTermRPS *rps,
diff --git a/libavcodec/hevc_refs.c b/libavcodec/hevc_refs.c
index 2fbe9e7..44c3d08 100644
--- a/libavcodec/hevc_refs.c
+++ b/libavcodec/hevc_refs.c
@@ -22,6 +22,7 @@
  */
 
 #include "libavutil/pixdesc.h"
+#include "libavutil/stereo3d.h"
 
 #include "internal.h"
 #include "thread.h"
@@ -151,6 +152,54 @@ int ff_hevc_set_new_ref(HEVCContext *s, AVFrame **frame, 
int poc)
     return 0;
 }
 
+static int set_side_data(HEVCContext *s, AVFrame *out)
+{
+    if (s->sei_frame_packing_present) {
+        AVFrameSideData *side_data;
+        AVStereo3D *stereo = av_stereo3d_alloc();
+        if (!stereo)
+            return AVERROR(ENOMEM);
+
+        switch (s->frame_packing_arrangement_type) {
+        case 3:
+            stereo->type = AV_STEREO3D_SIDEBYSIDE;
+            break;
+        case 4:
+            stereo->type = AV_STEREO3D_TOPBOTTOM;
+            break;
+        case 5:
+            stereo->type = AV_STEREO3D_FRAMESEQUENCE;
+            break;
+        default:
+            stereo->type = AV_STEREO3D_UNKNOWN;
+            break;
+        }
+
+        /* skip allocation if an unknown type was parsed or
+           if there is no information about views interpretation */
+        if (stereo->type != AV_STEREO3D_UNKNOWN &&
+            s->content_interpretation_type > 0 &&
+            s->content_interpretation_type < 3) {
+            if (s->content_interpretation_type == 2)
+                stereo->info |= AV_STEREO3D_ORDER_INVERT;
+
+            if (s->quincunx_subsampling)
+                stereo->info |= AV_STEREO3D_SAMPLE_QUINCUNX;
+
+            side_data = av_frame_new_side_data(out,
+                                               AV_FRAME_DATA_STEREO3D,
+                                               sizeof(AVStereo3D));
+            if (!side_data)
+                return AVERROR(ENOMEM);
+
+            memcpy(side_data->data, stereo, sizeof(AVStereo3D));
+        }
+        av_stereo3d_free(&stereo);
+    }
+
+    return 0;
+}
+
 int ff_hevc_output_frame(HEVCContext *s, AVFrame *out, int flush)
 {
     do {
@@ -190,6 +239,10 @@ int ff_hevc_output_frame(HEVCContext *s, AVFrame *out, int 
flush)
             if (ret < 0)
                 return ret;
 
+            ret = set_side_data(s, out);
+            if (ret < 0)
+                return ret;
+
             for (i = 0; i < 3; i++) {
                 int hshift = (i > 0) ? desc->log2_chroma_w : 0;
                 int vshift = (i > 0) ? desc->log2_chroma_h : 0;
diff --git a/libavcodec/hevc_sei.c b/libavcodec/hevc_sei.c
index 1cf698b..eed7b33 100644
--- a/libavcodec/hevc_sei.c
+++ b/libavcodec/hevc_sei.c
@@ -46,17 +46,17 @@ static void decode_nal_sei_decoded_picture_hash(HEVCContext 
*s)
     }
 }
 
-static void decode_nal_sei_frame_packing_arrangement(HEVCLocalContext *lc)
+static void decode_nal_sei_frame_packing_arrangement(HEVCContext *s)
 {
-    GetBitContext *gb = &lc->gb;
-    int cancel, type, quincunx;
+    GetBitContext *gb = &s->HEVClc.gb;
+    int cancel, type, quincunx, content;
 
     get_ue_golomb(gb);                  // frame_packing_arrangement_id
     cancel = get_bits1(gb);             // frame_packing_cancel_flag
     if (cancel == 0) {
         type     = get_bits(gb, 7);     // frame_packing_arrangement_type
         quincunx = get_bits1(gb);       // quincunx_sampling_flag
-        skip_bits(gb, 6);               // content_interpretation_type
+        content  = get_bits(gb, 6);     // content_interpretation_type
 
         // the following skips spatial_flipping_flag frame0_flipped_flag
         // field_views_flag current_frame_is_frame0_flag
@@ -69,6 +69,11 @@ static void 
decode_nal_sei_frame_packing_arrangement(HEVCLocalContext *lc)
         skip_bits1(gb);         // frame_packing_arrangement_persistance_flag
     }
     skip_bits1(gb);             // upsampled_aspect_ratio_flag
+
+    s->sei_frame_packing_present      = (cancel == 0);
+    s->frame_packing_arrangement_type = type;
+    s->content_interpretation_type    = content;
+    s->quincunx_subsampling           = quincunx;
 }
 
 static int decode_nal_sei_message(HEVCContext *s)
@@ -93,7 +98,7 @@ static int decode_nal_sei_message(HEVCContext *s)
         if (payload_type == 256)
             decode_nal_sei_decoded_picture_hash(s);
         else if (payload_type == 45)
-            decode_nal_sei_frame_packing_arrangement(&s->HEVClc);
+            decode_nal_sei_frame_packing_arrangement(s);
         else {
             av_log(s->avctx, AV_LOG_DEBUG, "Skipped PREFIX SEI %d\n", 
payload_type);
             skip_bits(gb, 8 * payload_size);
-- 
1.7.9.5

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

Reply via email to