From d8d0e2e092f111e5c46282ec9a3d966c4453a9b0 Mon Sep 17 00:00:00 2001
From: Jie Chen <jiechen.cj@alibaba-inc.com>
Date: Fri, 19 Jul 2024 09:57:06 +0800
Subject: [PATCH] JVET-AI0153-OMI-SEI

---
 .../object_mask_infos/intra/mask_info_0.txt   |  53 ++++++
 .../object_mask_infos/intra/mask_info_1.txt   |  33 ++++
 .../object_mask_infos/intra/mask_info_2.txt   |  22 +++
 .../object_mask_infos/intra/mask_info_3.txt   |  30 +++
 .../object_mask_infos/intra/mask_info_4.txt   |  21 +++
 .../lowdelay/mask_info_0.txt                  |  53 ++++++
 .../lowdelay/mask_info_1.txt                  |  33 ++++
 .../lowdelay/mask_info_2.txt                  |  22 +++
 .../lowdelay/mask_info_3.txt                  |  30 +++
 .../lowdelay/mask_info_4.txt                  |  21 +++
 .../randomaccess/mask_info_0.txt              |  53 ++++++
 .../randomaccess/mask_info_1.txt              |  30 +++
 .../randomaccess/mask_info_2.txt              |  22 +++
 .../randomaccess/mask_info_3.txt              |  21 +++
 .../randomaccess/mask_info_4.txt              |  33 ++++
 .../scalability_dimension_info_for_omi.cfg    |   9 +
 source/App/DecoderApp/DecApp.cpp              | 143 ++++++++++++++
 source/App/DecoderApp/DecApp.h                |   7 +
 source/App/DecoderApp/DecAppCfg.cpp           |   6 +
 source/App/DecoderApp/DecAppCfg.h             |   3 +
 source/App/EncoderApp/EncApp.cpp              |   6 +
 source/App/EncoderApp/EncAppCfg.cpp           |  20 ++
 source/App/EncoderApp/EncAppCfg.h             |   6 +
 source/Lib/CommonLib/SEI.h                    |  58 ++++++
 source/Lib/CommonLib/TypeDef.h                |   2 +
 source/Lib/DecoderLib/SEIread.cpp             | 141 ++++++++++++++
 source/Lib/DecoderLib/SEIread.h               |   3 +
 source/Lib/EncoderLib/EncCfg.h                |  14 ++
 source/Lib/EncoderLib/EncGOP.cpp              |  18 ++
 source/Lib/EncoderLib/SEIEncoder.cpp          | 174 ++++++++++++++++++
 source/Lib/EncoderLib/SEIEncoder.h            |   5 +
 source/Lib/EncoderLib/SEIwrite.cpp            | 101 ++++++++++
 source/Lib/EncoderLib/SEIwrite.h              |   3 +
 33 files changed, 1196 insertions(+)
 create mode 100644 cfg/sei_vui/object_mask_infos/intra/mask_info_0.txt
 create mode 100644 cfg/sei_vui/object_mask_infos/intra/mask_info_1.txt
 create mode 100644 cfg/sei_vui/object_mask_infos/intra/mask_info_2.txt
 create mode 100644 cfg/sei_vui/object_mask_infos/intra/mask_info_3.txt
 create mode 100644 cfg/sei_vui/object_mask_infos/intra/mask_info_4.txt
 create mode 100644 cfg/sei_vui/object_mask_infos/lowdelay/mask_info_0.txt
 create mode 100644 cfg/sei_vui/object_mask_infos/lowdelay/mask_info_1.txt
 create mode 100644 cfg/sei_vui/object_mask_infos/lowdelay/mask_info_2.txt
 create mode 100644 cfg/sei_vui/object_mask_infos/lowdelay/mask_info_3.txt
 create mode 100644 cfg/sei_vui/object_mask_infos/lowdelay/mask_info_4.txt
 create mode 100644 cfg/sei_vui/object_mask_infos/randomaccess/mask_info_0.txt
 create mode 100644 cfg/sei_vui/object_mask_infos/randomaccess/mask_info_1.txt
 create mode 100644 cfg/sei_vui/object_mask_infos/randomaccess/mask_info_2.txt
 create mode 100644 cfg/sei_vui/object_mask_infos/randomaccess/mask_info_3.txt
 create mode 100644 cfg/sei_vui/object_mask_infos/randomaccess/mask_info_4.txt
 create mode 100644 cfg/sei_vui/object_mask_infos/scalability_dimension_info_for_omi.cfg

