diff mbox series

[FFmpeg-devel,v2,07/18] cbs_h264: Implement fill and extract for frame packing arrangement message

Message ID 20210221195125.1901683-7-sw@jkqxz.net
State New
Headers show
Series [FFmpeg-devel,v2,01/18] cbs_sei: Delete SEI NAL units containing no messages
Related show

Checks

Context Check Description
andriy/x86_make success Make finished
andriy/x86_make_fate success Make fate finished
andriy/PPC64_make success Make finished
andriy/PPC64_make_fate success Make fate finished

Commit Message

Mark Thompson Feb. 21, 2021, 7:51 p.m. UTC
This maps from/to stereo 3D metadata.
---
 libavcodec/cbs_h2645.c | 83 ++++++++++++++++++++++++++++++++++++++++++
 libavcodec/cbs_sei.c   |  2 +
 2 files changed, 85 insertions(+)
diff mbox series

Patch

diff --git a/libavcodec/cbs_h2645.c b/libavcodec/cbs_h2645.c
index c01d243455..8efcd87156 100644
--- a/libavcodec/cbs_h2645.c
+++ b/libavcodec/cbs_h2645.c
@@ -20,6 +20,7 @@ 
 #include "libavutil/avassert.h"
 #include "libavutil/display.h"
 #include "libavutil/mastering_display_metadata.h"
+#include "libavutil/stereo3d.h"
 
 #include "bytestream.h"
 #include "cbs.h"
@@ -1684,6 +1685,87 @@  static const SEIMessageTypeDescriptor cbs_sei_common_types[] = {
     SEI_MESSAGE_TYPE_END,
 };
 
+static struct {
+    enum AVStereo3DType st_type;
+    uint8_t            fpa_type;
+} cbs_sei_fpa_type_map[] = {
+    { AV_STEREO3D_2D,                  6 },
+    { AV_STEREO3D_SIDEBYSIDE,          3 },
+    { AV_STEREO3D_TOPBOTTOM,           4 },
+    { AV_STEREO3D_FRAMESEQUENCE,       5 },
+    { AV_STEREO3D_CHECKERBOARD,        0 },
+    { AV_STEREO3D_SIDEBYSIDE_QUINCUNX, 3 },
+    { AV_STEREO3D_LINES,               2 },
+    { AV_STEREO3D_COLUMNS,             1 },
+};
+
+static void cbs_h264_fill_sei_frame_packing_arrangement
+    (H264RawSEIFramePackingArrangement *fpa, const AVStereo3D *st)
+{
+    memset(fpa, 0, sizeof(*fpa));
+
+    for (int i = 0; i < FF_ARRAY_ELEMS(cbs_sei_fpa_type_map); i++) {
+        if (cbs_sei_fpa_type_map[i].st_type == st->type) {
+            fpa->frame_packing_arrangement_type =
+                cbs_sei_fpa_type_map[i].fpa_type;
+            break;
+        }
+    }
+
+    fpa->quincunx_sampling_flag =
+        st->type == AV_STEREO3D_CHECKERBOARD ||
+        st->type == AV_STEREO3D_SIDEBYSIDE_QUINCUNX;
+
+    if (st->type == AV_STEREO3D_2D)
+        fpa->content_interpretation_type = 0;
+    else if (st->flags & AV_STEREO3D_FLAG_INVERT)
+        fpa->content_interpretation_type = 2;
+    else
+        fpa->content_interpretation_type = 1;
+
+    if (st->type == AV_STEREO3D_FRAMESEQUENCE) {
+        if (st->flags & AV_STEREO3D_FLAG_INVERT)
+            fpa->current_frame_is_frame0_flag =
+                st->view == AV_STEREO3D_VIEW_RIGHT;
+        else
+            fpa->current_frame_is_frame0_flag =
+                st->view == AV_STEREO3D_VIEW_LEFT;
+    }
+
+    fpa->frame_packing_arrangement_repetition_period =
+        st->type != AV_STEREO3D_FRAMESEQUENCE;
+}
+
+static void cbs_h264_extract_sei_frame_packing_arrangement
+    (AVStereo3D *st, const H264RawSEIFramePackingArrangement *fpa)
+{
+    memset(st, 0, sizeof(*st));
+
+    if (fpa->frame_packing_arrangement_cancel_flag) {
+        st->type = AV_STEREO3D_2D;
+        return;
+    }
+
+    for (int i = 0; i < FF_ARRAY_ELEMS(cbs_sei_fpa_type_map); i++) {
+        if (cbs_sei_fpa_type_map[i].fpa_type ==
+            fpa->frame_packing_arrangement_type) {
+            st->type = cbs_sei_fpa_type_map[i].st_type;
+            break;
+        }
+    }
+
+    if (st->type == AV_STEREO3D_SIDEBYSIDE &&
+        fpa->quincunx_sampling_flag)
+        st->type = AV_STEREO3D_SIDEBYSIDE_QUINCUNX;
+
+    if (st->type == AV_STEREO3D_2D) {
+        if (fpa->current_frame_is_frame0_flag)
+            st->view = AV_STEREO3D_VIEW_LEFT;
+        else
+            st->view = AV_STEREO3D_VIEW_RIGHT;
+    }
+}
+
 static void cbs_h264_fill_sei_display_orientation
     (H264RawSEIDisplayOrientation *disp, const int32_t matrix[9])
 {
@@ -1791,6 +1873,7 @@  static const SEIMessageTypeDescriptor cbs_sei_h264_types[] = {
         1, 0,
         sizeof(H264RawSEIFramePackingArrangement),
         SEI_MESSAGE_RW(h264, sei_frame_packing_arrangement),
+        SEI_MESSAGE_FE(h264, sei_frame_packing_arrangement),
     },
     {
         SEI_TYPE_DISPLAY_ORIENTATION,
diff --git a/libavcodec/cbs_sei.c b/libavcodec/cbs_sei.c
index 27b5997e47..3fbea264aa 100644
--- a/libavcodec/cbs_sei.c
+++ b/libavcodec/cbs_sei.c
@@ -386,6 +386,8 @@  static const SEIMetadata cbs_sei_metadata[] = {
       SEI_TYPE_CONTENT_LIGHT_LEVEL_INFO },
     { CBS_METADATA_DISPLAY_MATRIX,
       SEI_TYPE_DISPLAY_ORIENTATION },
+    { CBS_METADATA_STEREO3D,
+      SEI_TYPE_FRAME_PACKING_ARRANGEMENT },
 };
 
 static const SEIMessageTypeDescriptor *cbs_sei_find_type_from_metadata