Message ID | 20210217015146.19724-2-nuomi2021@gmail.com |
---|---|
State | Superseded |
Headers | show |
Series | add vvc raw demuxer, muxer, parser, metadata bsf | expand |
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 |
Nuo Mi: > From: Mark Thompson <sw@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; > } >
On Mon, Mar 8, 2021 at 10:28 PM Andreas Rheinhardt < andreas.rheinhardt@gmail.com> wrote: > Nuo Mi: > > From: Mark Thompson <sw@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. > One purpose of this patch is to make the caller's life easier. They do not need to care about the PSType, Just call cbs_h2645_replace_ps(CodedBitstreamContext *ctx, CodedBitstreamUnit *unit) > > > > + > > + 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; > > } > > > > _______________________________________________ > 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".
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); + + 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; }
From: Mark Thompson <sw@jkqxz.net> --- libavcodec/cbs_h2645.c | 167 +++++++++++++++++++++++++++++++---------- 1 file changed, 126 insertions(+), 41 deletions(-)