---
Instead of adding the side_data to the output frame, add it to the decoded 
frame, as the order of the two might be different.
Thanks to Anton for pointing this out on IRC.
Vittorio

 libavcodec/hevc.c      |    4 ++++
 libavcodec/hevc.h      |    8 ++++++++
 libavcodec/hevc_refs.c |   36 ++++++++++++++++++++++++++++++++++++
 libavcodec/hevc_sei.c  |   15 ++++++++++-----
 4 files changed, 58 insertions(+), 5 deletions(-)

diff --git a/libavcodec/hevc.c b/libavcodec/hevc.c
index f00667c..9709476 100644
--- a/libavcodec/hevc.c
+++ b/libavcodec/hevc.c
@@ -2381,6 +2381,10 @@ static int hevc_frame_start(HEVCContext *s)
         goto fail;
     }
 
+    ret = ff_hevc_set_side_data(s);
+    if (ret < 0)
+        goto fail;
+
     av_frame_unref(s->output_frame);
     ret = ff_hevc_output_frame(s, s->output_frame, 0);
     if (ret < 0)
diff --git a/libavcodec/hevc.h b/libavcodec/hevc.h
index ab95035..d71f493 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,
@@ -1018,6 +1024,8 @@ int ff_hevc_frame_nb_refs(HEVCContext *s);
 
 int ff_hevc_set_new_ref(HEVCContext *s, AVFrame **frame, int poc);
 
+int ff_hevc_set_side_data(HEVCContext *s);
+
 /**
  * Find next frame in output order and put a reference to it in frame.
  * @return 1 if a frame was output, 0 otherwise
diff --git a/libavcodec/hevc_refs.c b/libavcodec/hevc_refs.c
index 2fbe9e7..54daf99 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,41 @@ int ff_hevc_set_new_ref(HEVCContext *s, AVFrame **frame, 
int poc)
     return 0;
 }
 
+int ff_hevc_set_side_data(HEVCContext *s)
+{
+    AVFrame *out = s->ref->frame;
+
+    if (s->sei_frame_packing_present &&
+        s->frame_packing_arrangement_type >= 3 &&
+        s->frame_packing_arrangement_type <= 5 &&
+        s->content_interpretation_type > 0 &&
+        s->content_interpretation_type < 3) {
+        AVStereo3D *stereo = av_stereo3d_create_side_data(out);
+        if (!stereo)
+            return AVERROR(ENOMEM);
+
+        switch (s->frame_packing_arrangement_type) {
+        case 3:
+            if (s->quincunx_subsampling)
+                stereo->type = AV_STEREO3D_SIDEBYSIDE_QUINCUNX;
+            else
+                stereo->type = AV_STEREO3D_SIDEBYSIDE;
+            break;
+        case 4:
+            stereo->type = AV_STEREO3D_TOPBOTTOM;
+            break;
+        case 5:
+            stereo->type = AV_STEREO3D_FRAMESEQUENCE;
+            break;
+        }
+
+        if (s->content_interpretation_type == 2)
+            stereo->flags = AV_STEREO3D_FLAG_INVERT;
+    }
+
+    return 0;
+}
+
 int ff_hevc_output_frame(HEVCContext *s, AVFrame *out, int flush)
 {
     do {
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