[FFmpeg-devel] [PATCH v5 01/10] cbs_h2645: refact, use cbs_h2645_replace_ps to replace cbs_h26*_replace_*ps
Andreas Rheinhardt
andreas.rheinhardt at gmail.com
Sun Feb 14 21:45:14 EET 2021
Nuo Mi:
> From: Mark Thompson <sw at 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;
> }
>
More information about the ffmpeg-devel
mailing list