diff --git a/cfg/sei_vui/object_mask_infos/intra/mask_info_0.txt b/cfg/sei_vui/object_mask_infos/intra/mask_info_0.txt
new file mode 100644
index 0000000000..4d9cf4d13e
--- /dev/null
+++ b/cfg/sei_vui/object_mask_infos/intra/mask_info_0.txt
@@ -0,0 +1,53 @@
+SEIOmiCancelFlag: 0
+SEIOmiPersistenceFlag: 1
+SEIOmiNumAuxPicLayerMinus1: 0
+SEIOmiMaskIdLengthMinus1: 3
+SEIOmiMaskSampleValueLengthMinus8: 2
+SEIOmiMaskConfidenceInfoPresentFlag: 1
+SEIOmiMaskConfidenceLengthMinus1: 3
+SEIOmiMaskDepthInfoPresentFlag: 1
+SEIOmiMaskDepthLengthMinus1: 3
+SEIOmiMaskLabelInfoPresentFlag: 1
+SEIOmiMaskLabelLanguagePresentFlag: 1
+#SEIOmiBitEqualToZero: 0
+SEIOmiMaskLabelLanguage: English
+
+SEIOmiMaskPicUpdateFlag[0]: 1
+SEIOmiNumMaskInPicUpdate[0]: 3
+
+SEIOmiMaskId[0][0]: 0
+SEIOmiAuxSampleValue[0][0]: 32
+SEIOmiMaskCancel[0][0]: 0
+SEIOmiBoundingBoxPresentFlag[0][0]: 1
+SEIOmiMaskTop[0][0]: 10
+SEIOmiMaskLeft[0][0]: 10
+SEIOmiMaskWidth[0][0]: 20
+SEIOmiMaskHeight[0][0]: 20
+SEIOmiMaskConfidence[0][0]: 15
+SEIOmiMaskDepth[0][0]: 15
+SEIOmiMaskLabel[0][0]: mask0
+
+SEIOmiMaskId[0][1]: 1
+SEIOmiAuxSampleValue[0][1]: 64
+SEIOmiMaskCancel[0][1]: 0
+SEIOmiBoundingBoxPresentFlag[0][1]: 1
+SEIOmiMaskTop[0][1]: 30
+SEIOmiMaskLeft[0][1]: 30
+SEIOmiMaskWidth[0][1]: 40
+SEIOmiMaskHeight[0][1]: 40
+SEIOmiMaskConfidence[0][1]: 15
+SEIOmiMaskDepth[0][1]: 15
+SEIOmiMaskLabel[0][1]: mask1
+
+SEIOmiMaskId[0][2]: 2
+SEIOmiAuxSampleValue[0][2]: 128
+SEIOmiMaskCancel[0][2]: 0
+SEIOmiBoundingBoxPresentFlag[0][2]: 1
+SEIOmiMaskTop[0][2]: 50
+SEIOmiMaskLeft[0][2]: 50
+SEIOmiMaskWidth[0][2]: 60
+SEIOmiMaskHeight[0][2]: 60
+SEIOmiMaskConfidence[0][2]: 15
+SEIOmiMaskDepth[0][2]: 15
+SEIOmiMaskLabel[0][2]: mask2
+
diff --git a/cfg/sei_vui/object_mask_infos/intra/mask_info_1.txt b/cfg/sei_vui/object_mask_infos/intra/mask_info_1.txt
new file mode 100644
index 0000000000..b991ad0c34
--- /dev/null
+++ b/cfg/sei_vui/object_mask_infos/intra/mask_info_1.txt
@@ -0,0 +1,33 @@
+SEIOmiCancelFlag: 0
+SEIOmiPersistenceFlag: 1
+SEIOmiNumAuxPicLayerMinus1: 0
+SEIOmiMaskIdLengthMinus1: 3
+SEIOmiMaskSampleValueLengthMinus8: 2
+SEIOmiMaskConfidenceInfoPresentFlag: 1
+SEIOmiMaskConfidenceLengthMinus1: 3
+SEIOmiMaskDepthInfoPresentFlag: 1
+SEIOmiMaskDepthLengthMinus1: 3
+SEIOmiMaskLabelInfoPresentFlag: 1
+SEIOmiMaskLabelLanguagePresentFlag: 1
+#SEIOmiBitEqualToZero: 0
+SEIOmiMaskLabelLanguage: English
+
+SEIOmiMaskPicUpdateFlag[0]: 1
+SEIOmiNumMaskInPicUpdate[0]: 2
+
+SEIOmiMaskId[0][0]: 0
+SEIOmiAuxSampleValue[0][0]: 32
+SEIOmiMaskCancel[0][0]: 1
+
+SEIOmiMaskId[0][1]: 3
+SEIOmiAuxSampleValue[0][1]: 192
+SEIOmiMaskCancel[0][1]: 0
+SEIOmiBoundingBoxPresentFlag[0][1]: 1
+SEIOmiMaskTop[0][1]: 150
+SEIOmiMaskLeft[0][1]: 150
+SEIOmiMaskWidth[0][1]: 60
+SEIOmiMaskHeight[0][1]: 60
+SEIOmiMaskConfidence[0][1]: 15
+SEIOmiMaskDepth[0][1]: 15
+SEIOmiMaskLabel[0][1]: mask3
+
diff --git a/cfg/sei_vui/object_mask_infos/intra/mask_info_2.txt b/cfg/sei_vui/object_mask_infos/intra/mask_info_2.txt
new file mode 100644
index 0000000000..a33f9ecc2b
--- /dev/null
+++ b/cfg/sei_vui/object_mask_infos/intra/mask_info_2.txt
@@ -0,0 +1,22 @@
+SEIOmiCancelFlag: 0
+SEIOmiPersistenceFlag: 1
+SEIOmiNumAuxPicLayerMinus1: 0
+SEIOmiMaskIdLengthMinus1: 3
+SEIOmiMaskSampleValueLengthMinus8: 2
+SEIOmiMaskConfidenceInfoPresentFlag: 1
+SEIOmiMaskConfidenceLengthMinus1: 3
+SEIOmiMaskDepthInfoPresentFlag: 1
+SEIOmiMaskDepthLengthMinus1: 3
+SEIOmiMaskLabelInfoPresentFlag: 1
+SEIOmiMaskLabelLanguagePresentFlag: 1
+#SEIOmiBitEqualToZero: 0
+SEIOmiMaskLabelLanguage: English
+
+SEIOmiMaskPicUpdateFlag[0]: 1
+SEIOmiNumMaskInPicUpdate[0]: 1
+
+SEIOmiMaskId[0][0]: 2
+SEIOmiAuxSampleValue[0][0]: 128
+SEIOmiMaskCancel[0][0]: 1
+
+
diff --git a/cfg/sei_vui/object_mask_infos/intra/mask_info_3.txt b/cfg/sei_vui/object_mask_infos/intra/mask_info_3.txt
new file mode 100644
index 0000000000..b84b8b5add
--- /dev/null
+++ b/cfg/sei_vui/object_mask_infos/intra/mask_info_3.txt
@@ -0,0 +1,30 @@
+SEIOmiCancelFlag: 0
+SEIOmiPersistenceFlag: 1
+SEIOmiNumAuxPicLayerMinus1: 0
+SEIOmiMaskIdLengthMinus1: 3
+SEIOmiMaskSampleValueLengthMinus8: 2
+SEIOmiMaskConfidenceInfoPresentFlag: 1
+SEIOmiMaskConfidenceLengthMinus1: 3
+SEIOmiMaskDepthInfoPresentFlag: 1
+SEIOmiMaskDepthLengthMinus1: 3
+SEIOmiMaskLabelInfoPresentFlag: 1
+SEIOmiMaskLabelLanguagePresentFlag: 1
+#SEIOmiBitEqualToZero: 0
+SEIOmiMaskLabelLanguage: English
+
+SEIOmiMaskPicUpdateFlag[0]: 1
+SEIOmiNumMaskInPicUpdate[0]: 1
+
+SEIOmiMaskId[0][0]: 1
+SEIOmiAuxSampleValue[0][0]: 64
+SEIOmiMaskCancel[0][0]: 0
+SEIOmiBoundingBoxPresentFlag[0][0]: 1
+SEIOmiMaskTop[0][0]: 130
+SEIOmiMaskLeft[0][0]: 130
+SEIOmiMaskWidth[0][0]: 40
+SEIOmiMaskHeight[0][0]: 40
+SEIOmiMaskConfidence[0][0]: 15
+SEIOmiMaskDepth[0][0]: 15
+SEIOmiMaskLabel[0][0]: mask1 update
+
+
diff --git a/cfg/sei_vui/object_mask_infos/intra/mask_info_4.txt b/cfg/sei_vui/object_mask_infos/intra/mask_info_4.txt
new file mode 100644
index 0000000000..ac81e5a7f2
--- /dev/null
+++ b/cfg/sei_vui/object_mask_infos/intra/mask_info_4.txt
@@ -0,0 +1,21 @@
+SEIOmiCancelFlag: 0
+SEIOmiPersistenceFlag: 1
+SEIOmiNumAuxPicLayerMinus1: 0
+SEIOmiMaskIdLengthMinus1: 3
+SEIOmiMaskSampleValueLengthMinus8: 2
+SEIOmiMaskConfidenceInfoPresentFlag: 1
+SEIOmiMaskConfidenceLengthMinus1: 3
+SEIOmiMaskDepthInfoPresentFlag: 1
+SEIOmiMaskDepthLengthMinus1: 3
+SEIOmiMaskLabelInfoPresentFlag: 1
+SEIOmiMaskLabelLanguagePresentFlag: 1
+#SEIOmiBitEqualToZero: 0
+SEIOmiMaskLabelLanguage: English
+
+SEIOmiMaskPicUpdateFlag[0]: 1
+SEIOmiNumMaskInPicUpdate[0]: 1
+
+SEIOmiMaskId[0][0]: 3
+SEIOmiAuxSampleValue[0][0]: 192
+SEIOmiMaskCancel[0][0]: 1
+
diff --git a/cfg/sei_vui/object_mask_infos/lowdelay/mask_info_0.txt b/cfg/sei_vui/object_mask_infos/lowdelay/mask_info_0.txt
new file mode 100644
index 0000000000..4d9cf4d13e
--- /dev/null
+++ b/cfg/sei_vui/object_mask_infos/lowdelay/mask_info_0.txt
@@ -0,0 +1,53 @@
+SEIOmiCancelFlag: 0
+SEIOmiPersistenceFlag: 1
+SEIOmiNumAuxPicLayerMinus1: 0
+SEIOmiMaskIdLengthMinus1: 3
+SEIOmiMaskSampleValueLengthMinus8: 2
+SEIOmiMaskConfidenceInfoPresentFlag: 1
+SEIOmiMaskConfidenceLengthMinus1: 3
+SEIOmiMaskDepthInfoPresentFlag: 1
+SEIOmiMaskDepthLengthMinus1: 3
+SEIOmiMaskLabelInfoPresentFlag: 1
+SEIOmiMaskLabelLanguagePresentFlag: 1
+#SEIOmiBitEqualToZero: 0
+SEIOmiMaskLabelLanguage: English
+
+SEIOmiMaskPicUpdateFlag[0]: 1
+SEIOmiNumMaskInPicUpdate[0]: 3
+
+SEIOmiMaskId[0][0]: 0
+SEIOmiAuxSampleValue[0][0]: 32
+SEIOmiMaskCancel[0][0]: 0
+SEIOmiBoundingBoxPresentFlag[0][0]: 1
+SEIOmiMaskTop[0][0]: 10
+SEIOmiMaskLeft[0][0]: 10
+SEIOmiMaskWidth[0][0]: 20
+SEIOmiMaskHeight[0][0]: 20
+SEIOmiMaskConfidence[0][0]: 15
+SEIOmiMaskDepth[0][0]: 15
+SEIOmiMaskLabel[0][0]: mask0
+
+SEIOmiMaskId[0][1]: 1
+SEIOmiAuxSampleValue[0][1]: 64
+SEIOmiMaskCancel[0][1]: 0
+SEIOmiBoundingBoxPresentFlag[0][1]: 1
+SEIOmiMaskTop[0][1]: 30
+SEIOmiMaskLeft[0][1]: 30
+SEIOmiMaskWidth[0][1]: 40
+SEIOmiMaskHeight[0][1]: 40
+SEIOmiMaskConfidence[0][1]: 15
+SEIOmiMaskDepth[0][1]: 15
+SEIOmiMaskLabel[0][1]: mask1
+
+SEIOmiMaskId[0][2]: 2
+SEIOmiAuxSampleValue[0][2]: 128
+SEIOmiMaskCancel[0][2]: 0
+SEIOmiBoundingBoxPresentFlag[0][2]: 1
+SEIOmiMaskTop[0][2]: 50
+SEIOmiMaskLeft[0][2]: 50
+SEIOmiMaskWidth[0][2]: 60
+SEIOmiMaskHeight[0][2]: 60
+SEIOmiMaskConfidence[0][2]: 15
+SEIOmiMaskDepth[0][2]: 15
+SEIOmiMaskLabel[0][2]: mask2
+
diff --git a/cfg/sei_vui/object_mask_infos/lowdelay/mask_info_1.txt b/cfg/sei_vui/object_mask_infos/lowdelay/mask_info_1.txt
new file mode 100644
index 0000000000..b991ad0c34
--- /dev/null
+++ b/cfg/sei_vui/object_mask_infos/lowdelay/mask_info_1.txt
@@ -0,0 +1,33 @@
+SEIOmiCancelFlag: 0
+SEIOmiPersistenceFlag: 1
+SEIOmiNumAuxPicLayerMinus1: 0
+SEIOmiMaskIdLengthMinus1: 3
+SEIOmiMaskSampleValueLengthMinus8: 2
+SEIOmiMaskConfidenceInfoPresentFlag: 1
+SEIOmiMaskConfidenceLengthMinus1: 3
+SEIOmiMaskDepthInfoPresentFlag: 1
+SEIOmiMaskDepthLengthMinus1: 3
+SEIOmiMaskLabelInfoPresentFlag: 1
+SEIOmiMaskLabelLanguagePresentFlag: 1
+#SEIOmiBitEqualToZero: 0
+SEIOmiMaskLabelLanguage: English
+
+SEIOmiMaskPicUpdateFlag[0]: 1
+SEIOmiNumMaskInPicUpdate[0]: 2
+
+SEIOmiMaskId[0][0]: 0
+SEIOmiAuxSampleValue[0][0]: 32
+SEIOmiMaskCancel[0][0]: 1
+
+SEIOmiMaskId[0][1]: 3
+SEIOmiAuxSampleValue[0][1]: 192
+SEIOmiMaskCancel[0][1]: 0
+SEIOmiBoundingBoxPresentFlag[0][1]: 1
+SEIOmiMaskTop[0][1]: 150
+SEIOmiMaskLeft[0][1]: 150
+SEIOmiMaskWidth[0][1]: 60
+SEIOmiMaskHeight[0][1]: 60
+SEIOmiMaskConfidence[0][1]: 15
+SEIOmiMaskDepth[0][1]: 15
+SEIOmiMaskLabel[0][1]: mask3
+
diff --git a/cfg/sei_vui/object_mask_infos/lowdelay/mask_info_2.txt b/cfg/sei_vui/object_mask_infos/lowdelay/mask_info_2.txt
new file mode 100644
index 0000000000..a33f9ecc2b
--- /dev/null
+++ b/cfg/sei_vui/object_mask_infos/lowdelay/mask_info_2.txt
@@ -0,0 +1,22 @@
+SEIOmiCancelFlag: 0
+SEIOmiPersistenceFlag: 1
+SEIOmiNumAuxPicLayerMinus1: 0
+SEIOmiMaskIdLengthMinus1: 3
+SEIOmiMaskSampleValueLengthMinus8: 2
+SEIOmiMaskConfidenceInfoPresentFlag: 1
+SEIOmiMaskConfidenceLengthMinus1: 3
+SEIOmiMaskDepthInfoPresentFlag: 1
+SEIOmiMaskDepthLengthMinus1: 3
+SEIOmiMaskLabelInfoPresentFlag: 1
+SEIOmiMaskLabelLanguagePresentFlag: 1
+#SEIOmiBitEqualToZero: 0
+SEIOmiMaskLabelLanguage: English
+
+SEIOmiMaskPicUpdateFlag[0]: 1
+SEIOmiNumMaskInPicUpdate[0]: 1
+
+SEIOmiMaskId[0][0]: 2
+SEIOmiAuxSampleValue[0][0]: 128
+SEIOmiMaskCancel[0][0]: 1
+
+
diff --git a/cfg/sei_vui/object_mask_infos/lowdelay/mask_info_3.txt b/cfg/sei_vui/object_mask_infos/lowdelay/mask_info_3.txt
new file mode 100644
index 0000000000..b84b8b5add
--- /dev/null
+++ b/cfg/sei_vui/object_mask_infos/lowdelay/mask_info_3.txt
@@ -0,0 +1,30 @@
+SEIOmiCancelFlag: 0
+SEIOmiPersistenceFlag: 1
+SEIOmiNumAuxPicLayerMinus1: 0
+SEIOmiMaskIdLengthMinus1: 3
+SEIOmiMaskSampleValueLengthMinus8: 2
+SEIOmiMaskConfidenceInfoPresentFlag: 1
+SEIOmiMaskConfidenceLengthMinus1: 3
+SEIOmiMaskDepthInfoPresentFlag: 1
+SEIOmiMaskDepthLengthMinus1: 3
+SEIOmiMaskLabelInfoPresentFlag: 1
+SEIOmiMaskLabelLanguagePresentFlag: 1
+#SEIOmiBitEqualToZero: 0
+SEIOmiMaskLabelLanguage: English
+
+SEIOmiMaskPicUpdateFlag[0]: 1
+SEIOmiNumMaskInPicUpdate[0]: 1
+
+SEIOmiMaskId[0][0]: 1
+SEIOmiAuxSampleValue[0][0]: 64
+SEIOmiMaskCancel[0][0]: 0
+SEIOmiBoundingBoxPresentFlag[0][0]: 1
+SEIOmiMaskTop[0][0]: 130
+SEIOmiMaskLeft[0][0]: 130
+SEIOmiMaskWidth[0][0]: 40
+SEIOmiMaskHeight[0][0]: 40
+SEIOmiMaskConfidence[0][0]: 15
+SEIOmiMaskDepth[0][0]: 15
+SEIOmiMaskLabel[0][0]: mask1 update
+
+
diff --git a/cfg/sei_vui/object_mask_infos/lowdelay/mask_info_4.txt b/cfg/sei_vui/object_mask_infos/lowdelay/mask_info_4.txt
new file mode 100644
index 0000000000..ac81e5a7f2
--- /dev/null
+++ b/cfg/sei_vui/object_mask_infos/lowdelay/mask_info_4.txt
@@ -0,0 +1,21 @@
+SEIOmiCancelFlag: 0
+SEIOmiPersistenceFlag: 1
+SEIOmiNumAuxPicLayerMinus1: 0
+SEIOmiMaskIdLengthMinus1: 3
+SEIOmiMaskSampleValueLengthMinus8: 2
+SEIOmiMaskConfidenceInfoPresentFlag: 1
+SEIOmiMaskConfidenceLengthMinus1: 3
+SEIOmiMaskDepthInfoPresentFlag: 1
+SEIOmiMaskDepthLengthMinus1: 3
+SEIOmiMaskLabelInfoPresentFlag: 1
+SEIOmiMaskLabelLanguagePresentFlag: 1
+#SEIOmiBitEqualToZero: 0
+SEIOmiMaskLabelLanguage: English
+
+SEIOmiMaskPicUpdateFlag[0]: 1
+SEIOmiNumMaskInPicUpdate[0]: 1
+
+SEIOmiMaskId[0][0]: 3
+SEIOmiAuxSampleValue[0][0]: 192
+SEIOmiMaskCancel[0][0]: 1
+
diff --git a/cfg/sei_vui/object_mask_infos/randomaccess/mask_info_0.txt b/cfg/sei_vui/object_mask_infos/randomaccess/mask_info_0.txt
new file mode 100644
index 0000000000..4d9cf4d13e
--- /dev/null
+++ b/cfg/sei_vui/object_mask_infos/randomaccess/mask_info_0.txt
@@ -0,0 +1,53 @@
+SEIOmiCancelFlag: 0
+SEIOmiPersistenceFlag: 1
+SEIOmiNumAuxPicLayerMinus1: 0
+SEIOmiMaskIdLengthMinus1: 3
+SEIOmiMaskSampleValueLengthMinus8: 2
+SEIOmiMaskConfidenceInfoPresentFlag: 1
+SEIOmiMaskConfidenceLengthMinus1: 3
+SEIOmiMaskDepthInfoPresentFlag: 1
+SEIOmiMaskDepthLengthMinus1: 3
+SEIOmiMaskLabelInfoPresentFlag: 1
+SEIOmiMaskLabelLanguagePresentFlag: 1
+#SEIOmiBitEqualToZero: 0
+SEIOmiMaskLabelLanguage: English
+
+SEIOmiMaskPicUpdateFlag[0]: 1
+SEIOmiNumMaskInPicUpdate[0]: 3
+
+SEIOmiMaskId[0][0]: 0
+SEIOmiAuxSampleValue[0][0]: 32
+SEIOmiMaskCancel[0][0]: 0
+SEIOmiBoundingBoxPresentFlag[0][0]: 1
+SEIOmiMaskTop[0][0]: 10
+SEIOmiMaskLeft[0][0]: 10
+SEIOmiMaskWidth[0][0]: 20
+SEIOmiMaskHeight[0][0]: 20
+SEIOmiMaskConfidence[0][0]: 15
+SEIOmiMaskDepth[0][0]: 15
+SEIOmiMaskLabel[0][0]: mask0
+
+SEIOmiMaskId[0][1]: 1
+SEIOmiAuxSampleValue[0][1]: 64
+SEIOmiMaskCancel[0][1]: 0
+SEIOmiBoundingBoxPresentFlag[0][1]: 1
+SEIOmiMaskTop[0][1]: 30
+SEIOmiMaskLeft[0][1]: 30
+SEIOmiMaskWidth[0][1]: 40
+SEIOmiMaskHeight[0][1]: 40
+SEIOmiMaskConfidence[0][1]: 15
+SEIOmiMaskDepth[0][1]: 15
+SEIOmiMaskLabel[0][1]: mask1
+
+SEIOmiMaskId[0][2]: 2
+SEIOmiAuxSampleValue[0][2]: 128
+SEIOmiMaskCancel[0][2]: 0
+SEIOmiBoundingBoxPresentFlag[0][2]: 1
+SEIOmiMaskTop[0][2]: 50
+SEIOmiMaskLeft[0][2]: 50
+SEIOmiMaskWidth[0][2]: 60
+SEIOmiMaskHeight[0][2]: 60
+SEIOmiMaskConfidence[0][2]: 15
+SEIOmiMaskDepth[0][2]: 15
+SEIOmiMaskLabel[0][2]: mask2
+
diff --git a/cfg/sei_vui/object_mask_infos/randomaccess/mask_info_1.txt b/cfg/sei_vui/object_mask_infos/randomaccess/mask_info_1.txt
new file mode 100644
index 0000000000..b84b8b5add
--- /dev/null
+++ b/cfg/sei_vui/object_mask_infos/randomaccess/mask_info_1.txt
@@ -0,0 +1,30 @@
+SEIOmiCancelFlag: 0
+SEIOmiPersistenceFlag: 1
+SEIOmiNumAuxPicLayerMinus1: 0
+SEIOmiMaskIdLengthMinus1: 3
+SEIOmiMaskSampleValueLengthMinus8: 2
+SEIOmiMaskConfidenceInfoPresentFlag: 1
+SEIOmiMaskConfidenceLengthMinus1: 3
+SEIOmiMaskDepthInfoPresentFlag: 1
+SEIOmiMaskDepthLengthMinus1: 3
+SEIOmiMaskLabelInfoPresentFlag: 1
+SEIOmiMaskLabelLanguagePresentFlag: 1
+#SEIOmiBitEqualToZero: 0
+SEIOmiMaskLabelLanguage: English
+
+SEIOmiMaskPicUpdateFlag[0]: 1
+SEIOmiNumMaskInPicUpdate[0]: 1
+
+SEIOmiMaskId[0][0]: 1
+SEIOmiAuxSampleValue[0][0]: 64
+SEIOmiMaskCancel[0][0]: 0
+SEIOmiBoundingBoxPresentFlag[0][0]: 1
+SEIOmiMaskTop[0][0]: 130
+SEIOmiMaskLeft[0][0]: 130
+SEIOmiMaskWidth[0][0]: 40
+SEIOmiMaskHeight[0][0]: 40
+SEIOmiMaskConfidence[0][0]: 15
+SEIOmiMaskDepth[0][0]: 15
+SEIOmiMaskLabel[0][0]: mask1 update
+
+
diff --git a/cfg/sei_vui/object_mask_infos/randomaccess/mask_info_2.txt b/cfg/sei_vui/object_mask_infos/randomaccess/mask_info_2.txt
new file mode 100644
index 0000000000..a33f9ecc2b
--- /dev/null
+++ b/cfg/sei_vui/object_mask_infos/randomaccess/mask_info_2.txt
@@ -0,0 +1,22 @@
+SEIOmiCancelFlag: 0
+SEIOmiPersistenceFlag: 1
+SEIOmiNumAuxPicLayerMinus1: 0
+SEIOmiMaskIdLengthMinus1: 3
+SEIOmiMaskSampleValueLengthMinus8: 2
+SEIOmiMaskConfidenceInfoPresentFlag: 1
+SEIOmiMaskConfidenceLengthMinus1: 3
+SEIOmiMaskDepthInfoPresentFlag: 1
+SEIOmiMaskDepthLengthMinus1: 3
+SEIOmiMaskLabelInfoPresentFlag: 1
+SEIOmiMaskLabelLanguagePresentFlag: 1
+#SEIOmiBitEqualToZero: 0
+SEIOmiMaskLabelLanguage: English
+
+SEIOmiMaskPicUpdateFlag[0]: 1
+SEIOmiNumMaskInPicUpdate[0]: 1
+
+SEIOmiMaskId[0][0]: 2
+SEIOmiAuxSampleValue[0][0]: 128
+SEIOmiMaskCancel[0][0]: 1
+
+
diff --git a/cfg/sei_vui/object_mask_infos/randomaccess/mask_info_3.txt b/cfg/sei_vui/object_mask_infos/randomaccess/mask_info_3.txt
new file mode 100644
index 0000000000..ac81e5a7f2
--- /dev/null
+++ b/cfg/sei_vui/object_mask_infos/randomaccess/mask_info_3.txt
@@ -0,0 +1,21 @@
+SEIOmiCancelFlag: 0
+SEIOmiPersistenceFlag: 1
+SEIOmiNumAuxPicLayerMinus1: 0
+SEIOmiMaskIdLengthMinus1: 3
+SEIOmiMaskSampleValueLengthMinus8: 2
+SEIOmiMaskConfidenceInfoPresentFlag: 1
+SEIOmiMaskConfidenceLengthMinus1: 3
+SEIOmiMaskDepthInfoPresentFlag: 1
+SEIOmiMaskDepthLengthMinus1: 3
+SEIOmiMaskLabelInfoPresentFlag: 1
+SEIOmiMaskLabelLanguagePresentFlag: 1
+#SEIOmiBitEqualToZero: 0
+SEIOmiMaskLabelLanguage: English
+
+SEIOmiMaskPicUpdateFlag[0]: 1
+SEIOmiNumMaskInPicUpdate[0]: 1
+
+SEIOmiMaskId[0][0]: 3
+SEIOmiAuxSampleValue[0][0]: 192
+SEIOmiMaskCancel[0][0]: 1
+
diff --git a/cfg/sei_vui/object_mask_infos/randomaccess/mask_info_4.txt b/cfg/sei_vui/object_mask_infos/randomaccess/mask_info_4.txt
new file mode 100644
index 0000000000..b991ad0c34
--- /dev/null
+++ b/cfg/sei_vui/object_mask_infos/randomaccess/mask_info_4.txt
@@ -0,0 +1,33 @@
+SEIOmiCancelFlag: 0
+SEIOmiPersistenceFlag: 1
+SEIOmiNumAuxPicLayerMinus1: 0
+SEIOmiMaskIdLengthMinus1: 3
+SEIOmiMaskSampleValueLengthMinus8: 2
+SEIOmiMaskConfidenceInfoPresentFlag: 1
+SEIOmiMaskConfidenceLengthMinus1: 3
+SEIOmiMaskDepthInfoPresentFlag: 1
+SEIOmiMaskDepthLengthMinus1: 3
+SEIOmiMaskLabelInfoPresentFlag: 1
+SEIOmiMaskLabelLanguagePresentFlag: 1
+#SEIOmiBitEqualToZero: 0
+SEIOmiMaskLabelLanguage: English
+
+SEIOmiMaskPicUpdateFlag[0]: 1
+SEIOmiNumMaskInPicUpdate[0]: 2
+
+SEIOmiMaskId[0][0]: 0
+SEIOmiAuxSampleValue[0][0]: 32
+SEIOmiMaskCancel[0][0]: 1
+
+SEIOmiMaskId[0][1]: 3
+SEIOmiAuxSampleValue[0][1]: 192
+SEIOmiMaskCancel[0][1]: 0
+SEIOmiBoundingBoxPresentFlag[0][1]: 1
+SEIOmiMaskTop[0][1]: 150
+SEIOmiMaskLeft[0][1]: 150
+SEIOmiMaskWidth[0][1]: 60
+SEIOmiMaskHeight[0][1]: 60
+SEIOmiMaskConfidence[0][1]: 15
+SEIOmiMaskDepth[0][1]: 15
+SEIOmiMaskLabel[0][1]: mask3
+
diff --git a/cfg/sei_vui/object_mask_infos/scalability_dimension_info_for_omi.cfg b/cfg/sei_vui/object_mask_infos/scalability_dimension_info_for_omi.cfg
new file mode 100644
index 0000000000..b8159cacec
--- /dev/null
+++ b/cfg/sei_vui/object_mask_infos/scalability_dimension_info_for_omi.cfg
@@ -0,0 +1,9 @@
+#======== Scalability Dimension Information SEI message =====================
+SEISDIEnabled                               : 1
+SEISDIMaxLayersMinus1                       : 1
+SEISDIAuxiliaryInfoFlag                     : 1
+SEISDIMultiviewInfoFlag                     : 0
+SEISDILayerId                               : 0 1
+SEISDIAuxId                                 : 0 3
+SEISDINumAssociatedPrimaryLayersMinus1      : 0 0
+SEISDIAssociatedPrimaryLayerIdx             : 0
\ No newline at end of file
diff --git a/source/App/DecoderApp/DecApp.cpp b/source/App/DecoderApp/DecApp.cpp
index 3c5faa6210..1d9609d469 100644
--- a/source/App/DecoderApp/DecApp.cpp
+++ b/source/App/DecoderApp/DecApp.cpp
@@ -145,6 +145,18 @@ uint32_t DecApp::decode()
     }
   }
 
