Message ID | 20210211143611.5663-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 | 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; > } >
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".
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 --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; }
From: Mark Thompson <sw@jkqxz.net> --- libavcodec/cbs_h2645.c | 171 +++++++++++++++++++++++++++++++---------- 1 file changed, 130 insertions(+), 41 deletions(-)