diff mbox series

[FFmpeg-devel,v5,01/10] cbs_h2645: refact, use cbs_h2645_replace_ps to replace cbs_h26*_replace_*ps

Message ID 20210211143611.5663-2-nuomi2021@gmail.com
State Superseded
Headers show
Series add vvc raw demuxer, muxer, parser, metadata bsf | expand

Checks

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

Commit Message

Nuo Mi Feb. 11, 2021, 2:36 p.m. UTC
From: Mark Thompson <sw@jkqxz.net>

---
 libavcodec/cbs_h2645.c | 171 +++++++++++++++++++++++++++++++----------
 1 file changed, 130 insertions(+), 41 deletions(-)

Comments

Andreas Rheinhardt Feb. 14, 2021, 7:45 p.m. UTC | #1
Nuo Mi:
> From: Mark Thompson <sw@jkqxz.net>
> 
> ---
>  libavcodec/cbs_h2645.c | 171 +++++++++++++++++++++++++++++++----------
>  1 file changed, 130 insertions(+), 41 deletions(-)
> 
> diff --git a/libavcodec/cbs_h2645.c b/libavcodec/cbs_h2645.c
> index 6005d46e0d..36212d1da6 100644
> --- a/libavcodec/cbs_h2645.c
> +++ b/libavcodec/cbs_h2645.c
> @@ -661,38 +661,127 @@ static int cbs_h2645_split_fragment(CodedBitstreamContext *ctx,
>      return 0;
>  }
>  
> -#define cbs_h2645_replace_ps(h26n, ps_name, ps_var, id_element) \
> -static int cbs_h26 ## h26n ## _replace_ ## ps_var(CodedBitstreamContext *ctx, \
> -                                                  CodedBitstreamUnit *unit)  \
> -{ \
> -    CodedBitstreamH26 ## h26n ## Context *priv = ctx->priv_data; \
> -    H26 ## h26n ## Raw ## ps_name *ps_var = unit->content; \
> -    unsigned int id = ps_var->id_element; \
> -    int err; \
> -    if (id >= FF_ARRAY_ELEMS(priv->ps_var)) { \
> -        av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid " #ps_name \
> -               " id : %d.\n", id); \
> -        return AVERROR_INVALIDDATA; \
> -    } \
> -    err = ff_cbs_make_unit_refcounted(ctx, unit); \
> -    if (err < 0) \
> -        return err; \
> -    if (priv->ps_var[id] == priv->active_ ## ps_var) \
> -        priv->active_ ## ps_var = NULL ; \
> -    av_buffer_unref(&priv->ps_var ## _ref[id]); \
> -    av_assert0(unit->content_ref); \
> -    priv->ps_var ## _ref[id] = av_buffer_ref(unit->content_ref); \
> -    if (!priv->ps_var ## _ref[id]) \
> -        return AVERROR(ENOMEM); \
> -    priv->ps_var[id] = (H26 ## h26n ## Raw ## ps_name *)priv->ps_var ## _ref[id]->data; \
> -    return 0; \
> -}
> +static int cbs_h2645_replace_ps(CodedBitstreamContext *ctx,
> +                                CodedBitstreamUnit *unit)
> +{
> +    typedef struct {
> +        int nal_unit_type;
> +        int max_count;
> +        const char *name;

If this were a char name[4], these structs could be put in .rodata
instead of .data (or .data.rel.ro) when using position-independent code.

> +        size_t id_offset;
> +        size_t ref_array_offset;
> +        size_t ptr_array_offset;
> +        size_t active_offset;
> +    } PSType;
> +
> +    static const PSType h264_ps_types[] = {
> +        {
> +            H264_NAL_SPS,
> +            H264_MAX_SPS_COUNT,
> +            "SPS",
> +            offsetof(H264RawSPS, seq_parameter_set_id),
> +            offsetof(CodedBitstreamH264Context, sps_ref),
> +            offsetof(CodedBitstreamH264Context, sps),
> +            offsetof(CodedBitstreamH264Context, active_sps),
> +        },
> +        {
> +            H264_NAL_PPS,
> +            H264_MAX_PPS_COUNT,
> +            "PPS",
> +            offsetof(H264RawPPS, pic_parameter_set_id),
> +            offsetof(CodedBitstreamH264Context, pps_ref),
> +            offsetof(CodedBitstreamH264Context, pps),
> +            offsetof(CodedBitstreamH264Context, active_pps),
> +        },
> +    };
> +
> +    static const PSType h265_ps_types[] = {
> +        {
> +            HEVC_NAL_VPS,
> +            HEVC_MAX_VPS_COUNT,
> +            "VPS",
> +            offsetof(H265RawVPS, vps_video_parameter_set_id),
> +            offsetof(CodedBitstreamH265Context, vps_ref),
> +            offsetof(CodedBitstreamH265Context, vps),
> +            offsetof(CodedBitstreamH265Context, active_vps),
> +        },
> +        {
> +            HEVC_NAL_SPS,
> +            HEVC_MAX_SPS_COUNT,
> +            "SPS",
> +            offsetof(H265RawSPS, sps_seq_parameter_set_id),
> +            offsetof(CodedBitstreamH265Context, sps_ref),
> +            offsetof(CodedBitstreamH265Context, sps),
> +            offsetof(CodedBitstreamH265Context, active_sps),
> +        },
> +        {
> +            HEVC_NAL_PPS,
> +            HEVC_MAX_PPS_COUNT,
> +            "PPS",
> +            offsetof(H265RawPPS, pps_pic_parameter_set_id),
> +            offsetof(CodedBitstreamH265Context, pps_ref),
> +            offsetof(CodedBitstreamH265Context, pps),
> +            offsetof(CodedBitstreamH265Context, active_pps),
> +        },
> +    };
>  
> -cbs_h2645_replace_ps(4, SPS, sps, seq_parameter_set_id)
> -cbs_h2645_replace_ps(4, PPS, pps, pic_parameter_set_id)
> -cbs_h2645_replace_ps(5, VPS, vps, vps_video_parameter_set_id)
> -cbs_h2645_replace_ps(5, SPS, sps, sps_seq_parameter_set_id)
> -cbs_h2645_replace_ps(5, PPS, pps, pps_pic_parameter_set_id)
> +    const PSType *ps_type;
> +    AVBufferRef **ref_array;
> +    void **ptr_array;
> +    void **active;
> +    int err, id, i, nb_ps_types;
> +
> +    switch (ctx->codec->codec_id) {
> +    case AV_CODEC_ID_H264:
> +        ps_type     = h264_ps_types;
> +        nb_ps_types = FF_ARRAY_ELEMS(h264_ps_types);
> +        break;
> +    case AV_CODEC_ID_H265:
> +        ps_type     = h265_ps_types;
> +        nb_ps_types = FF_ARRAY_ELEMS(h265_ps_types);
> +        break;
> +    default:
> +        av_assert0(0);
> +    }
> +
> +    for (i = 0; i < nb_ps_types; i++) {
> +        if (ps_type->nal_unit_type == unit->type)
> +            break;
> +        ++ps_type;
> +    }
> +    av_assert0(i < nb_ps_types);
> +
> +    id = *((uint8_t*)unit->content + ps_type->id_offset);
> +
> +    if (id >= ps_type->max_count) {
> +        av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid %s id: %d.\n",
> +               ps_type->name, id);
> +        return AVERROR_INVALIDDATA;
> +    }
> +
> +    err = ff_cbs_make_unit_refcounted(ctx, unit);
> +    if (err < 0)
> +        return err;
> +
> +    ref_array =
> +         (AVBufferRef**)((uint8_t*)ctx->priv_data + ps_type->ref_array_offset);
> +    ptr_array = (void**)((uint8_t*)ctx->priv_data + ps_type->ptr_array_offset);
> +    active    = (void**)((uint8_t*)ctx->priv_data + ps_type->active_offset);
> +
> +    if (ptr_array[id] == *active) {
> +        // The old active parameter set is being overwritten, so it can't
> +        // be active after this point.
> +        *active = NULL;
> +    }
> +    av_buffer_unref(&ref_array[id]);
> +
> +    ref_array[id] = av_buffer_ref(unit->content_ref);
> +    if (!ref_array[id])
> +        return AVERROR(ENOMEM);
> +    ptr_array[id] = ref_array[id]->data;
> +
> +    return 0;
> +}
>  
>  static int cbs_h264_read_nal_unit(CodedBitstreamContext *ctx,
>                                    CodedBitstreamUnit *unit)
> @@ -717,7 +806,7 @@ static int cbs_h264_read_nal_unit(CodedBitstreamContext *ctx,
>              if (err < 0)
>                  return err;
>  
> -            err = cbs_h264_replace_sps(ctx, unit);
> +            err = cbs_h2645_replace_ps(ctx, unit);
>              if (err < 0)
>                  return err;
>          }
> @@ -739,7 +828,7 @@ static int cbs_h264_read_nal_unit(CodedBitstreamContext *ctx,
>              if (err < 0)
>                  return err;
>  
> -            err = cbs_h264_replace_pps(ctx, unit);
> +            err = cbs_h2645_replace_ps(ctx, unit);
>              if (err < 0)
>                  return err;
>          }
> @@ -836,7 +925,7 @@ static int cbs_h265_read_nal_unit(CodedBitstreamContext *ctx,
>              if (err < 0)
>                  return err;
>  
> -            err = cbs_h265_replace_vps(ctx, unit);
> +            err = cbs_h2645_replace_ps(ctx, unit);
>              if (err < 0)
>                  return err;
>          }
> @@ -849,7 +938,7 @@ static int cbs_h265_read_nal_unit(CodedBitstreamContext *ctx,
>              if (err < 0)
>                  return err;
>  
> -            err = cbs_h265_replace_sps(ctx, unit);
> +            err = cbs_h2645_replace_ps(ctx, unit);
>              if (err < 0)
>                  return err;
>          }
> @@ -863,7 +952,7 @@ static int cbs_h265_read_nal_unit(CodedBitstreamContext *ctx,
>              if (err < 0)
>                  return err;
>  
> -            err = cbs_h265_replace_pps(ctx, unit);
> +            err = cbs_h2645_replace_ps(ctx, unit);
>              if (err < 0)
>                  return err;
>          }
> @@ -1007,7 +1096,7 @@ static int cbs_h264_write_nal_unit(CodedBitstreamContext *ctx,
>              if (err < 0)
>                  return err;
>  
> -            err = cbs_h264_replace_sps(ctx, unit);
> +            err = cbs_h2645_replace_ps(ctx, unit);
>              if (err < 0)
>                  return err;
>          }
> @@ -1031,7 +1120,7 @@ static int cbs_h264_write_nal_unit(CodedBitstreamContext *ctx,
>              if (err < 0)
>                  return err;
>  
> -            err = cbs_h264_replace_pps(ctx, unit);
> +            err = cbs_h2645_replace_ps(ctx, unit);
>              if (err < 0)
>                  return err;
>          }
> @@ -1124,7 +1213,7 @@ static int cbs_h265_write_nal_unit(CodedBitstreamContext *ctx,
>              if (err < 0)
>                  return err;
>  
> -            err = cbs_h265_replace_vps(ctx, unit);
> +            err = cbs_h2645_replace_ps(ctx, unit);
>              if (err < 0)
>                  return err;
>          }
> @@ -1138,7 +1227,7 @@ static int cbs_h265_write_nal_unit(CodedBitstreamContext *ctx,
>              if (err < 0)
>                  return err;
>  
> -            err = cbs_h265_replace_sps(ctx, unit);
> +            err = cbs_h2645_replace_ps(ctx, unit);
>              if (err < 0)
>                  return err;
>          }
> @@ -1152,7 +1241,7 @@ static int cbs_h265_write_nal_unit(CodedBitstreamContext *ctx,
>              if (err < 0)
>                  return err;
>  
> -            err = cbs_h265_replace_pps(ctx, unit);
> +            err = cbs_h2645_replace_ps(ctx, unit);
>              if (err < 0)
>                  return err;
>          }
>
Nuo Mi Feb. 15, 2021, 7:16 a.m. UTC | #2
On Mon, Feb 15, 2021 at 3:45 AM Andreas Rheinhardt <
andreas.rheinhardt@gmail.com> wrote:

> Nuo Mi:
> > From: Mark Thompson <sw@jkqxz.net>
> >
> >
> > -}
> > +static int cbs_h2645_replace_ps(CodedBitstreamContext *ctx,
> > +                                CodedBitstreamUnit *unit)
> > +{
> > +    typedef struct {
> > +        int nal_unit_type;
> > +        int max_count;
> > +        const char *name;
>
> If this were a char name[4], these structs could be put in .rodata
> instead of .data (or .data.rel.ro) when using position-independent code.
>
thanks for the suggestion.
What's the benifite for this?
thanks

>
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
Andreas Rheinhardt Feb. 15, 2021, 12:32 p.m. UTC | #3
Nuo Mi:
> On Mon, Feb 15, 2021 at 3:45 AM Andreas Rheinhardt <
> andreas.rheinhardt@gmail.com> wrote:
> 
>> Nuo Mi:
>>> From: Mark Thompson <sw@jkqxz.net>
>>>
>>>
>>> -}
>>> +static int cbs_h2645_replace_ps(CodedBitstreamContext *ctx,
>>> +                                CodedBitstreamUnit *unit)
>>> +{
>>> +    typedef struct {
>>> +        int nal_unit_type;
>>> +        int max_count;
>>> +        const char *name;
>>
>> If this were a char name[4], these structs could be put in .rodata
>> instead of .data (or .data.rel.ro) when using position-independent code.
>>
> thanks for the suggestion.
> What's the benifite for this?
> thanks
> 
When one uses position-independent code, the static linker does not know
the runtime address of the strings here, because their position is not
known until runtime. Therefore the static linker has to create
relocations for them which means that it tells the runtime linker that
it should patch up the char * pointer above to point to the real
(offsetted) address of the relevant string. For platforms other than
Windows, these relocations are expensive (see [1]) and the resultant
pages are dirty and can't be shared between processes; furthermore this
process isn't done in a lazy manner, so that even someone who never uses
cbs_h2645 (or cbs at all) will have the dirty pages from the above as
soon as libavcodec is loaded.

- Andreas

[1]:
https://chromium.googlesource.com/chromium/src/+/master/docs/native_relocations.md
diff mbox series

Patch

diff --git a/libavcodec/cbs_h2645.c b/libavcodec/cbs_h2645.c
index 6005d46e0d..36212d1da6 100644
--- a/libavcodec/cbs_h2645.c
+++ b/libavcodec/cbs_h2645.c
@@ -661,38 +661,127 @@  static int cbs_h2645_split_fragment(CodedBitstreamContext *ctx,
     return 0;
 }
 
-#define cbs_h2645_replace_ps(h26n, ps_name, ps_var, id_element) \
-static int cbs_h26 ## h26n ## _replace_ ## ps_var(CodedBitstreamContext *ctx, \
-                                                  CodedBitstreamUnit *unit)  \
-{ \
-    CodedBitstreamH26 ## h26n ## Context *priv = ctx->priv_data; \
-    H26 ## h26n ## Raw ## ps_name *ps_var = unit->content; \
-    unsigned int id = ps_var->id_element; \
-    int err; \
-    if (id >= FF_ARRAY_ELEMS(priv->ps_var)) { \
-        av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid " #ps_name \
-               " id : %d.\n", id); \
-        return AVERROR_INVALIDDATA; \
-    } \
-    err = ff_cbs_make_unit_refcounted(ctx, unit); \
-    if (err < 0) \
-        return err; \
-    if (priv->ps_var[id] == priv->active_ ## ps_var) \
-        priv->active_ ## ps_var = NULL ; \
-    av_buffer_unref(&priv->ps_var ## _ref[id]); \
-    av_assert0(unit->content_ref); \
-    priv->ps_var ## _ref[id] = av_buffer_ref(unit->content_ref); \
-    if (!priv->ps_var ## _ref[id]) \
-        return AVERROR(ENOMEM); \
-    priv->ps_var[id] = (H26 ## h26n ## Raw ## ps_name *)priv->ps_var ## _ref[id]->data; \
-    return 0; \
-}
+static int cbs_h2645_replace_ps(CodedBitstreamContext *ctx,
+                                CodedBitstreamUnit *unit)
+{
+    typedef struct {
+        int nal_unit_type;
+        int max_count;
+        const char *name;
+        size_t id_offset;
+        size_t ref_array_offset;
+        size_t ptr_array_offset;
+        size_t active_offset;
+    } PSType;
+
+    static const PSType h264_ps_types[] = {
+        {
+            H264_NAL_SPS,
+            H264_MAX_SPS_COUNT,
+            "SPS",
+            offsetof(H264RawSPS, seq_parameter_set_id),
+            offsetof(CodedBitstreamH264Context, sps_ref),
+            offsetof(CodedBitstreamH264Context, sps),
+            offsetof(CodedBitstreamH264Context, active_sps),
+        },
+        {
+            H264_NAL_PPS,
+            H264_MAX_PPS_COUNT,
+            "PPS",
+            offsetof(H264RawPPS, pic_parameter_set_id),
+            offsetof(CodedBitstreamH264Context, pps_ref),
+            offsetof(CodedBitstreamH264Context, pps),
+            offsetof(CodedBitstreamH264Context, active_pps),
+        },
+    };
+
+    static const PSType h265_ps_types[] = {
+        {
+            HEVC_NAL_VPS,
+            HEVC_MAX_VPS_COUNT,
+            "VPS",
+            offsetof(H265RawVPS, vps_video_parameter_set_id),
+            offsetof(CodedBitstreamH265Context, vps_ref),
+            offsetof(CodedBitstreamH265Context, vps),
+            offsetof(CodedBitstreamH265Context, active_vps),
+        },
+        {
+            HEVC_NAL_SPS,
+            HEVC_MAX_SPS_COUNT,
+            "SPS",
+            offsetof(H265RawSPS, sps_seq_parameter_set_id),
+            offsetof(CodedBitstreamH265Context, sps_ref),
+            offsetof(CodedBitstreamH265Context, sps),
+            offsetof(CodedBitstreamH265Context, active_sps),
+        },
+        {
+            HEVC_NAL_PPS,
+            HEVC_MAX_PPS_COUNT,
+            "PPS",
+            offsetof(H265RawPPS, pps_pic_parameter_set_id),
+            offsetof(CodedBitstreamH265Context, pps_ref),
+            offsetof(CodedBitstreamH265Context, pps),
+            offsetof(CodedBitstreamH265Context, active_pps),
+        },
+    };
 
-cbs_h2645_replace_ps(4, SPS, sps, seq_parameter_set_id)
-cbs_h2645_replace_ps(4, PPS, pps, pic_parameter_set_id)
-cbs_h2645_replace_ps(5, VPS, vps, vps_video_parameter_set_id)
-cbs_h2645_replace_ps(5, SPS, sps, sps_seq_parameter_set_id)
-cbs_h2645_replace_ps(5, PPS, pps, pps_pic_parameter_set_id)
+    const PSType *ps_type;
+    AVBufferRef **ref_array;
+    void **ptr_array;
+    void **active;
+    int err, id, i, nb_ps_types;
+
+    switch (ctx->codec->codec_id) {
+    case AV_CODEC_ID_H264:
+        ps_type     = h264_ps_types;
+        nb_ps_types = FF_ARRAY_ELEMS(h264_ps_types);
+        break;
+    case AV_CODEC_ID_H265:
+        ps_type     = h265_ps_types;
+        nb_ps_types = FF_ARRAY_ELEMS(h265_ps_types);
+        break;
+    default:
+        av_assert0(0);
+    }
+
+    for (i = 0; i < nb_ps_types; i++) {
+        if (ps_type->nal_unit_type == unit->type)
+            break;
+        ++ps_type;
+    }
+    av_assert0(i < nb_ps_types);
+
+    id = *((uint8_t*)unit->content + ps_type->id_offset);
+
+    if (id >= ps_type->max_count) {
+        av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid %s id: %d.\n",
+               ps_type->name, id);
+        return AVERROR_INVALIDDATA;
+    }
+
+    err = ff_cbs_make_unit_refcounted(ctx, unit);
+    if (err < 0)
+        return err;
+
+    ref_array =
+         (AVBufferRef**)((uint8_t*)ctx->priv_data + ps_type->ref_array_offset);
+    ptr_array = (void**)((uint8_t*)ctx->priv_data + ps_type->ptr_array_offset);
+    active    = (void**)((uint8_t*)ctx->priv_data + ps_type->active_offset);
+
+    if (ptr_array[id] == *active) {
+        // The old active parameter set is being overwritten, so it can't
+        // be active after this point.
+        *active = NULL;
+    }
+    av_buffer_unref(&ref_array[id]);
+
+    ref_array[id] = av_buffer_ref(unit->content_ref);
+    if (!ref_array[id])
+        return AVERROR(ENOMEM);
+    ptr_array[id] = ref_array[id]->data;
+
+    return 0;
+}
 
 static int cbs_h264_read_nal_unit(CodedBitstreamContext *ctx,
                                   CodedBitstreamUnit *unit)
@@ -717,7 +806,7 @@  static int cbs_h264_read_nal_unit(CodedBitstreamContext *ctx,
             if (err < 0)
                 return err;
 
-            err = cbs_h264_replace_sps(ctx, unit);
+            err = cbs_h2645_replace_ps(ctx, unit);
             if (err < 0)
                 return err;
         }
@@ -739,7 +828,7 @@  static int cbs_h264_read_nal_unit(CodedBitstreamContext *ctx,
             if (err < 0)
                 return err;
 
-            err = cbs_h264_replace_pps(ctx, unit);
+            err = cbs_h2645_replace_ps(ctx, unit);
             if (err < 0)
                 return err;
         }
@@ -836,7 +925,7 @@  static int cbs_h265_read_nal_unit(CodedBitstreamContext *ctx,
             if (err < 0)
                 return err;
 
-            err = cbs_h265_replace_vps(ctx, unit);
+            err = cbs_h2645_replace_ps(ctx, unit);
             if (err < 0)
                 return err;
         }
@@ -849,7 +938,7 @@  static int cbs_h265_read_nal_unit(CodedBitstreamContext *ctx,
             if (err < 0)
                 return err;
 
-            err = cbs_h265_replace_sps(ctx, unit);
+            err = cbs_h2645_replace_ps(ctx, unit);
             if (err < 0)
                 return err;
         }
@@ -863,7 +952,7 @@  static int cbs_h265_read_nal_unit(CodedBitstreamContext *ctx,
             if (err < 0)
                 return err;
 
-            err = cbs_h265_replace_pps(ctx, unit);
+            err = cbs_h2645_replace_ps(ctx, unit);
             if (err < 0)
                 return err;
         }
@@ -1007,7 +1096,7 @@  static int cbs_h264_write_nal_unit(CodedBitstreamContext *ctx,
             if (err < 0)
                 return err;
 
-            err = cbs_h264_replace_sps(ctx, unit);
+            err = cbs_h2645_replace_ps(ctx, unit);
             if (err < 0)
                 return err;
         }
@@ -1031,7 +1120,7 @@  static int cbs_h264_write_nal_unit(CodedBitstreamContext *ctx,
             if (err < 0)
                 return err;
 
-            err = cbs_h264_replace_pps(ctx, unit);
+            err = cbs_h2645_replace_ps(ctx, unit);
             if (err < 0)
                 return err;
         }
@@ -1124,7 +1213,7 @@  static int cbs_h265_write_nal_unit(CodedBitstreamContext *ctx,
             if (err < 0)
                 return err;
 
-            err = cbs_h265_replace_vps(ctx, unit);
+            err = cbs_h2645_replace_ps(ctx, unit);
             if (err < 0)
                 return err;
         }
@@ -1138,7 +1227,7 @@  static int cbs_h265_write_nal_unit(CodedBitstreamContext *ctx,
             if (err < 0)
                 return err;
 
-            err = cbs_h265_replace_sps(ctx, unit);
+            err = cbs_h2645_replace_ps(ctx, unit);
             if (err < 0)
                 return err;
         }
@@ -1152,7 +1241,7 @@  static int cbs_h265_write_nal_unit(CodedBitstreamContext *ctx,
             if (err < 0)
                 return err;
 
-            err = cbs_h265_replace_pps(ctx, unit);
+            err = cbs_h2645_replace_ps(ctx, unit);
             if (err < 0)
                 return err;
         }