+#if JVET_AI0153_OMI_SEI
+  if (!m_objectMaskInfoSEIFileName.empty())
+  {
+    std::ofstream ofile(m_objectMaskInfoSEIFileName.c_str());
+    if (!ofile.good() || !ofile.is_open())
+    {
+      fprintf(stderr, "\nUnable to open file '%s' for writing Object-Mask-Information-SEI\n", m_objectMaskInfoSEIFileName.c_str());
+      exit(EXIT_FAILURE);
+    }
+  }
+#endif
+
   // main decoder loop
   bool loopFiltered[MAX_VPS_LAYERS] = { false };
 
@@ -1207,6 +1219,12 @@ void DecApp::xWriteOutput( PicList* pcListPic, uint32_t tId )
         }
         writeLineToOutputLog(pcPic);
 
+#if JVET_AI0153_OMI_SEI
+        if (!m_objectMaskInfoSEIFileName.empty())
+        {
+          xOutputObjectMaskInfos(pcPic);
+        }
+#endif
         // update POC of display order
         m_iPOCLastDisplay = pcPic->getPOC();
 
@@ -1420,6 +1438,12 @@ void DecApp::xFlushOutput( PicList* pcListPic, const int layerId )
             }
           }
           writeLineToOutputLog(pcPic);
+#if JVET_AI0153_OMI_SEI
+          if (!m_objectMaskInfoSEIFileName.empty())
+          {
+            xOutputObjectMaskInfos(pcPic);
+          }
+#endif
         // update POC of display order
         m_iPOCLastDisplay = pcPic->getPOC();
 
@@ -1599,6 +1623,125 @@ void DecApp::xOutputAnnotatedRegions(PicList* pcListPic)
   }
 }
 
