diff options
author | Andreas Rheinhardt <andreas.rheinhardt@googlemail.com> | 2019-02-11 23:47:43 +0100 |
---|---|---|
committer | Mark Thompson <sw@jkqxz.net> | 2019-02-25 21:40:13 +0000 |
commit | b8c45bbcbc207293f955e838ea66106f4b65b1ac (patch) | |
tree | e46eb58202941ad69cbd56f142a7900c7499ae13 /libavcodec/cbs.c | |
parent | c5b452ed2f16a0d7bf01d7d84097337f8756987b (diff) | |
download | ffmpeg-b8c45bbcbc207293f955e838ea66106f4b65b1ac.tar.gz |
libavcodec/cbs: Stop needlessly reallocating the units array
Currently, a fragment's unit array is constantly reallocated during
splitting of a packet. This commit changes this: One can keep the units
array by distinguishing between the number of allocated and the number
of valid units in the units array.
The more units a packet is split into, the bigger the benefit.
So MPEG-2 benefits the most; for a video coming from an NTSC-DVD
(usually 32 units per frame) the average cost of cbs_insert_unit (for a
single unit) went down from 6717 decicycles to 450 decicycles (based
upon 10 runs with 4194304 runs each); if each packet consists of only
one unit, it went down from 2425 to 448; for a H.264 video where most
packets contain nine units, it went from 4431 to 450.
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@googlemail.com>
Diffstat (limited to 'libavcodec/cbs.c')
-rw-r--r-- | libavcodec/cbs.c | 62 |
1 files changed, 36 insertions, 26 deletions
diff --git a/libavcodec/cbs.c b/libavcodec/cbs.c index ecbf57c293..c388be896b 100644 --- a/libavcodec/cbs.c +++ b/libavcodec/cbs.c @@ -136,14 +136,13 @@ static void cbs_unit_uninit(CodedBitstreamContext *ctx, unit->data_bit_padding = 0; } -void ff_cbs_fragment_uninit(CodedBitstreamContext *ctx, - CodedBitstreamFragment *frag) +void ff_cbs_fragment_reset(CodedBitstreamContext *ctx, + CodedBitstreamFragment *frag) { int i; for (i = 0; i < frag->nb_units; i++) cbs_unit_uninit(ctx, &frag->units[i]); - av_freep(&frag->units); frag->nb_units = 0; av_buffer_unref(&frag->data_ref); @@ -152,6 +151,15 @@ void ff_cbs_fragment_uninit(CodedBitstreamContext *ctx, frag->data_bit_padding = 0; } +void ff_cbs_fragment_free(CodedBitstreamContext *ctx, + CodedBitstreamFragment *frag) +{ + ff_cbs_fragment_reset(ctx, frag); + + av_freep(&frag->units); + frag->nb_units_allocated = 0; +} + static int cbs_read_fragment_content(CodedBitstreamContext *ctx, CodedBitstreamFragment *frag) { @@ -216,8 +224,6 @@ int ff_cbs_read_extradata(CodedBitstreamContext *ctx, { int err; - memset(frag, 0, sizeof(*frag)); - err = cbs_fill_fragment_data(ctx, frag, par->extradata, par->extradata_size); if (err < 0) @@ -236,8 +242,6 @@ int ff_cbs_read_packet(CodedBitstreamContext *ctx, { int err; - memset(frag, 0, sizeof(*frag)); - if (pkt->buf) { frag->data_ref = av_buffer_ref(pkt->buf); if (!frag->data_ref) @@ -265,8 +269,6 @@ int ff_cbs_read(CodedBitstreamContext *ctx, { int err; - memset(frag, 0, sizeof(*frag)); - err = cbs_fill_fragment_data(ctx, frag, data, size); if (err < 0) return err; @@ -548,20 +550,34 @@ static int cbs_insert_unit(CodedBitstreamContext *ctx, { CodedBitstreamUnit *units; - units = av_malloc_array(frag->nb_units + 1, sizeof(*units)); - if (!units) - return AVERROR(ENOMEM); + if (frag->nb_units < frag->nb_units_allocated) { + units = frag->units; + + if (position < frag->nb_units) + memmove(units + position + 1, units + position, + (frag->nb_units - position) * sizeof(*units)); + } else { + units = av_malloc_array(frag->nb_units + 1, sizeof(*units)); + if (!units) + return AVERROR(ENOMEM); + + ++frag->nb_units_allocated; - if (position > 0) - memcpy(units, frag->units, position * sizeof(*units)); - if (position < frag->nb_units) - memcpy(units + position + 1, frag->units + position, - (frag->nb_units - position) * sizeof(*units)); + if (position > 0) + memcpy(units, frag->units, position * sizeof(*units)); + + if (position < frag->nb_units) + memcpy(units + position + 1, frag->units + position, + (frag->nb_units - position) * sizeof(*units)); + } memset(units + position, 0, sizeof(*units)); - av_freep(&frag->units); - frag->units = units; + if (units != frag->units) { + av_free(frag->units); + frag->units = units; + } + ++frag->nb_units; return 0; @@ -652,16 +668,10 @@ int ff_cbs_delete_unit(CodedBitstreamContext *ctx, --frag->nb_units; - if (frag->nb_units == 0) { - av_freep(&frag->units); - - } else { + if (frag->nb_units > 0) memmove(frag->units + position, frag->units + position + 1, (frag->nb_units - position) * sizeof(*frag->units)); - // Don't bother reallocating the unit array. - } - return 0; } |