Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/FFmpeg/FFmpeg.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Rheinhardt <andreas.rheinhardt@googlemail.com>2018-11-04 07:48:40 +0300
committerMark Thompson <sw@jkqxz.net>2018-11-11 22:22:52 +0300
commit6df9020f45eaff66ba2c2bac98cda9ddaacb03f3 (patch)
tree9eff811332dcc440242cdb5e66d28b0ab8710b67 /libavcodec/cbs_mpeg2.c
parent252e79663de802d8d0b38fbfdfeeda2d86b4e611 (diff)
cbs_mpeg2: Improve performance of writing slices
Instead of using a combination of bitreader and -writer for copying data, one can byte-align the (obsolete and removed) bitreader to improve performance. One can even use memcpy in the normal case. This improved the time needed for writing the slicedata from 33618 to 2370 decicycles when tested on a video originating from a DVD (4194394 runs). Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@googlemail.com> Signed-off-by: Mark Thompson <sw@jkqxz.net>
Diffstat (limited to 'libavcodec/cbs_mpeg2.c')
-rw-r--r--libavcodec/cbs_mpeg2.c39
1 files changed, 27 insertions, 12 deletions
diff --git a/libavcodec/cbs_mpeg2.c b/libavcodec/cbs_mpeg2.c
index 0df4234b12..8b8b266563 100644
--- a/libavcodec/cbs_mpeg2.c
+++ b/libavcodec/cbs_mpeg2.c
@@ -264,8 +264,6 @@ static int cbs_mpeg2_write_slice(CodedBitstreamContext *ctx,
PutBitContext *pbc)
{
MPEG2RawSlice *slice = unit->content;
- GetBitContext gbc;
- size_t bits_left;
int err;
err = cbs_mpeg2_write_slice_header(ctx, pbc, &slice->header);
@@ -273,21 +271,38 @@ static int cbs_mpeg2_write_slice(CodedBitstreamContext *ctx,
return err;
if (slice->data) {
+ size_t rest = slice->data_size - (slice->data_bit_start + 7) / 8;
+ uint8_t *pos = slice->data + slice->data_bit_start / 8;
+
+ av_assert0(slice->data_bit_start >= 0 &&
+ 8 * slice->data_size > slice->data_bit_start);
+
if (slice->data_size * 8 + 8 > put_bits_left(pbc))
return AVERROR(ENOSPC);
- init_get_bits(&gbc, slice->data, slice->data_size * 8);
- skip_bits_long(&gbc, slice->data_bit_start);
-
- while (get_bits_left(&gbc) > 15)
- put_bits(pbc, 16, get_bits(&gbc, 16));
+ // First copy the remaining bits of the first byte
+ if (slice->data_bit_start % 8)
+ put_bits(pbc, 8 - slice->data_bit_start % 8,
+ *pos++ & MAX_UINT_BITS(8 - slice->data_bit_start % 8));
+
+ if (put_bits_count(pbc) % 8 == 0) {
+ // If the writer is aligned at this point,
+ // memcpy can be used to improve performance.
+ // This is the normal case.
+ flush_put_bits(pbc);
+ memcpy(put_bits_ptr(pbc), pos, rest);
+ skip_put_bytes(pbc, rest);
+ } else {
+ // If not, we have to copy manually:
+ for (; rest > 3; rest -= 4, pos += 4)
+ put_bits32(pbc, AV_RB32(pos));
- bits_left = get_bits_left(&gbc);
- put_bits(pbc, bits_left, get_bits(&gbc, bits_left));
+ for (; rest; rest--, pos++)
+ put_bits(pbc, 8, *pos);
- // Align with zeroes.
- while (put_bits_count(pbc) % 8 != 0)
- put_bits(pbc, 1, 0);
+ // Align with zeros
+ put_bits(pbc, 8 - put_bits_count(pbc) % 8, 0);
+ }
}
return 0;