+#if JVET_AI0153_OMI_SEI
+void DecApp::xOutputObjectMaskInfos(Picture* pcPic)
+{
+  SEIMessages objectMaskInfoSEIs = getSeisByType(pcPic->SEIs, SEI::PayloadType::OBJECT_MASK_INFO);
+  for (auto it = objectMaskInfoSEIs.begin(); it != objectMaskInfoSEIs.end(); it++)
+  {
+    const SEIObjectMaskInfos& seiObjectMaskInfo = *(SEIObjectMaskInfos*) (*it);
+
+    if (!seiObjectMaskInfo.m_hdr.m_cancelFlag)
+    {
+      if (m_omiHeader.m_receivedSettingsOnce)
+      {
+        CHECK(m_omiHeader.m_numAuxPicLayerMinus1 != seiObjectMaskInfo.m_hdr.m_numAuxPicLayerMinus1, "omi_num_aux_pic_layer_minus1 should be consistent within the CLVS.")
+        CHECK(m_omiHeader.m_maskIdLengthMinus1 != seiObjectMaskInfo.m_hdr.m_maskIdLengthMinus1, "omi_mask_id_length_minus1 should be consistent within the CLVS.")
+        CHECK(m_omiHeader.m_maskSampleValueLengthMinus8 != seiObjectMaskInfo.m_hdr.m_maskSampleValueLengthMinus8,"omi_mask_sample_value_length_minus8 should be consistent within the CLVS.")
+        CHECK(m_omiHeader.m_maskConfidenceInfoPresentFlag != seiObjectMaskInfo.m_hdr.m_maskConfidenceInfoPresentFlag,"Confidence info present flag should be consistent within the CLVS.");
+        if (m_omiHeader.m_maskConfidenceInfoPresentFlag)
+        {
+          CHECK(m_omiHeader.m_maskConfidenceLengthMinus1 != seiObjectMaskInfo.m_hdr.m_maskConfidenceLengthMinus1, "Confidence length should be consistent within the CLVS.");
+        }
+        CHECK(m_omiHeader.m_maskDepthInfoPresentFlag != seiObjectMaskInfo.m_hdr.m_maskDepthInfoPresentFlag,"Depth info present flag should be consistent within the CLVS.");
+        if (m_omiHeader.m_maskDepthInfoPresentFlag)
+        {
+          CHECK(m_omiHeader.m_maskDepthLengthMinus1 != seiObjectMaskInfo.m_hdr.m_maskDepthLengthMinus1, "Depth length should be consistent within the CLVS.");
+        }
+      }
+      else
+      {
+        m_omiHeader.m_receivedSettingsOnce = true;
+        m_omiHeader                        = seiObjectMaskInfo.m_hdr;   // copy the settings.
+      }
+    }
+
+    FILE* fpPersist = fopen(m_objectMaskInfoSEIFileName.c_str(), "ab");
+    if (fpPersist == nullptr)
+    {
+      std::cout << "Not able to open file for writing persist SEI messages" << std::endl;
+    }
+    else
+    {
+      fprintf(fpPersist, "POC %d\n", (int) pcPic->getPOC());
+      // header
+      fprintf(fpPersist, "OMI Cancel Flag = %d\n", seiObjectMaskInfo.m_hdr.m_cancelFlag);
+      if (!seiObjectMaskInfo.m_hdr.m_cancelFlag)
+      {
+        fprintf(fpPersist, "OMI Persistence Flag = %d\n", seiObjectMaskInfo.m_hdr.m_persistenceFlag);
+        fprintf(fpPersist, "OMI AuxPicLayer Num = %d\n", seiObjectMaskInfo.m_hdr.m_numAuxPicLayerMinus1 + 1);
+        fprintf(fpPersist, "OMI MaskId Length = %d\n", seiObjectMaskInfo.m_hdr.m_maskIdLengthMinus1 + 1);
+        fprintf(fpPersist, "OMI MaskSampleValue Length = %d\n",seiObjectMaskInfo.m_hdr.m_maskSampleValueLengthMinus8 + 8);
+        fprintf(fpPersist, "OMI MaskConf Present = %d\n", seiObjectMaskInfo.m_hdr.m_maskConfidenceInfoPresentFlag);
+        if (seiObjectMaskInfo.m_hdr.m_maskConfidenceInfoPresentFlag)
+        {
+          fprintf(fpPersist, "OMI MaskConf Length = %d\n", seiObjectMaskInfo.m_hdr.m_maskConfidenceLengthMinus1 + 1);
+        }
+        fprintf(fpPersist, "OMI MaskDepth Present = %d\n", seiObjectMaskInfo.m_hdr.m_maskDepthInfoPresentFlag);
+        if (seiObjectMaskInfo.m_hdr.m_maskDepthInfoPresentFlag)
+        {
+          fprintf(fpPersist, "OMI MaskDepth Length = %d\n", seiObjectMaskInfo.m_hdr.m_maskDepthLengthMinus1 + 1);
+        }
+        fprintf(fpPersist, "OMI MaskLabel Present = %d\n", seiObjectMaskInfo.m_hdr.m_maskLabelInfoPresentFlag);
+        if (seiObjectMaskInfo.m_hdr.m_maskLabelInfoPresentFlag)
+        {
+          fprintf(fpPersist, "OMI MaskLabelLang Present = %d\n",seiObjectMaskInfo.m_hdr.m_maskLabelLanguagePresentFlag);
+          if (seiObjectMaskInfo.m_hdr.m_maskLabelLanguagePresentFlag)
+          {
+            fprintf(fpPersist, "OMI MaskLabelLang = %s\n", seiObjectMaskInfo.m_hdr.m_maskLabelLanguage.c_str());
+          }
+        }
+        fprintf(fpPersist, "\n");
+
+        // infos
+        uint32_t maskIdx = 0;
+        for (uint32_t i = 0; i <= seiObjectMaskInfo.m_hdr.m_numAuxPicLayerMinus1; i++)
+        {
+          fprintf(fpPersist, "OMI MaskUpdateFlag[%d] = %d\n", i, seiObjectMaskInfo.m_maskPicUpdateFlag[i]);
+          if (seiObjectMaskInfo.m_maskPicUpdateFlag[i])
+          {
+            fprintf(fpPersist, "OMI MaskUpdateNum[%d] = %d\n", i, seiObjectMaskInfo.m_numMaskInPicUpdate[i]);
+            for (uint32_t j = 0; j < seiObjectMaskInfo.m_numMaskInPicUpdate[i]; j++)
+            {
+              fprintf(fpPersist, "MaskId[%d][%d] = %d\n", i, j, seiObjectMaskInfo.m_objectMaskInfos[maskIdx].maskId);
+              fprintf(fpPersist, "AuxSampleValue[%d][%d] = %d\n", i, j, seiObjectMaskInfo.m_objectMaskInfos[maskIdx].auxSampleValue);
+              fprintf(fpPersist, "MaskCancel[%d][%d] = %d\n", i, j,
+                      seiObjectMaskInfo.m_objectMaskInfos[maskIdx].maskCancel);
+              if (!seiObjectMaskInfo.m_objectMaskInfos[maskIdx].maskCancel)
+              {
+                fprintf(fpPersist, "MaskBBoxPresentFlag[%d][%d] = %d\n", i, j, seiObjectMaskInfo.m_objectMaskInfos[maskIdx].maskBoundingBoxPresentFlag);
+                if (seiObjectMaskInfo.m_objectMaskInfos[maskIdx].maskBoundingBoxPresentFlag)
+                {
+                  fprintf(fpPersist, "MaskTop[%d][%d] = %d\n", i, j,seiObjectMaskInfo.m_objectMaskInfos[maskIdx].maskTop);
+                  fprintf(fpPersist, "MaskLeft[%d][%d] = %d\n", i, j,seiObjectMaskInfo.m_objectMaskInfos[maskIdx].maskLeft);
+                  fprintf(fpPersist, "MaskWidth[%d][%d] = %d\n", i, j,seiObjectMaskInfo.m_objectMaskInfos[maskIdx].maskWidth);
+                  fprintf(fpPersist, "MaskHeight[%d][%d] = %d\n", i, j, seiObjectMaskInfo.m_objectMaskInfos[maskIdx].maskHeight);
+                }
+                if (seiObjectMaskInfo.m_hdr.m_maskConfidenceInfoPresentFlag)
+                {
+                  fprintf(fpPersist, "MaskConf[%d][%d] = %d\n", i, j,seiObjectMaskInfo.m_objectMaskInfos[maskIdx].maskConfidence);
+                }
+                if (seiObjectMaskInfo.m_hdr.m_maskDepthInfoPresentFlag)
+                {
+                  fprintf(fpPersist, "MaskDepth[%d][%d] = %d\n", i, j,seiObjectMaskInfo.m_objectMaskInfos[maskIdx].maskDepth);
+                }
+                if (m_omiHeader.m_maskLabelInfoPresentFlag)
+                {
+                  fprintf(fpPersist, "MaskLabel[%d][%d] = %s\n", i, j, seiObjectMaskInfo.m_objectMaskInfos[maskIdx].maskLabel.c_str());
+                }
+              }
+              maskIdx++;
+            }
+            fprintf(fpPersist, "\n");
+          }
+        }
+      }
+      fclose(fpPersist);
+    }
+  }
+}
+#endif
+
 /** \param nalu Input nalu to check whether its LayerId is within targetDecLayerIdSet
  */
 bool DecApp::xIsNaluWithinTargetDecLayerIdSet( const InputNALUnit* nalu ) const
diff --git a/source/App/DecoderApp/DecApp.h b/source/App/DecoderApp/DecApp.h
index c92890252a..c039fe4d1c 100644
--- a/source/App/DecoderApp/DecApp.h
+++ b/source/App/DecoderApp/DecApp.h
@@ -90,6 +90,10 @@ private:
   std::map<uint32_t, SEIAnnotatedRegions::AnnotatedRegionObject> m_arObjects; ///< AR object pool
   std::map<uint32_t, std::string>                                m_arLabels; ///< AR label pool
 
+#if JVET_AI0153_OMI_SEI
+  SEIObjectMaskInfos::ObjectMaskInfoHeader m_omiHeader;   ///< OMI header
+#endif
+
 private:
   bool  xIsNaluWithinTargetDecLayerIdSet( const InputNALUnit* nalu ) const; ///< check whether given Nalu is within targetDecLayerIdSet
   bool  xIsNaluWithinTargetOutputLayerIdSet( const InputNALUnit* nalu ) const; ///< check whether given Nalu is within targetOutputLayerIdSet
@@ -118,6 +122,9 @@ private:
 
   void  writeLineToOutputLog(Picture * pcPic);
   void xOutputAnnotatedRegions(PicList* pcListPic);
+#if JVET_AI0153_OMI_SEI
+  void xOutputObjectMaskInfos(Picture* pcPic);
+#endif
 };
 
 //! \}
diff --git a/source/App/DecoderApp/DecAppCfg.cpp b/source/App/DecoderApp/DecAppCfg.cpp
index ed2ddde038..254603cdf6 100644
--- a/source/App/DecoderApp/DecAppCfg.cpp
+++ b/source/App/DecoderApp/DecAppCfg.cpp
@@ -99,6 +99,9 @@ bool DecAppCfg::parseCfg( int argc, char* argv[] )
   ("SEICTIFilename",            m_SEICTIFileName,                      std::string(""), "CTI YUV output file name. If empty, no Colour Transform is applied (ignore SEI message)\n")
   ("SEIFGSFilename",            m_SEIFGSFileName,                      std::string(""), "FGS YUV output file name. If empty, no film grain is applied (ignore SEI message)\n")
   ("SEIAnnotatedRegionsInfoFilename", m_annotatedRegionsSEIFileName,   std::string(""), "Annotated regions output file name. If empty, no object information will be saved (ignore SEI message)\n")
+#if JVET_AI0153_OMI_SEI
+  ("SEIObjectMaskInfosFilename", m_objectMaskInfoSEIFileName,          std::string(""), "Object mask information output file name. If empty, no object mask information will be saved (ignore SEI message)\n")
+#endif
   ("OutputDecodedSEIMessagesFilename", m_outputDecodedSEIMessagesFilename, std::string(""), "When non empty, output decoded SEI messages to the indicated file. If file is '-', then output to stdout\n")
 #if JVET_S0257_DUMP_360SEI_MESSAGE
   ("360DumpFile",               m_outputDecoded360SEIMessagesFilename, std::string(""), "When non empty, output decoded 360 SEI messages to the indicated file.\n")
@@ -270,6 +273,9 @@ DecAppCfg::DecAppCfg()
   , m_SEICTIFileName()
   , m_SEIFGSFileName()
   , m_annotatedRegionsSEIFileName()
+#if JVET_AI0153_OMI_SEI
+  , m_objectMaskInfoSEIFileName()
+#endif
   , m_targetDecLayerIdSet()
   , m_outputDecodedSEIMessagesFilename()
 #if JVET_S0257_DUMP_360SEI_MESSAGE
diff --git a/source/App/DecoderApp/DecAppCfg.h b/source/App/DecoderApp/DecAppCfg.h
index d9978955bb..857783f893 100644
--- a/source/App/DecoderApp/DecAppCfg.h
+++ b/source/App/DecoderApp/DecAppCfg.h
@@ -78,6 +78,9 @@ protected:
   std::string   m_SEICTIFileName;                     ///< output Recon with CTI file name
   std::string   m_SEIFGSFileName;                     ///< output file name for reconstructed sequence with film grain
   std::string   m_annotatedRegionsSEIFileName;        ///< annotated regions file name
+#if JVET_AI0153_OMI_SEI
+  std::string m_objectMaskInfoSEIFileName;            ///< object mask information file name
+#endif
   std::vector<int> m_targetDecLayerIdSet;             ///< set of LayerIds to be included in the sub-bitstream extraction process.
   std::string   m_outputDecodedSEIMessagesFilename;   ///< filename to output decoded SEI messages to. If '-', then use stdout. If empty, do not output details.
 #if JVET_S0257_DUMP_360SEI_MESSAGE
diff --git a/source/App/EncoderApp/EncApp.cpp b/source/App/EncoderApp/EncApp.cpp
index 5d31380589..386a68eef8 100644
--- a/source/App/EncoderApp/EncApp.cpp
+++ b/source/App/EncoderApp/EncApp.cpp
@@ -998,6 +998,9 @@ void EncApp::xInitLibCfg( int layerIdx )
   m_cEncLib.setOmniViewportSEIHorRange                           ( m_omniViewportSEIHorRange );
   m_cEncLib.setOmniViewportSEIVerRange                           ( m_omniViewportSEIVerRange );
   m_cEncLib.setAnnotatedRegionSEIFileRoot                        (m_arSEIFileRoot);
+#if JVET_AI0153_OMI_SEI
+  m_cEncLib.setObjectMaskInfoSEIFileRoot                         (m_omiSEIFileRoot);
+#endif
   m_cEncLib.setRwpSEIEnabled                                     (m_rwpSEIEnabled);
   m_cEncLib.setRwpSEIRwpCancelFlag                               (m_rwpSEIRwpCancelFlag);
   m_cEncLib.setRwpSEIRwpPersistenceFlag                          (m_rwpSEIRwpPersistenceFlag);
@@ -1160,6 +1163,9 @@ void EncApp::xInitLibCfg( int layerIdx )
   m_cEncLib.setSdiSEIViewIdVal                                   (m_sdiSEIViewIdVal);
   m_cEncLib.setSdiSEIAuxId                                       (m_sdiSEIAuxId);
   m_cEncLib.setSdiSEINumAssociatedPrimaryLayersMinus1            (m_sdiSEINumAssociatedPrimaryLayersMinus1);
+#if JVET_AI0153_OMI_SEI
+  m_cEncLib.setSdiSEIAssociatedPrimaryLayerIdx                   (m_sdiSEIAssociatedPrimaryLayerIdx);
+#endif
   // multiview acquisition information sei
   m_cEncLib.setMaiSEIEnabled                                     (m_maiSEIEnabled);
   m_cEncLib.setMaiSEIIntrinsicParamFlag                          (m_maiSEIIntrinsicParamFlag);
