diff mbox series

[FFmpeg-devel,2/7] lavc/hevc_ps: Add sps parse support for HEVC SCC extension syntax

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

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
According to 7.3.2.2.3 in T-REC-H.265-201911.

Signed-off-by: Linjie Fu <linjie.justin.fu@gmail.com>
---
 libavcodec/hevc.h    |  3 +++
 libavcodec/hevc_ps.c | 32 +++++++++++++++++++++++++++++---
 libavcodec/hevc_ps.h | 15 +++++++++++++++
 3 files changed, 47 insertions(+), 3 deletions(-)

Comments

James Almer July 9, 2020, 4:51 p.m. UTC | #1
On 7/9/2020 1:17 PM, Linjie Fu wrote:
> According to 7.3.2.2.3 in T-REC-H.265-201911.
> 
> Signed-off-by: Linjie Fu <linjie.justin.fu@gmail.com>
> ---
>  libavcodec/hevc.h    |  3 +++
>  libavcodec/hevc_ps.c | 32 +++++++++++++++++++++++++++++---
>  libavcodec/hevc_ps.h | 15 +++++++++++++++
>  3 files changed, 47 insertions(+), 3 deletions(-)
> 
> diff --git a/libavcodec/hevc.h b/libavcodec/hevc.h
> index 1804755..6b454a7 100644
> --- a/libavcodec/hevc.h
> +++ b/libavcodec/hevc.h
> @@ -154,6 +154,9 @@ enum {
>      // get near that, though, so set a lower limit here with the maximum
>      // possible value for 4K video (at most 135 16x16 Ctb rows).
>      HEVC_MAX_ENTRY_POINT_OFFSETS = HEVC_MAX_TILE_COLUMNS * 135,
> +
> +    // A.3.7: Screen content coding extensions
> +    HEVC_MAX_PALETTE_PREDICTOR_SIZE = 128,
>  };
>  
>  
> diff --git a/libavcodec/hevc_ps.c b/libavcodec/hevc_ps.c
> index 584e2ba..7610d3b 100644
> --- a/libavcodec/hevc_ps.c
> +++ b/libavcodec/hevc_ps.c
> @@ -909,7 +909,7 @@ int ff_hevc_parse_sps(HEVCSPS *sps, GetBitContext *gb, unsigned int *sps_id,
>      HEVCWindow *ow;
>      int ret = 0;
>      int log2_diff_max_min_transform_block_size;
> -    int bit_depth_chroma, start, vui_present, sublayer_ordering_info;
> +    int bit_depth_chroma, start, vui_present, sublayer_ordering_info, num_comps;
>      int i;
>  
>      // Coded parameters
> @@ -1130,8 +1130,11 @@ int ff_hevc_parse_sps(HEVCSPS *sps, GetBitContext *gb, unsigned int *sps_id,
>          decode_vui(gb, avctx, apply_defdispwin, sps);
>  
>      if (get_bits1(gb)) { // sps_extension_flag
> -        sps->sps_range_extension_flag = get_bits1(gb);
> -        skip_bits(gb, 7); //sps_extension_7bits = get_bits(gb, 7);
> +        sps->sps_range_extension_flag      = get_bits1(gb);
> +        sps->sps_multilayer_extension_flag = get_bits1(gb);
> +        sps->sps_3d_extension_flag         = get_bits1(gb);
> +        sps->sps_scc_extension_flag        = get_bits1(gb);
> +        skip_bits(gb, 4); //sps_extension_4bits = get_bits(gb, 4);
>          if (sps->sps_range_extension_flag) {
>              sps->transform_skip_rotation_enabled_flag = get_bits1(gb);
>              sps->transform_skip_context_enabled_flag  = get_bits1(gb);
> @@ -1157,6 +1160,29 @@ int ff_hevc_parse_sps(HEVCSPS *sps, GetBitContext *gb, unsigned int *sps_id,
>                  av_log(avctx, AV_LOG_WARNING,
>                     "cabac_bypass_alignment_enabled_flag not yet implemented\n");
>          }
> +        if (sps->sps_multilayer_extension_flag || sps->sps_3d_extension_flag)
> +            av_log(avctx, AV_LOG_WARNING,
> +                   "multilayer_extension or 3d_extension not yet implemented\n");
> +
> +        if (sps->sps_scc_extension_flag) {
> +            sps->sps_curr_pic_ref_enabled_flag = get_bits1(gb);
> +            sps->palette_mode_enabled_flag     = get_bits1(gb);
> +            if (sps->palette_mode_enabled_flag) {
> +                sps->palette_max_size = get_ue_golomb_long(gb);
> +                sps->delta_palette_max_predictor_size = get_ue_golomb_long(gb);
> +                sps->sps_palette_predictor_initializers_present_flag = get_bits1(gb);
> +
> +                if (sps->sps_palette_predictor_initializers_present_flag) {
> +                    sps->sps_num_palette_predictor_initializers_minus1 = get_ue_golomb_long(gb);
> +                    num_comps = sps->chroma_format_idc == 0 ? 1 : 3;
> +                    for (int comp = 0; comp < num_comps; comp++)
> +                        for (i = 0; i <= sps->sps_num_palette_predictor_initializers_minus1; i++)
> +                            sps->sps_palette_predictor_initializer[comp][i] = get_ue_golomb_long(gb);

This isn't an ue value. Its length is a fixed value (each plane's
bitdepth, afaics).

> +                }
> +            }
> +            sps->motion_vector_resolution_control_idc   = get_bits(gb, 2);
> +            sps->intra_boundary_filtering_disabled_flag = get_bits1(gb);
> +        }
>      }
>      if (apply_defdispwin) {
>          sps->output_window.left_offset   += sps->vui.def_disp_win.left_offset;
> diff --git a/libavcodec/hevc_ps.h b/libavcodec/hevc_ps.h
> index 2a1bbf6..1501811 100644
> --- a/libavcodec/hevc_ps.h
> +++ b/libavcodec/hevc_ps.h
> @@ -223,6 +223,21 @@ typedef struct HEVCSPS {
>      int persistent_rice_adaptation_enabled_flag;
>      int cabac_bypass_alignment_enabled_flag;
>  
> +    // not yet implemented
> +    int sps_multilayer_extension_flag;
> +    int sps_3d_extension_flag;
> +
> +    int sps_scc_extension_flag;
> +    int sps_curr_pic_ref_enabled_flag;
> +    int palette_mode_enabled_flag;
> +    int palette_max_size;
> +    int delta_palette_max_predictor_size;
> +    int sps_palette_predictor_initializers_present_flag;
> +    int sps_num_palette_predictor_initializers_minus1;
> +    int sps_palette_predictor_initializer[3][HEVC_MAX_PALETTE_PREDICTOR_SIZE];
> +    int motion_vector_resolution_control_idc;
> +    int intra_boundary_filtering_disabled_flag;
> +
>      ///< coded frame dimension in various units
>      int width;
>      int height;
>
Linjie Fu July 9, 2020, 5:35 p.m. UTC | #2
On Fri, Jul 10, 2020 at 12:54 AM James Almer <jamrial@gmail.com> wrote:
>
> On 7/9/2020 1:51 PM, James Almer wrote:
> > On 7/9/2020 1:17 PM, Linjie Fu wrote:
> >> According to 7.3.2.2.3 in T-REC-H.265-201911.
> >>
> >> Signed-off-by: Linjie Fu <linjie.justin.fu@gmail.com>
> >> ---
> >>  libavcodec/hevc.h    |  3 +++
> >>  libavcodec/hevc_ps.c | 32 +++++++++++++++++++++++++++++---
> >>  libavcodec/hevc_ps.h | 15 +++++++++++++++
> >>  3 files changed, 47 insertions(+), 3 deletions(-)
> >>
> >> diff --git a/libavcodec/hevc.h b/libavcodec/hevc.h
> >> index 1804755..6b454a7 100644
> >> --- a/libavcodec/hevc.h
> >> +++ b/libavcodec/hevc.h
> >> @@ -154,6 +154,9 @@ enum {
> >>      // get near that, though, so set a lower limit here with the maximum
> >>      // possible value for 4K video (at most 135 16x16 Ctb rows).
> >>      HEVC_MAX_ENTRY_POINT_OFFSETS = HEVC_MAX_TILE_COLUMNS * 135,
> >> +
> >> +    // A.3.7: Screen content coding extensions
> >> +    HEVC_MAX_PALETTE_PREDICTOR_SIZE = 128,
> >>  };
> >>
> >>
> >> diff --git a/libavcodec/hevc_ps.c b/libavcodec/hevc_ps.c
> >> index 584e2ba..7610d3b 100644
> >> --- a/libavcodec/hevc_ps.c
> >> +++ b/libavcodec/hevc_ps.c
> >> @@ -909,7 +909,7 @@ int ff_hevc_parse_sps(HEVCSPS *sps, GetBitContext *gb, unsigned int *sps_id,
> >>      HEVCWindow *ow;
> >>      int ret = 0;
> >>      int log2_diff_max_min_transform_block_size;
> >> -    int bit_depth_chroma, start, vui_present, sublayer_ordering_info;
> >> +    int bit_depth_chroma, start, vui_present, sublayer_ordering_info, num_comps;
> >>      int i;
> >>
> >>      // Coded parameters
> >> @@ -1130,8 +1130,11 @@ int ff_hevc_parse_sps(HEVCSPS *sps, GetBitContext *gb, unsigned int *sps_id,
> >>          decode_vui(gb, avctx, apply_defdispwin, sps);
> >>
> >>      if (get_bits1(gb)) { // sps_extension_flag
> >> -        sps->sps_range_extension_flag = get_bits1(gb);
> >> -        skip_bits(gb, 7); //sps_extension_7bits = get_bits(gb, 7);
> >> +        sps->sps_range_extension_flag      = get_bits1(gb);
> >> +        sps->sps_multilayer_extension_flag = get_bits1(gb);
> >> +        sps->sps_3d_extension_flag         = get_bits1(gb);
> >> +        sps->sps_scc_extension_flag        = get_bits1(gb);
> >> +        skip_bits(gb, 4); //sps_extension_4bits = get_bits(gb, 4);
> >>          if (sps->sps_range_extension_flag) {
> >>              sps->transform_skip_rotation_enabled_flag = get_bits1(gb);
> >>              sps->transform_skip_context_enabled_flag  = get_bits1(gb);
> >> @@ -1157,6 +1160,29 @@ int ff_hevc_parse_sps(HEVCSPS *sps, GetBitContext *gb, unsigned int *sps_id,
> >>                  av_log(avctx, AV_LOG_WARNING,
> >>                     "cabac_bypass_alignment_enabled_flag not yet implemented\n");
> >>          }
> >> +        if (sps->sps_multilayer_extension_flag || sps->sps_3d_extension_flag)
> >> +            av_log(avctx, AV_LOG_WARNING,
> >> +                   "multilayer_extension or 3d_extension not yet implemented\n");
>
> Also, you can't just ignore these. If you don't parse both, you'll be
> reading the wrong bits for SCC.
>
> Either add support for these two, or return AVERROR_PATCHWELCOME. Same
> for PPS.

Ah, should have noticed this.
Will fix, thx.

> >> +
> >> +        if (sps->sps_scc_extension_flag) {
> >> +            sps->sps_curr_pic_ref_enabled_flag = get_bits1(gb);
> >> +            sps->palette_mode_enabled_flag     = get_bits1(gb);
> >> +            if (sps->palette_mode_enabled_flag) {
> >> +                sps->palette_max_size = get_ue_golomb_long(gb);
> >> +                sps->delta_palette_max_predictor_size = get_ue_golomb_long(gb);
> >> +                sps->sps_palette_predictor_initializers_present_flag = get_bits1(gb);
> >> +
> >> +                if (sps->sps_palette_predictor_initializers_present_flag) {
> >> +                    sps->sps_num_palette_predictor_initializers_minus1 = get_ue_golomb_long(gb);
> >> +                    num_comps = sps->chroma_format_idc == 0 ? 1 : 3;
> >> +                    for (int comp = 0; comp < num_comps; comp++)
> >> +                        for (i = 0; i <= sps->sps_num_palette_predictor_initializers_minus1; i++)
> >> +                            sps->sps_palette_predictor_initializer[comp][i] = get_ue_golomb_long(gb);
> >
> > This isn't an ue value. Its length is a fixed value (each plane's
> > bitdepth, afaics).
> >
It's u(v), shall be in the range of 0 to (1 << BitDepth) - 1, inclusive, thx.

- Linjie
diff mbox series

Patch

diff --git a/libavcodec/hevc.h b/libavcodec/hevc.h
index 1804755..6b454a7 100644
--- a/libavcodec/hevc.h
+++ b/libavcodec/hevc.h
@@ -154,6 +154,9 @@  enum {
     // get near that, though, so set a lower limit here with the maximum
     // possible value for 4K video (at most 135 16x16 Ctb rows).
     HEVC_MAX_ENTRY_POINT_OFFSETS = HEVC_MAX_TILE_COLUMNS * 135,
+
+    // A.3.7: Screen content coding extensions
+    HEVC_MAX_PALETTE_PREDICTOR_SIZE = 128,
 };
 
 
diff --git a/libavcodec/hevc_ps.c b/libavcodec/hevc_ps.c
index 584e2ba..7610d3b 100644
--- a/libavcodec/hevc_ps.c
+++ b/libavcodec/hevc_ps.c
@@ -909,7 +909,7 @@  int ff_hevc_parse_sps(HEVCSPS *sps, GetBitContext *gb, unsigned int *sps_id,
     HEVCWindow *ow;
     int ret = 0;
     int log2_diff_max_min_transform_block_size;
-    int bit_depth_chroma, start, vui_present, sublayer_ordering_info;
+    int bit_depth_chroma, start, vui_present, sublayer_ordering_info, num_comps;
     int i;
 
     // Coded parameters
@@ -1130,8 +1130,11 @@  int ff_hevc_parse_sps(HEVCSPS *sps, GetBitContext *gb, unsigned int *sps_id,
         decode_vui(gb, avctx, apply_defdispwin, sps);
 
     if (get_bits1(gb)) { // sps_extension_flag
-        sps->sps_range_extension_flag = get_bits1(gb);
-        skip_bits(gb, 7); //sps_extension_7bits = get_bits(gb, 7);
+        sps->sps_range_extension_flag      = get_bits1(gb);
+        sps->sps_multilayer_extension_flag = get_bits1(gb);
+        sps->sps_3d_extension_flag         = get_bits1(gb);
+        sps->sps_scc_extension_flag        = get_bits1(gb);
+        skip_bits(gb, 4); //sps_extension_4bits = get_bits(gb, 4);
         if (sps->sps_range_extension_flag) {
             sps->transform_skip_rotation_enabled_flag = get_bits1(gb);
             sps->transform_skip_context_enabled_flag  = get_bits1(gb);
@@ -1157,6 +1160,29 @@  int ff_hevc_parse_sps(HEVCSPS *sps, GetBitContext *gb, unsigned int *sps_id,
                 av_log(avctx, AV_LOG_WARNING,
                    "cabac_bypass_alignment_enabled_flag not yet implemented\n");
         }
+        if (sps->sps_multilayer_extension_flag || sps->sps_3d_extension_flag)
+            av_log(avctx, AV_LOG_WARNING,
+                   "multilayer_extension or 3d_extension not yet implemented\n");
+
+        if (sps->sps_scc_extension_flag) {
+            sps->sps_curr_pic_ref_enabled_flag = get_bits1(gb);
+            sps->palette_mode_enabled_flag     = get_bits1(gb);
+            if (sps->palette_mode_enabled_flag) {
+                sps->palette_max_size = get_ue_golomb_long(gb);
+                sps->delta_palette_max_predictor_size = get_ue_golomb_long(gb);
+                sps->sps_palette_predictor_initializers_present_flag = get_bits1(gb);
+
+                if (sps->sps_palette_predictor_initializers_present_flag) {
+                    sps->sps_num_palette_predictor_initializers_minus1 = get_ue_golomb_long(gb);
+                    num_comps = sps->chroma_format_idc == 0 ? 1 : 3;
+                    for (int comp = 0; comp < num_comps; comp++)
+                        for (i = 0; i <= sps->sps_num_palette_predictor_initializers_minus1; i++)
+                            sps->sps_palette_predictor_initializer[comp][i] = get_ue_golomb_long(gb);
+                }
+            }
+            sps->motion_vector_resolution_control_idc   = get_bits(gb, 2);
+            sps->intra_boundary_filtering_disabled_flag = get_bits1(gb);
+        }
     }
     if (apply_defdispwin) {
         sps->output_window.left_offset   += sps->vui.def_disp_win.left_offset;
diff --git a/libavcodec/hevc_ps.h b/libavcodec/hevc_ps.h
index 2a1bbf6..1501811 100644
--- a/libavcodec/hevc_ps.h
+++ b/libavcodec/hevc_ps.h
@@ -223,6 +223,21 @@  typedef struct HEVCSPS {
     int persistent_rice_adaptation_enabled_flag;
     int cabac_bypass_alignment_enabled_flag;
 
+    // not yet implemented
+    int sps_multilayer_extension_flag;
+    int sps_3d_extension_flag;
+
+    int sps_scc_extension_flag;
+    int sps_curr_pic_ref_enabled_flag;
+    int palette_mode_enabled_flag;
+    int palette_max_size;
+    int delta_palette_max_predictor_size;
+    int sps_palette_predictor_initializers_present_flag;
+    int sps_num_palette_predictor_initializers_minus1;
+    int sps_palette_predictor_initializer[3][HEVC_MAX_PALETTE_PREDICTOR_SIZE];
+    int motion_vector_resolution_control_idc;
+    int intra_boundary_filtering_disabled_flag;
+
     ///< coded frame dimension in various units
     int width;
     int height;