[FFmpeg-devel] [PATCH v2 07/18] cbs_h264: Implement fill and extract for frame packing arrangement message
Mark Thompson
sw at jkqxz.net
Sun Feb 21 21:51:14 EET 2021
This maps from/to stereo 3D metadata.
---
libavcodec/cbs_h2645.c | 83 ++++++++++++++++++++++++++++++++++++++++++
libavcodec/cbs_sei.c | 2 +
2 files changed, 85 insertions(+)
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
--
2.30.0
More information about the ffmpeg-devel
mailing list