[FFmpeg-devel] [PATCH v6 1/9] cbs_h2645: refact, use cbs_h2645_replace_ps to replace cbs_h26*_replace_*ps
Andreas Rheinhardt
andreas.rheinhardt at gmail.com
Mon Mar 8 16:20:40 EET 2021
Nuo Mi:
> From: Mark Thompson <sw at jkqxz.net>
>
> ---
> libavcodec/cbs_h2645.c | 167 +++++++++++++++++++++++++++++++----------
> 1 file changed, 126 insertions(+), 41 deletions(-)
>
> diff --git a/libavcodec/cbs_h2645.c b/libavcodec/cbs_h2645.c
> index 6005d46e0d..57c419aa05 100644
> --- a/libavcodec/cbs_h2645.c
> +++ b/libavcodec/cbs_h2645.c
> @@ -661,38 +661,123 @@ 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 {
> + // Codec this parameter set exists in.
> + enum AVCodecID codec_id;
> + // The NAL unit type corresponding to this parameter set type.
> + int nal_unit_type;
> + // Name of the parameter set. This field is large enough to
> + // contain a string of the form "XPS".
> + char name[4];
> + // The maximum number of this type of parameter set which might
> + // be stored. The greatest valid id is also one less than this.
> + int id_count;
> + // Offset of the ID field (uint8_t) in the decomposed raw
> + // parameter set structure.
> + size_t id_offset;
> + // Offset of the reference array (AVBufferRef*[]) in the codec
> + // private context.
> + size_t ref_array_offset;
> + // Offset of the pointer array (CodecRawXPS*[]) in the codec
> + // private context.
> + size_t ptr_array_offset;
> + // Offset of the active field (const CodecRawXPS*) in the codec
> + // private context, or zero if this codec does not have active
> + // parameter sets.
> + size_t active_offset;
> + } PSType;
> +
> +#define H26456_PS_TYPE(codec, nal, cname, uname, count, id_off, active_off) { \
> + .codec_id = AV_CODEC_ID_ ## codec, \
> + .nal_unit_type = nal, \
> + .name = #cname, \
> + .id_count = count, \
> + .id_offset = id_off, \
> + .ref_array_offset = offsetof(CodedBitstream ## codec ## Context, \
> + uname ## _ref), \
> + .ptr_array_offset = offsetof(CodedBitstream ## codec ## Context, \
> + uname), \
> + .active_offset = active_off, \
> + }
> +
> +#define H2645_PS_TYPE(codec, nal, cname, uname, count, id_name, active_field) \
> + H26456_PS_TYPE(codec, nal, cname, uname, count, \
> + offsetof(codec ## Raw ## cname, id_name ## _parameter_set_id), \
> + offsetof(CodedBitstream ## codec ## Context, active_field))
> +
> +#define H264_PS_TYPE(cname, uname, id_name) \
> + H2645_PS_TYPE(H264, H264_NAL_ ## cname, cname, uname, \
> + H264_MAX_ ## cname ## _COUNT, \
> + id_name, active_ ## uname)
> +#define H265_PS_TYPE(cname, uname, id_name) \
> + H2645_PS_TYPE(H265, HEVC_NAL_ ## cname, cname, uname, \
> + HEVC_MAX_ ## cname ## _COUNT, \
> + uname ## _ ## id_name, active_ ## uname)
> +
> + static const PSType ps_types[] = {
> + H264_PS_TYPE(SPS, sps, seq),
> + H264_PS_TYPE(PPS, pps, pic),
> + H265_PS_TYPE(VPS, vps, video),
> + H265_PS_TYPE(SPS, sps, seq),
> + H265_PS_TYPE(PPS, pps, pic),
> + };
> +
> + const PSType *ps_type;
> + AVBufferRef **ref_array;
> + void **ptr_array;
> + int err, id = 0, i;
> +
> + ps_type = NULL;
> + for (i = 0; i < FF_ARRAY_ELEMS(ps_types); i++) {
> + if (ps_types[i].codec_id == ctx->codec->codec_id &&
> + ps_types[i].nal_unit_type == unit->type) {
> + ps_type = &ps_types[i];
> + break;
> + }
> + }
> + av_assert0(ps_type);
It is actually unnecessary to search for the type at runtime: All that
is needed is to change the signature to
cbs_h2645_replace_ps(CodedBitstreamContext *ctx, CodedBitstreamUnit
*unit, const PSType *type), move the definition of the PSTypes out of
cbs_h2645_replace_ps() and adapt the callers.
> +
> + if (ps_type->id_offset) {
> + id = *((uint8_t*)unit->content + ps_type->id_offset);
> +
> + if (id >= ps_type->id_count) {
> + av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid %s id: %d.\n",
> + ps_type->name, id);
> + return AVERROR_INVALIDDATA;
> + }
> + }
>
> -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)
> + 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);
> +
> + if (ps_type->active_offset) {
> + void **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 +802,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 +824,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 +921,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 +934,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 +948,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 +1092,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 +1116,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 +1209,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 +1223,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 +1237,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;
> }
>
More information about the ffmpeg-devel
mailing list