aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Niedermayer <michael@niedermayer.cc>2017-06-13 03:18:21 +0200
committerMichael Niedermayer <michael@niedermayer.cc>2017-06-13 04:17:13 +0200
commit4f9e958b04c69b1cebdc682b752cf6add75a0693 (patch)
tree491318ae7cc8a093616e2f1ebe145feaae610794
parentdb93fd74e4be68f97efcb958537f46a2a133aa47 (diff)
downloadffmpeg-4f9e958b04c69b1cebdc682b752cf6add75a0693.tar.gz
avcodec/put_bits: Implement put_bits32() in a single pass instead of 2 passes writing 16bits each
820 cpu cycles -> 660 cpu cycles for 100 put_bits32() Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
-rw-r--r--libavcodec/put_bits.h34
1 files changed, 28 insertions, 6 deletions
diff --git a/libavcodec/put_bits.h b/libavcodec/put_bits.h
index 68ed391195..9bd45cd8ba 100644
--- a/libavcodec/put_bits.h
+++ b/libavcodec/put_bits.h
@@ -209,15 +209,37 @@ static inline void put_sbits(PutBitContext *pb, int n, int32_t value)
*/
static void av_unused put_bits32(PutBitContext *s, uint32_t value)
{
- int lo = value & 0xffff;
- int hi = value >> 16;
+ unsigned int bit_buf;
+ int bit_left;
+
+ bit_buf = s->bit_buf;
+ bit_left = s->bit_left;
+
#ifdef BITSTREAM_WRITER_LE
- put_bits(s, 16, lo);
- put_bits(s, 16, hi);
+ bit_buf |= value << (32 - bit_left);
+ if (3 < s->buf_end - s->buf_ptr) {
+ AV_WL32(s->buf_ptr, bit_buf);
+ s->buf_ptr += 4;
+ } else {
+ av_log(NULL, AV_LOG_ERROR, "Internal error, put_bits buffer too small\n");
+ av_assert2(0);
+ }
+ bit_buf = (uint64_t)value >> bit_left;
#else
- put_bits(s, 16, hi);
- put_bits(s, 16, lo);
+ bit_buf = (uint64_t)bit_buf << bit_left;
+ bit_buf |= value >> (32 - bit_left);
+ if (3 < s->buf_end - s->buf_ptr) {
+ AV_WB32(s->buf_ptr, bit_buf);
+ s->buf_ptr += 4;
+ } else {
+ av_log(NULL, AV_LOG_ERROR, "Internal error, put_bits buffer too small\n");
+ av_assert2(0);
+ }
+ bit_buf = value;
#endif
+
+ s->bit_buf = bit_buf;
+ s->bit_left = bit_left;
}
/**