diff mbox series

[FFmpeg-devel,3/7] lavc/hevc_ps: Add pps parse support for hevc scc extension

Message ID 1594311460-10498-4-git-send-email-linjie.fu@intel.com
State New
Headers show
Series HEVC native support for Screen content coding
Related show

Checks

Context Check Description
andriy/default pending
andriy/make success Make finished
andriy/make_fate success Make fate finished

Commit Message

Fu, Linjie July 9, 2020, 4:17 p.m. UTC
Signed-off-by: Linjie Fu <linjie.justin.fu@gmail.com>
---
 libavcodec/hevc_ps.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++--
 libavcodec/hevc_ps.h | 17 +++++++++++++++++
 2 files changed, 68 insertions(+), 2 deletions(-)
diff mbox series

Patch

diff --git a/libavcodec/hevc_ps.c b/libavcodec/hevc_ps.c
index 7610d3b..887b960 100644
--- a/libavcodec/hevc_ps.c
+++ b/libavcodec/hevc_ps.c
@@ -1388,6 +1388,45 @@  static int pps_range_extensions(GetBitContext *gb, AVCodecContext *avctx,
     return(0);
 }
 
+static int pps_scc_extensions(GetBitContext *gb, AVCodecContext *avctx,
+                                HEVCPPS *pps, HEVCSPS *sps) {
+    int num_comps;
+    int i, ret;
+
+    pps->pps_curr_pic_ref_enabled_flag = get_bits1(gb);
+    if (pps->residual_adaptive_colour_transform_enabled_flag = get_bits1(gb)) {
+        pps->pps_slice_act_qp_offsets_present_flag = get_bits1(gb);
+        pps->pps_act_y_qp_offset  = get_se_golomb_long(gb) - 5;
+        pps->pps_act_cb_qp_offset = get_se_golomb_long(gb) - 5;
+        pps->pps_act_cr_qp_offset = get_se_golomb_long(gb) - 3;
+
+#define CHECK_QP_OFFSET(name) (pps->pps_act_ ## name ## _qp_offset < -12 || \
+                               pps->pps_act_ ## name ## _qp_offset > 12)
+        ret = CHECK_QP_OFFSET(y) || CHECK_QP_OFFSET(cb) || CHECK_QP_OFFSET(cr);
+#undef CHECK_QP_OFFSET
+        if (ret) {
+            av_log(avctx, AV_LOG_ERROR,
+                   "PpsActQpOffsetY/Cb/Cr shall be in the range of [-12, 12].\n");
+            return AVERROR_INVALIDDATA;
+        }
+    }
+
+    if (pps->pps_palette_predictor_initializers_present_flag = get_bits1(gb)) {
+        if ((pps->pps_num_palette_predictor_initializers = get_ue_golomb_long(gb)) > 0) {
+            pps->monochrome_palette_flag = get_bits1(gb);
+            pps->luma_bit_depth_entry_minus8 = get_ue_golomb_long(gb);
+            if (!pps->monochrome_palette_flag)
+                pps->chroma_bit_depth_entry_minus8 = get_ue_golomb_long(gb);
+            num_comps = pps->monochrome_palette_flag ? 1 : 3;
+            for (int comp = 0; comp < num_comps; comp++)
+                for (i = 0; i < pps->pps_num_palette_predictor_initializers; i++)
+                    pps->pps_palette_predictor_initializer[comp][i] = get_ue_golomb_long(gb);
+        }
+    }
+
+    return 0;
+}
+
 static inline int setup_pps(AVCodecContext *avctx, GetBitContext *gb,
                             HEVCPPS *pps, HEVCSPS *sps)
 {
@@ -1740,12 +1779,22 @@  int ff_hevc_decode_nal_pps(GetBitContext *gb, AVCodecContext *avctx,
     pps->slice_header_extension_present_flag = get_bits1(gb);
 
     if (get_bits1(gb)) { // pps_extension_present_flag
-        pps->pps_range_extensions_flag = get_bits1(gb);
-        skip_bits(gb, 7); // pps_extension_7bits
+        pps->pps_range_extensions_flag     = get_bits1(gb);
+        pps->pps_multilayer_extension_flag = get_bits1(gb);
+        pps->pps_3d_extension_flag         = get_bits1(gb);
+        pps->pps_scc_extensions_flag       = get_bits1(gb);
+        skip_bits(gb, 4); // pps_extension_4bits
         if (sps->ptl.general_ptl.profile_idc == FF_PROFILE_HEVC_REXT && pps->pps_range_extensions_flag) {
             if ((ret = pps_range_extensions(gb, avctx, pps, sps)) < 0)
                 goto err;
         }
+        if (pps->pps_multilayer_extension_flag || pps->pps_3d_extension_flag)
+            av_log(avctx, AV_LOG_WARNING,
+                   "multilayer_extension or 3d_extension not yet implemented\n");
+        if (sps->ptl.general_ptl.profile_idc == FF_PROFILE_HEVC_SCC && pps->pps_scc_extensions_flag) {
+            if ((ret = pps_scc_extensions(gb, avctx, pps, sps)) < 0)
+                goto err;
+        }
     }
 
     ret = setup_pps(avctx, gb, pps, sps);
diff --git a/libavcodec/hevc_ps.h b/libavcodec/hevc_ps.h
index 1501811..0cfac43 100644
--- a/libavcodec/hevc_ps.h
+++ b/libavcodec/hevc_ps.h
@@ -312,6 +312,9 @@  typedef struct HEVCPPS {
     uint8_t slice_header_extension_present_flag;
     uint8_t log2_max_transform_skip_block_size;
     uint8_t pps_range_extensions_flag;
+    uint8_t pps_multilayer_extension_flag;
+    uint8_t pps_3d_extension_flag;
+    uint8_t pps_scc_extensions_flag;
     uint8_t cross_component_prediction_enabled_flag;
     uint8_t chroma_qp_offset_list_enabled_flag;
     uint8_t diff_cu_chroma_qp_offset_depth;
@@ -321,6 +324,20 @@  typedef struct HEVCPPS {
     uint8_t log2_sao_offset_scale_luma;
     uint8_t log2_sao_offset_scale_chroma;
 
+    // Scc extension parameters
+    uint8_t pps_curr_pic_ref_enabled_flag;
+    uint8_t residual_adaptive_colour_transform_enabled_flag;
+    uint8_t pps_slice_act_qp_offsets_present_flag;
+    int8_t  pps_act_y_qp_offset;  // _plus5
+    int8_t  pps_act_cb_qp_offset; // _plus5
+    int8_t  pps_act_cr_qp_offset; // _plus3
+    uint8_t pps_palette_predictor_initializers_present_flag;
+    uint8_t pps_num_palette_predictor_initializers;
+    uint8_t monochrome_palette_flag;
+    uint8_t luma_bit_depth_entry_minus8;
+    uint8_t chroma_bit_depth_entry_minus8;
+    uint8_t pps_palette_predictor_initializer[3][HEVC_MAX_PALETTE_PREDICTOR_SIZE];
+
     // Inferred parameters
     unsigned int *column_width;  ///< ColumnWidth
     unsigned int *row_height;    ///< RowHeight