diff --git a/source/App/EncoderApp/EncAppCfg.cpp b/source/App/EncoderApp/EncAppCfg.cpp
index 61282a5b73..8705f04ae2 100644
--- a/source/App/EncoderApp/EncAppCfg.cpp
+++ b/source/App/EncoderApp/EncAppCfg.cpp
@@ -696,6 +696,9 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
   SMultiValueInput<uint32_t>        cfg_sdiSEIViewIdVal                (0, 63, 0, std::numeric_limits<uint32_t>::max());
   SMultiValueInput<uint32_t>        cfg_sdiSEIAuxId                    (0, 255, 0, 63);
   SMultiValueInput<uint32_t>        cfg_sdiSEINumAssociatedPrimaryLayersMinus1 (0, 63, 0, 63);
+#if JVET_AI0153_OMI_SEI
+  SMultiValueInput<uint32_t>        cfg_sdiSEIAssociatedPrimaryLayerIdx(0, 63, 0, 63);
+#endif
   SMultiValueInput<bool>            cfg_maiSEISignFocalLengthX         (0, 1,   0, std::numeric_limits<uint32_t>::max());
   SMultiValueInput<uint32_t>        cfg_maiSEIExponentFocalLengthX     (0, 63, 0, std::numeric_limits<uint32_t>::max());
   SMultiValueInput<uint32_t>        cfg_maiSEIMantissaFocalLengthX     (0, std::numeric_limits<uint32_t>::max(), 0, std::numeric_limits<uint32_t>::max());
@@ -1467,6 +1470,9 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
 ("SEISubpicLevelInfoExplicitFraction", m_cfgSubpictureLevelInfoSEI.m_explicitFraction, false, "Enable sending of explicit fractions in Subpicture Level Information SEI messages")
 ("SEISubpicLevelInfoNumSubpics", m_cfgSubpictureLevelInfoSEI.m_numSubpictures, 1, "Number of subpictures for Subpicture Level Information SEI messages")
 ("SEIAnnotatedRegionsFileRoot,-ar", m_arSEIFileRoot, std::string(""), "Annotated region SEI parameters root file name (wo num ext); only the file name base is to be added. Underscore and POC would be automatically addded to . E.g. \"-ar ar\" will search for files ar_0.txt, ar_1.txt, ...")
+#if JVET_AI0153_OMI_SEI
+("SEIObjectMaskFileRoot,-omi", m_omiSEIFileRoot, std::string(""), "Object mask information SEI parameters root file name (wo num ext); only the file name base is to be added. Underscore and POC would be automatically added to . E.g. \"-omi omi\" will search for files omi_0.txt, omi_1.txt, ...")
+#endif
 ("SEISubpicLevelInfoMaxSublayers", m_cfgSubpictureLevelInfoSEI.m_sliMaxSublayers, 1, "Number of sublayers for Subpicture Level Information SEI messages")
 ("SEISubpicLevelInfoSublayerInfoPresentFlag", m_cfgSubpictureLevelInfoSEI.hasSublayerInfo, false, "Enable sending of level information for all sublayers in Subpicture Level Information SEI messages")
 ("SEISubpicLevelInfoRefLevelFractions", cfg_sliFractions, cfg_sliFractions, "List of subpicture level fractions for Subpicture Level Information SEI messages")
@@ -1613,6 +1619,9 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
   ("SEISDIViewIdVal",                                 cfg_sdiSEIViewIdVal,        cfg_sdiSEIViewIdVal, "List of the view identifiers in the scalaibility dimension information SEI message")
   ("SEISDIAuxId",                                     cfg_sdiSEIAuxId,                cfg_sdiSEIAuxId, "List of the auxiliary identifiers in the scalaibility dimension information SEI message")
   ("SEISDINumAssociatedPrimaryLayersMinus1",          cfg_sdiSEINumAssociatedPrimaryLayersMinus1, cfg_sdiSEINumAssociatedPrimaryLayersMinus1, "List of the numbers of associated primary layers of i-th layer, which is an auxiliary layer.")
+#if JVET_AI0153_OMI_SEI
+  ("SEISDIAssociatedPrimaryLayerIdx",                 cfg_sdiSEIAssociatedPrimaryLayerIdx, cfg_sdiSEIAssociatedPrimaryLayerIdx, "List of the layer index of the j-th associated primary layer of the i-th layer, which is an auxiliary layer. It is a 1-d list and the number of the associated primary layer of the i-th auxiliary layer is indicated by cfg_sdiSEINumAssociatedPrimaryLayersMinus1 and cfg_sdiSEIAuxId.")
+#endif
   // multiview acquisition information SEI
   ("SEIMAIEnabled",                                   m_maiSEIEnabled,                                    false, "Control generation of multiview acquisition information SEI message")
   ("SEIMAIIntrinsicParamFlag",                        m_maiSEIIntrinsicParamFlag,                         false, "Specifies the presence of intrinsic camera parameters in the multiview acquisition information SEI message")
@@ -3514,6 +3523,9 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
       m_sdiSEIViewIdVal.resize(m_sdiSEIMaxLayersMinus1 + 1);
       m_sdiSEIAuxId.resize(m_sdiSEIMaxLayersMinus1 + 1);
       m_sdiSEINumAssociatedPrimaryLayersMinus1.resize(m_sdiSEIMaxLayersMinus1 + 1);
+#if JVET_AI0153_OMI_SEI
+      uint32_t associatedPrimaryLayerIdxListCnt = 0;
+#endif
       for (int i = 0; i <= m_sdiSEIMaxLayersMinus1; i++)
       {
         m_sdiSEILayerId[i] = cfg_sdiSEILayerId.values[i];
@@ -3527,6 +3539,14 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
           if (m_sdiSEIAuxId[i] > 0)
           {
             m_sdiSEINumAssociatedPrimaryLayersMinus1[i] = cfg_sdiSEINumAssociatedPrimaryLayersMinus1.values[i];
+#if JVET_AI0153_OMI_SEI
+            m_sdiSEIAssociatedPrimaryLayerIdx.resize(associatedPrimaryLayerIdxListCnt + m_sdiSEINumAssociatedPrimaryLayersMinus1[i] + 1);
+            for (uint32_t k = 0; k <= m_sdiSEINumAssociatedPrimaryLayersMinus1[i]; k++)
+            {
+              m_sdiSEIAssociatedPrimaryLayerIdx[associatedPrimaryLayerIdxListCnt + k] = cfg_sdiSEIAssociatedPrimaryLayerIdx.values[associatedPrimaryLayerIdxListCnt + k];
+            }
+            associatedPrimaryLayerIdxListCnt += (m_sdiSEINumAssociatedPrimaryLayersMinus1[i] + 1);
+#endif
           }
         }
       }
diff --git a/source/App/EncoderApp/EncAppCfg.h b/source/App/EncoderApp/EncAppCfg.h
index 2131ae88ff..772e92f8d8 100644
--- a/source/App/EncoderApp/EncAppCfg.h
+++ b/source/App/EncoderApp/EncAppCfg.h
@@ -626,6 +626,9 @@ protected:
   std::vector<uint32_t>  m_sdiSEIViewIdVal;
   std::vector<uint32_t>  m_sdiSEIAuxId;
   std::vector<uint32_t>  m_sdiSEINumAssociatedPrimaryLayersMinus1;
+#if JVET_AI0153_OMI_SEI
+  std::vector<uint32_t>  m_sdiSEIAssociatedPrimaryLayerIdx;
+#endif
   // multiview acquisition information sei
   bool              m_maiSEIEnabled;
   bool              m_maiSEIIntrinsicParamFlag;
@@ -707,6 +710,9 @@ protected:
   std::vector<uint32_t> m_omniViewportSEIHorRange;
   std::vector<uint32_t> m_omniViewportSEIVerRange;
   std::string           m_arSEIFileRoot;  // Annotated region SEI - initialized from external file
+#if JVET_AI0153_OMI_SEI
+  std::string           m_omiSEIFileRoot;   // Object mask information SEI - initialized from external file
+#endif
   bool                  m_rwpSEIEnabled;
   bool                  m_rwpSEIRwpCancelFlag;
   bool                  m_rwpSEIRwpPersistenceFlag;
diff --git a/source/Lib/CommonLib/SEI.h b/source/Lib/CommonLib/SEI.h
index 6eb4f05468..9588ae36a3 100644
--- a/source/Lib/CommonLib/SEI.h
+++ b/source/Lib/CommonLib/SEI.h
@@ -107,9 +107,13 @@ public:
 #if JVET_AG2034_SPTI_SEI
     SOURCE_PICTURE_TIMING_INFO = 216,
 #endif
+#if JVET_AI0153_OMI_SEI
+    OBJECT_MASK_INFO = 217,
+#endif
 #if JVET_AH2006_TXTDESCRINFO_SEI
     SEI_TEXT_DESCRIPTION                       = 219,
 #endif
+
   };
 
   SEI() {}
@@ -1275,6 +1279,60 @@ public:
   std::vector<std::pair<AnnotatedRegionLabelIndex,  AnnotatedRegionLabel>  > m_annotatedLabels;
 };
 
+#if JVET_AI0153_OMI_SEI
+class SEIObjectMaskInfos : public SEI
+{
+public:
+  PayloadType payloadType() const { return PayloadType::OBJECT_MASK_INFO; }
+  SEIObjectMaskInfos() {}
+  SEIObjectMaskInfos(const SEIObjectMaskInfos& sei) { copyFrom(sei); }
+  virtual ~SEIObjectMaskInfos() {}
+
+  void copyFrom(const SEIObjectMaskInfos& seiObjectMask) { (*this) = seiObjectMask; }
+
+  struct ObjectMaskInfo
+  {
+    ObjectMaskInfo() : maskCancel(false), maskBoundingBoxPresentFlag(false) {}
+    bool        maskCancel;
+    uint32_t    maskId;
+    uint32_t    auxSampleValue;
+    bool        maskBoundingBoxPresentFlag;
+    uint32_t    maskTop;
+    uint32_t    maskLeft;
+    uint32_t    maskWidth;
+    uint32_t    maskHeight;
+    uint32_t    maskConfidence;
+    uint32_t    maskDepth;
+    std::string maskLabel;
+  };
+
+  struct ObjectMaskInfoHeader
+  {
+    ObjectMaskInfoHeader() : m_cancelFlag(true), m_receivedSettingsOnce(false) {}
+    bool m_cancelFlag;
+    bool m_receivedSettingsOnce;   // used for decoder conformance checking. Other confidence flags must be unchanged
+                                  // once this flag is set.
+    bool m_persistenceFlag;
+    uint32_t    m_numAuxPicLayerMinus1;
+    uint32_t    m_maskIdLengthMinus1;
+    uint32_t    m_maskSampleValueLengthMinus8;
+    bool        m_maskConfidenceInfoPresentFlag;
+    uint32_t    m_maskConfidenceLengthMinus1;   // Only valid if m_maskConfidenceInfoPresentFlag
+    bool        m_maskDepthInfoPresentFlag;
+    uint32_t    m_maskDepthLengthMinus1;   // Only valid if m_maskDepthInfoPresentFlag
+    bool        m_maskLabelInfoPresentFlag;
+    bool        m_maskLabelLanguagePresentFlag;   // Only valid if m_maskLabelInfoPresentFlag
+    // SEIOmiBitEqualToZero
+    std::string m_maskLabelLanguage;   // Only valid if m_maskLabelLanguagePresentFlag
+  };
+
+  ObjectMaskInfoHeader        m_hdr;
+  std::vector<uint32_t>       m_maskPicUpdateFlag;
+  std::vector<uint32_t>       m_numMaskInPicUpdate;
+  std::vector<ObjectMaskInfo> m_objectMaskInfos;
+};
+#endif
+
 class SEIExtendedDrapIndication : public SEI
 {
 public:
diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h
index 4c1e90fefd..cf9b9b7459 100644
--- a/source/Lib/CommonLib/TypeDef.h
+++ b/source/Lib/CommonLib/TypeDef.h
@@ -68,6 +68,8 @@
 
 #define JVET_AI0071_NNPFC_SPO_USAGE_IDCS 1  // Indication of the user viewing and/or machine analysis usage in the NNPFC and SPO SEI messages
 
+#define JVET_AI0153_OMI_SEI 1 // JVET-AI0153: OMI-SEI Implementation as JVET-AH0346
+
 //########### place macros to be be kept below this line ###############
 
 #define GDR_ENABLED   1
diff --git a/source/Lib/DecoderLib/SEIread.cpp b/source/Lib/DecoderLib/SEIread.cpp
index 4ee860cd44..acdabd1228 100644
--- a/source/Lib/DecoderLib/SEIread.cpp
+++ b/source/Lib/DecoderLib/SEIread.cpp
@@ -382,6 +382,12 @@ bool SEIReader::xReadSEImessage(SEIMessages& seis, const NalUnitType nalUnitType
       sei = new SEIAnnotatedRegions;
       xParseSEIAnnotatedRegions((SEIAnnotatedRegions &) *sei, payloadSize, pDecodedMessageOutputStream);
       break;
+#if JVET_AI0153_OMI_SEI
+    case SEI::PayloadType::OBJECT_MASK_INFO:
+      sei = new SEIObjectMaskInfos;
+      xParseSEIObjectMaskInfos((SEIObjectMaskInfos&) *sei, payloadSize, pDecodedMessageOutputStream);
+      break;
+#endif
     case SEI::PayloadType::PARAMETER_SETS_INCLUSION_INDICATION:
       sei = new SEIParameterSetsInclusionIndication;
       xParseSEIParameterSetsInclusionIndication((SEIParameterSetsInclusionIndication &) *sei, payloadSize,
@@ -1870,6 +1876,141 @@ void SEIReader::xParseSEIAnnotatedRegions(SEIAnnotatedRegions& sei, uint32_t pay
   }
 }
 
+#if JVET_AI0153_OMI_SEI
+void SEIReader::xParseSEIObjectMaskInfos(SEIObjectMaskInfos& sei, uint32_t payloadSize, std::ostream* pDecodedMessageOutputStream)
+{
+  output_sei_message_header(sei, pDecodedMessageOutputStream, payloadSize);
+  uint32_t val;
+
+  sei_read_flag(pDecodedMessageOutputStream, val, "omi_cancel_flag");
+  sei.m_hdr.m_cancelFlag = val;
+  if (!sei.m_hdr.m_cancelFlag)
+  {
+    sei_read_flag(pDecodedMessageOutputStream, val, "omi_persistence_flag");
+    sei.m_hdr.m_persistenceFlag = val;
+    sei_read_uvlc(pDecodedMessageOutputStream, val, "omi_num_aux_pic_layer_minus1");
+    sei.m_hdr.m_numAuxPicLayerMinus1 = val;
+    sei_read_uvlc(pDecodedMessageOutputStream, val, "omi_mask_id_length_minus1");
+    sei.m_hdr.m_maskIdLengthMinus1 = val;
+    sei_read_uvlc(pDecodedMessageOutputStream, val, "omi_mask_sample_value_length_minus8");
+    sei.m_hdr.m_maskSampleValueLengthMinus8 = val;
+    sei_read_flag(pDecodedMessageOutputStream, val, "omi_mask_confidence_info_present_flag");
+    sei.m_hdr.m_maskConfidenceInfoPresentFlag = val;
+    if (sei.m_hdr.m_maskConfidenceInfoPresentFlag)
+    {
+      sei_read_code(pDecodedMessageOutputStream, 4, val, "omi_mask_confidence_length_minus1");
+      sei.m_hdr.m_maskConfidenceLengthMinus1 = val;
+    }
+    sei_read_flag(pDecodedMessageOutputStream, val, "omi_mask_depth_info_present_flag");
+    sei.m_hdr.m_maskDepthInfoPresentFlag = val;
+    if (sei.m_hdr.m_maskDepthInfoPresentFlag)
+    {
+      sei_read_code(pDecodedMessageOutputStream, 4, val, "omi_mask_depth_length_minus1");
+      sei.m_hdr.m_maskDepthLengthMinus1 = val;
+    }
+    sei_read_flag(pDecodedMessageOutputStream, val, "omi_mask_label_info_present_flag");
+    sei.m_hdr.m_maskLabelInfoPresentFlag = val;
+    if (sei.m_hdr.m_maskLabelInfoPresentFlag)
+    {
+      sei_read_flag(pDecodedMessageOutputStream, val, "omi_mask_label_language_present_flag");
+      sei.m_hdr.m_maskLabelLanguagePresentFlag = val;
+      if (sei.m_hdr.m_maskLabelLanguagePresentFlag)
+      {
+        // byte alignment
+        while (!isByteAligned())
+        {
+          uint32_t code;
+          sei_read_flag(pDecodedMessageOutputStream, code, "omi_bit_equal_to_zero");
+          CHECK(code != 0, "non-zero value parsed for zero-bit");
+        }
+        sei.m_hdr.m_maskLabelLanguage.clear();
+        do
+        {
+          sei_read_code(pDecodedMessageOutputStream, 8, val, "omi_mask_lable_language");
+          if (val)
+          {
+            sei.m_hdr.m_maskLabelLanguage.push_back((char) val);
+          }
+        } while (val != '\0');
+        CHECK(sei.m_hdr.m_maskLabelLanguage.size() > 255, "label oversize");
+      }
+    }
+
+    sei.m_maskPicUpdateFlag.resize(sei.m_hdr.m_numAuxPicLayerMinus1 + 1);
+    sei.m_numMaskInPicUpdate.resize(sei.m_hdr.m_numAuxPicLayerMinus1 + 1);
+    for (uint32_t i = 0; i <= sei.m_hdr.m_numAuxPicLayerMinus1; i++)
+    {
+      sei_read_flag(pDecodedMessageOutputStream, val, "omi_mask_pic_update_flag[i]");
+      sei.m_maskPicUpdateFlag[i] = val;
+      if (sei.m_maskPicUpdateFlag[i])
+      {
+        sei_read_uvlc(pDecodedMessageOutputStream, val, "omi_num_mask_in_pic_update[i]");
+        sei.m_numMaskInPicUpdate[i] = val;
+        for (uint32_t j = 0; j < sei.m_numMaskInPicUpdate[i]; j++)
+        {
+          SEIObjectMaskInfos::ObjectMaskInfo objMaskInfo;
+          sei_read_code(pDecodedMessageOutputStream, sei.m_hdr.m_maskIdLengthMinus1 + 1, val, "omi_mask_id[i][j]");
+          objMaskInfo.maskId = val;
+          sei_read_code(pDecodedMessageOutputStream, sei.m_hdr.m_maskSampleValueLengthMinus8 + 8, val, "omi_aux_sample_value[i][j]");
+          objMaskInfo.auxSampleValue = val;
+          sei_read_flag(pDecodedMessageOutputStream, val, "omi_mask_cancel[i][j]");
+          objMaskInfo.maskCancel = val;
+          if (!objMaskInfo.maskCancel)
+          {
+            sei_read_flag(pDecodedMessageOutputStream, val, "omi_mask_bounding_box_present_flag[i][j]");
+            objMaskInfo.maskBoundingBoxPresentFlag = val;
+            if (objMaskInfo.maskBoundingBoxPresentFlag)
+            {
+              sei_read_code(pDecodedMessageOutputStream, 16, val, "omi_mask_top[i][j]");
+              objMaskInfo.maskTop = val;
+              sei_read_code(pDecodedMessageOutputStream, 16, val, "omi_mask_left[i][j]");
+              objMaskInfo.maskLeft = val;
+              sei_read_code(pDecodedMessageOutputStream, 16, val, "omi_mask_width[i][j]");
+              objMaskInfo.maskWidth = val;
+              sei_read_code(pDecodedMessageOutputStream, 16, val, "omi_mask_height[i][j]");
+              objMaskInfo.maskHeight = val;
+            }
+
+            if (sei.m_hdr.m_maskConfidenceInfoPresentFlag)
+            {
+              sei_read_code(pDecodedMessageOutputStream, sei.m_hdr.m_maskConfidenceLengthMinus1 + 1, val, "omi_mask_confidence[i][j]");
+              objMaskInfo.maskConfidence = val;
+            }
+            if (sei.m_hdr.m_maskDepthInfoPresentFlag)
+            {
+              sei_read_code(pDecodedMessageOutputStream, sei.m_hdr.m_maskDepthLengthMinus1 + 1, val, "omi_mask_depth[i][j]");
+              objMaskInfo.maskDepth = val;
+            }
+            // byte alignment
+            while (!isByteAligned())
+            {
+              uint32_t code;
+              sei_read_flag(pDecodedMessageOutputStream, code, "omi_bit_equal_to_zero");
+              CHECK(code != 0, "non-zero value parsed for zero-bit");
+            }
+            if (sei.m_hdr.m_maskLabelInfoPresentFlag)
+            {
+              objMaskInfo.maskLabel.clear();
+              do
+              {
+                sei_read_code(pDecodedMessageOutputStream, 8, val, "omi_mask_label[i][j][k]");
+                if (val)
+                {
+                  objMaskInfo.maskLabel.push_back((char) val);
+                }
+              } while (val != '\0');
+              CHECK(objMaskInfo.maskLabel.size() > 255, "label oversize");
+            }
+          }
+
+          sei.m_objectMaskInfos.push_back(objMaskInfo);
+        }
+      }
+    }
+  }
+}
+#endif
+
 #if JVET_AH2006_EOI_SEI
 void SEIReader::xParseSEIEncoderOptimizationInfo(SEIEncoderOptimizationInfo& sei, uint32_t payloadSize, std::ostream* pDecodedMessageOutputStream)
 {
diff --git a/source/Lib/DecoderLib/SEIread.h b/source/Lib/DecoderLib/SEIread.h
index 26df095a22..7cd24f1b8f 100644
--- a/source/Lib/DecoderLib/SEIread.h
+++ b/source/Lib/DecoderLib/SEIread.h
@@ -89,6 +89,9 @@ protected:
   void xParseSEIParameterSetsInclusionIndication(SEIParameterSetsInclusionIndication& sei, uint32_t payloadSize,                std::ostream* pDecodedMessageOutputStream);
   void xParseSEIMasteringDisplayColourVolume  (SEIMasteringDisplayColourVolume& sei,  uint32_t payloadSize,                     std::ostream *pDecodedMessageOutputStream);
   void xParseSEIAnnotatedRegions              (SEIAnnotatedRegions& sei,              uint32_t payloadSize,                     std::ostream *pDecodedMessageOutputStream);
+#if JVET_AI0153_OMI_SEI
+  void xParseSEIObjectMaskInfos               (SEIObjectMaskInfos& sei,               uint32_t payloadSize,                     std::ostream* pDecodedMessageOutputStream);
+#endif
   void xParseSEIAlternativeTransferCharacteristics(SEIAlternativeTransferCharacteristics& sei,              uint32_t payLoadSize,                     std::ostream *pDecodedMessageOutputStream);
 #if JVET_AH2006_EOI_SEI
   void xParseSEIEncoderOptimizationInfo(SEIEncoderOptimizationInfo& sei, uint32_t payloadSize, std::ostream* pDecodedMessageOutputStream);
diff --git a/source/Lib/EncoderLib/EncCfg.h b/source/Lib/EncoderLib/EncCfg.h
index b3f16514ec..4395bc76ab 100644
--- a/source/Lib/EncoderLib/EncCfg.h
+++ b/source/Lib/EncoderLib/EncCfg.h
@@ -879,6 +879,9 @@ protected:
   std::vector<uint32_t>  m_sdiSEIViewIdVal;
   std::vector<uint32_t>  m_sdiSEIAuxId;
   std::vector<uint32_t>  m_sdiSEINumAssociatedPrimaryLayersMinus1;
+#if JVET_AI0153_OMI_SEI
+  std::vector<uint32_t> m_sdiSEIAssociatedPrimaryLayerIdx;
+#endif
   // mai sei
   bool              m_maiSEIEnabled;
   bool              m_maiSEIIntrinsicParamFlag;
@@ -934,6 +937,9 @@ protected:
   int       m_driSEINonlinearNumMinus1;
   std::vector<uint32_t> m_driSEINonlinearModel;
   std::string           m_arSEIFileRoot;  // Annotated region SEI - initialized from external file
+#if JVET_AI0153_OMI_SEI
+  std::string           m_omiSEIFileRoot;   // Object mask information SEI - initialized from external file
+#endif
 
   bool m_SEIManifestSEIEnabled;
   bool m_SEIPrefixIndicationSEIEnabled;
@@ -2313,6 +2319,10 @@ public:
   uint32_t  getOmniViewportSEIVerRange(int idx)                      { return m_omniViewportSEIVerRange[idx]; }
   void  setAnnotatedRegionSEIFileRoot(const std::string &s)          { m_arSEIFileRoot = s; m_arObjects.clear();}
   const std::string &getAnnotatedRegionSEIFileRoot() const           { return m_arSEIFileRoot; }
+#if JVET_AI0153_OMI_SEI
+  void  setObjectMaskInfoSEIFileRoot(const std::string& s)           { m_omiSEIFileRoot = s; }
+  const std::string& getObjectMaskInfoSEIFileRoot() const            { return m_omiSEIFileRoot; }
+#endif
   void     setRwpSEIEnabled(bool b)                                                                     { m_rwpSEIEnabled = b; }
   bool     getRwpSEIEnabled()                                                                           { return m_rwpSEIEnabled; }
   void     setRwpSEIRwpCancelFlag(bool b)                                                               { m_rwpSEIRwpCancelFlag = b; }
@@ -2602,6 +2612,10 @@ public:
   uint32_t getSdiSEIAuxId(int idx) const                             { return m_sdiSEIAuxId[idx]; }
   void     setSdiSEINumAssociatedPrimaryLayersMinus1(const std::vector<uint32_t>& sdiSEINumAssociatedPrimaryLayersMinus1)   { m_sdiSEINumAssociatedPrimaryLayersMinus1 = sdiSEINumAssociatedPrimaryLayersMinus1; }
   uint32_t getSdiSEINumAssociatedPrimaryLayersMinus1(int idx) const  { return m_sdiSEINumAssociatedPrimaryLayersMinus1[idx]; }
+#if JVET_AI0153_OMI_SEI
+  void     setSdiSEIAssociatedPrimaryLayerIdx(const std::vector<uint32_t>& sdiSEIAssociatedPrimaryLayerIdx) { m_sdiSEIAssociatedPrimaryLayerIdx = sdiSEIAssociatedPrimaryLayerIdx; }
+  uint32_t getSdiSEIAssociatedPrimaryLayerIdx(int idx) const                                                { return m_sdiSEIAssociatedPrimaryLayerIdx[idx]; }
+#endif
   // multiview acquisition information SEI
   void     setMaiSEIEnabled(bool b)                                  { m_maiSEIEnabled = b; }
   bool     getMaiSEIEnabled() const                                  { return m_maiSEIEnabled; }
diff --git a/source/Lib/EncoderLib/EncGOP.cpp b/source/Lib/EncoderLib/EncGOP.cpp
index 453a9a1a80..3880ecc7b0 100644
--- a/source/Lib/EncoderLib/EncGOP.cpp
+++ b/source/Lib/EncoderLib/EncGOP.cpp
@@ -1002,6 +1002,24 @@ void EncGOP::xCreatePerPictureSEIMessages (int picInGOP, SEIMessages& seiMessage
     }
   }
 
+#if JVET_AI0153_OMI_SEI
+  if (!m_pcCfg->getObjectMaskInfoSEIFileRoot().empty())
+  {
+    // CHECK(!m_pcCfg->getSdiSEIEnabled(), "SDI-SEI has not enabled. (OMI-SEI depends on SDI-SEI)");
+    SEIObjectMaskInfos* seiObjectMaskInfo = new SEIObjectMaskInfos();
+    const bool          success           = m_seiEncoder.initSEIObjectMaskInfos(seiObjectMaskInfo, slice->getPOC());
+
+    if (success)
+    {
+      seiMessages.push_back(seiObjectMaskInfo);
+    }
+    else
+    {
+      delete seiObjectMaskInfo;
+    }
+  }
+#endif
+
   if (m_pcCfg->getFilmGrainCharactersticsSEIEnabled() && m_pcCfg->getFilmGrainCharactersticsSEIPerPictureSEI())
   {
     SEIFilmGrainCharacteristics *fgcSEI = new SEIFilmGrainCharacteristics;
diff --git a/source/Lib/EncoderLib/SEIEncoder.cpp b/source/Lib/EncoderLib/SEIEncoder.cpp
index ccd9b3b7e1..83d8275c75 100644
--- a/source/Lib/EncoderLib/SEIEncoder.cpp
+++ b/source/Lib/EncoderLib/SEIEncoder.cpp
@@ -932,6 +932,141 @@ void SEIEncoder::readAnnotatedRegionSEI(std::istream &fic, SEIAnnotatedRegions *
   }
 }
 
+#if JVET_AI0153_OMI_SEI
+void SEIEncoder::readObjectMaskInfoSEI(std::istream& fic, SEIObjectMaskInfos* seiObjMask, bool& failed)
+{
+  readTokenValue(seiObjMask->m_hdr.m_cancelFlag, failed, fic, "SEIOmiCancelFlag");
+  if (!seiObjMask->m_hdr.m_cancelFlag)
+  {
+    readTokenValue(seiObjMask->m_hdr.m_persistenceFlag, failed, fic, "SEIOmiPersistenceFlag");
+    readTokenValueAndValidate<uint32_t>(seiObjMask->m_hdr.m_numAuxPicLayerMinus1, failed, fic, "SEIOmiNumAuxPicLayerMinus1", uint32_t(0), uint32_t(255));
+
+    if (m_pcCfg->getSdiSEIEnabled())
+    {
+      // Conformance Check: the value of omi_num_aux_pic_layer shall be equal to numAuxLayer
+      std::vector<std::vector<uint32_t>> associatedPrimaryLayerIdx;
+      uint32_t                           associatedPrimaryLayerIdxCnt = 0;
+      for (uint32_t i = 0; i <= m_pcCfg->getSdiSEIMaxLayersMinus1(); i++)
+      {
+        if (m_pcCfg->getSdiSEIAuxId(i))
+        {
+          associatedPrimaryLayerIdx.push_back(std::vector<uint32_t>(m_pcCfg->getSdiSEINumAssociatedPrimaryLayersMinus1(i) + 1));
+          for (uint32_t j = 0; j <= m_pcCfg->getSdiSEINumAssociatedPrimaryLayersMinus1(i); j++)
+          {
+            associatedPrimaryLayerIdx[i][j] = m_pcCfg->getSdiSEIAssociatedPrimaryLayerIdx(associatedPrimaryLayerIdxCnt++);
+          }
+        }
+        else
+        {
+          associatedPrimaryLayerIdx.push_back(std::vector<uint32_t>());
+        }
+      }
+
+      int      primaryLayerId = m_pcEncLib->getLayerId();
+      uint32_t numAuxLayer    = 0;
+      for (uint32_t i = 0; i <= m_pcCfg->getSdiSEIMaxLayersMinus1(); i++)
+      {
+        if (m_pcCfg->getSdiSEIAuxId(i) == 3)
+        {
+          for (uint32_t j = 0; j <= m_pcCfg->getSdiSEINumAssociatedPrimaryLayersMinus1(i); j++)
+          {
+            if (m_pcCfg->getSdiSEILayerId(associatedPrimaryLayerIdx[i][j]) == primaryLayerId)
+            {
+              numAuxLayer++;
+            }
+          }
+        }
+      }
+      CHECK(((seiObjMask->m_hdr.m_numAuxPicLayerMinus1 + 1) != numAuxLayer), "The value of omi_num_aux_pic_layer shall be equal to numAuxLayer.");
+    }
+
+    readTokenValueAndValidate<uint32_t>(seiObjMask->m_hdr.m_maskIdLengthMinus1, failed, fic, "SEIOmiMaskIdLengthMinus1",uint32_t(0), uint32_t(255));
+    readTokenValueAndValidate<uint32_t>(seiObjMask->m_hdr.m_maskSampleValueLengthMinus8, failed, fic,"SEIOmiMaskSampleValueLengthMinus8", uint32_t(0), uint32_t(8));
+    readTokenValue(seiObjMask->m_hdr.m_maskConfidenceInfoPresentFlag, failed, fic,"SEIOmiMaskConfidenceInfoPresentFlag");
+    if (seiObjMask->m_hdr.m_maskConfidenceInfoPresentFlag)
+    {
+      readTokenValueAndValidate<uint32_t>(seiObjMask->m_hdr.m_maskConfidenceLengthMinus1, failed, fic,"SEIOmiMaskConfidenceLengthMinus1", uint32_t(0), uint32_t(31));
+    }
+    readTokenValue(seiObjMask->m_hdr.m_maskDepthInfoPresentFlag, failed, fic, "SEIOmiMaskDepthInfoPresentFlag");
+    if (seiObjMask->m_hdr.m_maskDepthInfoPresentFlag)
+    {
+      readTokenValueAndValidate<uint32_t>(seiObjMask->m_hdr.m_maskDepthLengthMinus1, failed, fic,"SEIOmiMaskDepthLengthMinus1", uint32_t(0), uint32_t(31));
+    }
+    readTokenValue(seiObjMask->m_hdr.m_maskLabelInfoPresentFlag, failed, fic, "SEIOmiMaskLabelInfoPresentFlag");
+    if (seiObjMask->m_hdr.m_maskLabelInfoPresentFlag)
+    {
+      readTokenValue(seiObjMask->m_hdr.m_maskLabelLanguagePresentFlag, failed, fic,"SEIOmiMaskLabelLanguagePresentFlag");
+      if (seiObjMask->m_hdr.m_maskLabelLanguagePresentFlag)
+      {
+        readTokenValue(seiObjMask->m_hdr.m_maskLabelLanguage, failed, fic, "SEIOmiMaskLabelLanguage");
+      }
+    }
+
+    uint32_t objMaskInfoCnt = 0;
+    seiObjMask->m_maskPicUpdateFlag.resize(seiObjMask->m_hdr.m_numAuxPicLayerMinus1 + 1);
+    seiObjMask->m_numMaskInPicUpdate.resize(seiObjMask->m_hdr.m_numAuxPicLayerMinus1 + 1);
+    for (uint32_t i = 0; i <= seiObjMask->m_hdr.m_numAuxPicLayerMinus1; i++)
+    {
+      std::string cfgMaskPicUpdateFlagStr = "SEIOmiMaskPicUpdateFlag[" + std::to_string(i) + "]";
+      readTokenValue(seiObjMask->m_maskPicUpdateFlag[i], failed, fic, cfgMaskPicUpdateFlagStr.c_str());
+      if (seiObjMask->m_maskPicUpdateFlag[i])
+      {
+        std::string cfgNumMaskInPicUpdataStr = "SEIOmiNumMaskInPicUpdate[" + std::to_string(i) + "]";
+        readTokenValueAndValidate<uint32_t>(seiObjMask->m_numMaskInPicUpdate[i], failed, fic, cfgNumMaskInPicUpdataStr.c_str(), uint32_t(0), uint32_t((1 << (seiObjMask->m_hdr.m_maskIdLengthMinus1 + 1)) - 1));
+        seiObjMask->m_objectMaskInfos.resize(objMaskInfoCnt + seiObjMask->m_numMaskInPicUpdate[i]);
+        for (uint32_t j = 0; j < seiObjMask->m_numMaskInPicUpdate[i]; j++)
+        {
+          SEIObjectMaskInfos::ObjectMaskInfo& omi = seiObjMask->m_objectMaskInfos[objMaskInfoCnt];
+
+          std::string cfgMaskIdStr = "SEIOmiMaskId[" + std::to_string(i) + "][" + std::to_string(j) + "]";
+          std::string cfgAuxSampleValueStr = "SEIOmiAuxSampleValue[" + std::to_string(i) + "][" + std::to_string(j) + "]";
+          std::string cfgMaskCancelStr = "SEIOmiMaskCancel[" + std::to_string(i) + "][" + std::to_string(j) + "]";
+          readTokenValueAndValidate<uint32_t>(omi.maskId, failed, fic, cfgMaskIdStr.c_str(), uint32_t(0), uint32_t((1 << (seiObjMask->m_hdr.m_maskIdLengthMinus1 + 1)) - 1));
+          readTokenValueAndValidate<uint32_t>(omi.auxSampleValue, failed, fic, cfgAuxSampleValueStr.c_str(), uint32_t(0), uint32_t((1 << (seiObjMask->m_hdr.m_maskSampleValueLengthMinus8 + 8)) - 1));
+          readTokenValue(omi.maskCancel, failed, fic, cfgMaskCancelStr.c_str());
+          if (!omi.maskCancel)
+          {
+            std::string cfgMaskBoundingBoxPresentFlagStr = "SEIOmiBoundingBoxPresentFlag[" + std::to_string(i) + "][" + std::to_string(j) + "]";
+            readTokenValue(omi.maskBoundingBoxPresentFlag, failed, fic, cfgMaskBoundingBoxPresentFlagStr.c_str());
+
+            if (omi.maskBoundingBoxPresentFlag)
+            {
+              std::string cfgMaskTopStr    = "SEIOmiMaskTop[" + std::to_string(i) + "][" + std::to_string(j) + "]";
+              std::string cfgMaskLeftStr   = "SEIOmiMaskLeft[" + std::to_string(i) + "][" + std::to_string(j) + "]";
+              std::string cfgMaskWidthStr  = "SEIOmiMaskWidth[" + std::to_string(i) + "][" + std::to_string(j) + "]";
+              std::string cfgMaskHeightStr = "SEIOmiMaskHeight[" + std::to_string(i) + "][" + std::to_string(j) + "]";
+              readTokenValueAndValidate(omi.maskTop, failed, fic, cfgMaskTopStr.c_str(), uint32_t(0), uint32_t(0xffff));
+              readTokenValueAndValidate(omi.maskLeft, failed, fic, cfgMaskLeftStr.c_str(), uint32_t(0), uint32_t(0xffff));
+              readTokenValueAndValidate(omi.maskWidth, failed, fic, cfgMaskWidthStr.c_str(), uint32_t(0),uint32_t(0xffff));
+              readTokenValueAndValidate(omi.maskHeight, failed, fic, cfgMaskHeightStr.c_str(), uint32_t(0),uint32_t(0xffff));
+            }
+
+            if (seiObjMask->m_hdr.m_maskConfidenceInfoPresentFlag)
+            {
+              std::string cfgMaskConfidenceStr = "SEIOmiMaskConfidence[" + std::to_string(i) + "][" + std::to_string(j) + "]";
+              readTokenValueAndValidate(omi.maskConfidence, failed, fic, cfgMaskConfidenceStr.c_str(), uint32_t(0), uint32_t((1 << (seiObjMask->m_hdr.m_maskConfidenceLengthMinus1 + 1)) - 1));
+            }
+
+            if (seiObjMask->m_hdr.m_maskDepthInfoPresentFlag)
+            {
+              std::string cfgMaskDepthStr = "SEIOmiMaskDepth[" + std::to_string(i) + "][" + std::to_string(j) + "]";
+              readTokenValueAndValidate(omi.maskDepth, failed, fic, cfgMaskDepthStr.c_str(), uint32_t(0), uint32_t((1 << (seiObjMask->m_hdr.m_maskDepthLengthMinus1 + 1)) - 1));
+            }
+
+            if (seiObjMask->m_hdr.m_maskLabelInfoPresentFlag)
+            {
+              std::string cfgMaskLabelStr = "SEIOmiMaskLabel[" + std::to_string(i) + "][" + std::to_string(j) + "]";
+              readTokenValue(omi.maskLabel, failed, fic, cfgMaskLabelStr.c_str());
+            }
+          }
+          objMaskInfoCnt++;
+        }
+      }
+    }
+  }
+}
+#endif
+
 bool SEIEncoder::initSEIAnnotatedRegions(SEIAnnotatedRegions* SEIAnnoReg, int currPOC)
 {
   assert(m_isInitialized);
@@ -965,6 +1100,38 @@ bool SEIEncoder::initSEIAnnotatedRegions(SEIAnnotatedRegions* SEIAnnoReg, int cu
   return true;
 }
 
+#if JVET_AI0153_OMI_SEI
+bool SEIEncoder::initSEIObjectMaskInfos(SEIObjectMaskInfos* SEIObjMask, int currPOC)
+{
+  CHECK(m_isInitialized == 0, "SEI is uninitialized");
+  CHECK(SEIObjMask == nullptr, "ObjectMaskInfo SEI is undefined");
+  if (!m_pcCfg->getObjectMaskInfoSEIFileRoot().empty())
+  {
+    bool        failed = false;
+    std::string ObjMaskSEIFileWithPoc(m_pcCfg->getObjectMaskInfoSEIFileRoot());
+    {
+      std::stringstream suffix;
+      suffix << "_" << currPOC << ".txt";
+      ObjMaskSEIFileWithPoc += suffix.str();
+    }
+    std::ifstream fic(ObjMaskSEIFileWithPoc.c_str());
+    if (!fic.good() || !fic.is_open())
+    {
+      std::cerr << "No Object Mask Informations SEI parameters file " << ObjMaskSEIFileWithPoc << " for POC " << currPOC
+                << std::endl;
+      return false;
+    }
+
+    readObjectMaskInfoSEI(fic, SEIObjMask, failed);
+    if (failed)
+    {
+      std::cerr << "Error while reading Object Mask Informations SEI parameters file '" << ObjMaskSEIFileWithPoc << "'" << std::endl;
+      exit(EXIT_FAILURE);
+    }
+  }
+  return true;
+}
+#endif
 
 void SEIEncoder::initSEIAlternativeTransferCharacteristics(SEIAlternativeTransferCharacteristics *seiAltTransCharacteristics)
 {
@@ -1093,6 +1260,9 @@ void SEIEncoder::initSEIScalabilityDimensionInfo(SEIScalabilityDimensionInfo *se
       sei->m_sdiViewIdLenMinus1 = m_pcCfg->getSdiSEIViewIdLenMinus1();
     }
     sei->m_sdiLayerId.resize(sei->m_sdiMaxLayersMinus1 + 1);
+#if JVET_AI0153_OMI_SEI
+    uint32_t associatedPrimaryLayerIdxCnt = 0;
+#endif
     for (int i = 0; i <= sei->m_sdiMaxLayersMinus1; i++)
     {
       sei->m_sdiLayerId[i] = m_pcCfg->getSdiSEILayerId(i);
@@ -1113,7 +1283,11 @@ void SEIEncoder::initSEIScalabilityDimensionInfo(SEIScalabilityDimensionInfo *se
           sei->m_sdiAssociatedPrimaryLayerIdx[i].resize(sei->m_sdiNumAssociatedPrimaryLayersMinus1[i] + 1);
           for (int j = 0; j <= sei->m_sdiNumAssociatedPrimaryLayersMinus1[i]; j++)
           {
+#if JVET_AI0153_OMI_SEI
+            sei->m_sdiAssociatedPrimaryLayerIdx[i][j] = m_pcCfg->getSdiSEIAssociatedPrimaryLayerIdx(associatedPrimaryLayerIdxCnt++);
+#else
             sei->m_sdiAssociatedPrimaryLayerIdx[i][j] = 0;
+#endif
           }
         }
       }
diff --git a/source/Lib/EncoderLib/SEIEncoder.h b/source/Lib/EncoderLib/SEIEncoder.h
index 6cb2ac6086..2f22e81a9e 100644
--- a/source/Lib/EncoderLib/SEIEncoder.h
+++ b/source/Lib/EncoderLib/SEIEncoder.h
@@ -93,6 +93,11 @@ public:
   void initSEISEIManifest(SEIManifest *seiSeiManifest, const SEIMessages &seiMessage);
   void initSEISEIPrefixIndication(SEIPrefixIndication *seiSeiPrefixIndications, const SEI *sei);
 
+#if JVET_AI0153_OMI_SEI
+  void readObjectMaskInfoSEI(std::istream& fic, SEIObjectMaskInfos* seiObjMask, bool& failed);
+  bool initSEIObjectMaskInfos(SEIObjectMaskInfos* sei, int currPOC);
+#endif
+
 #if JVET_AG2034_SPTI_SEI
   void initSEISourcePictureTimingInfo(SEISourcePictureTimingInfo* SEISourcePictureTimingInfo);
 #endif
diff --git a/source/Lib/EncoderLib/SEIwrite.cpp b/source/Lib/EncoderLib/SEIwrite.cpp
index fda2b6b8f3..2f0086fa2d 100644
--- a/source/Lib/EncoderLib/SEIwrite.cpp
+++ b/source/Lib/EncoderLib/SEIwrite.cpp
@@ -161,6 +161,11 @@ void SEIWriter::xWriteSEIpayloadData(OutputBitstream &bs, const SEI &sei, HRD &h
   case SEI::PayloadType::ANNOTATED_REGIONS:
     xWriteSEIAnnotatedRegions(*static_cast<const SEIAnnotatedRegions *>(&sei));
     break;
+#if JVET_AI0153_OMI_SEI
+  case SEI::PayloadType::OBJECT_MASK_INFO:
+    xWriteSEIObjectMaskInfos(*static_cast<const SEIObjectMaskInfos*>(&sei));
+    break;
+#endif
   case SEI::PayloadType::SEI_MANIFEST:
     CHECK((SEIPrefixIndicationIdx), "wrong SEI prefix indication message");
     xWriteSEISEIManifest(*static_cast<const SEIManifest *>(&sei));
@@ -899,6 +904,102 @@ void SEIWriter::xWriteSEIAnnotatedRegions(const SEIAnnotatedRegions &sei)
     }
   }
 }
+
+#if JVET_AI0153_OMI_SEI
+void SEIWriter::xWriteSEIObjectMaskInfos(const SEIObjectMaskInfos& sei)
+{
+  xWriteFlag(sei.m_hdr.m_cancelFlag, "omi_cancel_flag");
+  if (!sei.m_hdr.m_cancelFlag)
+  {
+    xWriteFlag(sei.m_hdr.m_persistenceFlag, "omi_persistence_flag");
+    xWriteUvlc((uint32_t) sei.m_hdr.m_numAuxPicLayerMinus1, "omi_num_aux_pic_layer_minus1");
+    xWriteUvlc((uint32_t) sei.m_hdr.m_maskIdLengthMinus1, "omi_mask_id_length_minus1");
+    xWriteUvlc((uint32_t) sei.m_hdr.m_maskSampleValueLengthMinus8, "omi_mask_sample_value_length_minus8");
+    xWriteFlag(sei.m_hdr.m_maskConfidenceInfoPresentFlag, "omi_mask_confidence_info_present_flag");
+    if (sei.m_hdr.m_maskConfidenceInfoPresentFlag)
+    {
+      CHECK((sei.m_hdr.m_maskConfidenceLengthMinus1 > 15 || sei.m_hdr.m_maskConfidenceLengthMinus1 < 0), "The range of omi_mask_confidence_length_minus1 must be [0, 15]");
+      xWriteCode((sei.m_hdr.m_maskConfidenceLengthMinus1), 4, "omi_mask_confidence_length_minus1");
+    }
+    xWriteFlag(sei.m_hdr.m_maskDepthInfoPresentFlag, "omi_mask_depth_info_present_flag");
+    if (sei.m_hdr.m_maskDepthInfoPresentFlag)
+    {
+      CHECK((sei.m_hdr.m_maskDepthLengthMinus1 > 15 || sei.m_hdr.m_maskDepthLengthMinus1 < 0), "The range of omi_mask_depth_length_minus1 must be [0, 15]");
+      xWriteCode((sei.m_hdr.m_maskDepthLengthMinus1), 4, "omi_mask_depth_length_minus1");
+    }
+    xWriteFlag(sei.m_hdr.m_maskLabelInfoPresentFlag, "omi_mask_label_info_present_flag");
+    if (sei.m_hdr.m_maskLabelInfoPresentFlag)
+    {
+      xWriteFlag(sei.m_hdr.m_maskLabelLanguagePresentFlag, "omi_mask_label_language_present_flag");
+      if (sei.m_hdr.m_maskLabelLanguagePresentFlag)
+      {
+        while (!isByteAligned())
+        {
+          xWriteFlag(0, "omi_bit_equal_to_zero");
+        }
+        CHECK(sei.m_hdr.m_maskLabelLanguage.size() > 255, "label oversize");
+        for (uint32_t m = 0; m < sei.m_hdr.m_maskLabelLanguage.size(); m++)
+        {
+          char ch = sei.m_hdr.m_maskLabelLanguage[m];
+          xWriteCode(ch, 8, "omi_mask_lable_language");
+        }
+        xWriteCode('\0', 8, "omi_mask_lable_language");
+      }
+    }
+
+    uint32_t maskCnt = 0;
+    for (uint32_t i = 0; i <= sei.m_hdr.m_numAuxPicLayerMinus1; i++)
+    {
+      xWriteFlag(sei.m_maskPicUpdateFlag[i], "omi_mask_pic_update_flag[i]");
+      if (sei.m_maskPicUpdateFlag[i])
+      {
+        xWriteUvlc((uint32_t) sei.m_numMaskInPicUpdate[i], "omi_num_mask_in_pic_update[i]");
+        for (uint32_t j = 0; j < sei.m_numMaskInPicUpdate[i]; j++)
+        {
+          xWriteCode(sei.m_objectMaskInfos[maskCnt].maskId, sei.m_hdr.m_maskIdLengthMinus1 + 1, "omi_mask_id[i][j]");
+          xWriteCode(sei.m_objectMaskInfos[maskCnt].auxSampleValue, sei.m_hdr.m_maskSampleValueLengthMinus8 + 8, "omi_aux_sample_value[i][j]");
+          xWriteFlag(sei.m_objectMaskInfos[maskCnt].maskCancel, "omi_mask_cancel[i][j]");
+          if (!sei.m_objectMaskInfos[maskCnt].maskCancel)
+          {
+            xWriteFlag(sei.m_objectMaskInfos[maskCnt].maskBoundingBoxPresentFlag, "omi_mask_bounding_box_present_flag[i][j]");
+            if (sei.m_objectMaskInfos[maskCnt].maskBoundingBoxPresentFlag)
+            {
+              xWriteCode((uint32_t) sei.m_objectMaskInfos[maskCnt].maskTop, 16, "omi_mask_top[i][j]");
+              xWriteCode((uint32_t) sei.m_objectMaskInfos[maskCnt].maskLeft, 16, "omi_mask_left[i][j]");
+              xWriteCode((uint32_t) sei.m_objectMaskInfos[maskCnt].maskWidth, 16, "omi_mask_width[i][j]");
+              xWriteCode((uint32_t) sei.m_objectMaskInfos[maskCnt].maskHeight, 16, "omi_mask_height[i][j]");
+            }
+            if (sei.m_hdr.m_maskConfidenceInfoPresentFlag)
+            {
+              xWriteCode(sei.m_objectMaskInfos[maskCnt].maskConfidence, sei.m_hdr.m_maskConfidenceLengthMinus1 + 1, "omi_mask_confidence[i][j]");
+            }
+            if (sei.m_hdr.m_maskDepthInfoPresentFlag)
+            {
+              xWriteCode(sei.m_objectMaskInfos[maskCnt].maskDepth, sei.m_hdr.m_maskDepthLengthMinus1 + 1, "omi_mask_depth[i][j]");
+            }
+            while (!isByteAligned())
+            {
+              xWriteFlag(0, "omi_bit_equal_to_zero");
+            }
+            if (sei.m_hdr.m_maskLabelInfoPresentFlag)
+            {
+              CHECK(sei.m_objectMaskInfos[maskCnt].maskLabel.size() > 255, "label oversize");
+              for (uint32_t m = 0; m < sei.m_objectMaskInfos[maskCnt].maskLabel.size(); m++)
+              {
+                char ch = sei.m_objectMaskInfos[maskCnt].maskLabel[m];
+                xWriteCode(ch, 8, "omi_mask_label");
+              }
+              xWriteCode('\0', 8, "omi_mask_label");
+            }
+          }
+          maskCnt++;
+        }
+      }
+    }
+  }
+}
+#endif
+
 void SEIWriter::xWriteByteAlign()
 {
   if( m_pcBitIf->getNumberOfWrittenBits() % 8 != 0)
diff --git a/source/Lib/EncoderLib/SEIwrite.h b/source/Lib/EncoderLib/SEIwrite.h
index f630c16710..82c5755a03 100644
--- a/source/Lib/EncoderLib/SEIwrite.h
+++ b/source/Lib/EncoderLib/SEIwrite.h
@@ -102,6 +102,9 @@ protected:
 
   void xWriteSEIColourTransformInfo(const SEIColourTransformInfo& sei);
   void xWriteSEIAnnotatedRegions                  (const SEIAnnotatedRegions& sei);
+#if JVET_AI0153_OMI_SEI
+  void xWriteSEIObjectMaskInfos(const SEIObjectMaskInfos& sei);
+#endif
   void xWriteSEIpayloadData(OutputBitstream &bs, const SEI &sei, HRD &hrd, const uint32_t temporalId,
                             int SEIPrefixIndicationIdx = 0);
   void xWriteSEIShutterInterval(const SEIShutterIntervalInfo& sei);
-- 
GitLab