]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/put_bits.h
Merge commit 'db4903eb4875bed6c5b8a4259cdd7bc1768dfdf6'
[ffmpeg] / libavcodec / put_bits.h
index 68ed3911957487b504c3e1c8bcb1b4f089aa6a60..1ceb1cc766246dff19de5d7baf97a5c79a3bc157 100644 (file)
@@ -119,6 +119,18 @@ static inline void flush_put_bits(PutBitContext *s)
     s->bit_buf  = 0;
 }
 
+static inline void flush_put_bits_le(PutBitContext *s)
+{
+    while (s->bit_left < 32) {
+        av_assert0(s->buf_ptr < s->buf_end);
+        *s->buf_ptr++ = s->bit_buf;
+        s->bit_buf  >>= 8;
+        s->bit_left  += 8;
+    }
+    s->bit_left = 32;
+    s->bit_buf  = 0;
+}
+
 #ifdef BITSTREAM_WRITER_LE
 #define avpriv_align_put_bits align_put_bits_unsupported_here
 #define avpriv_put_string ff_put_string_unsupported_here
@@ -197,6 +209,34 @@ static inline void put_bits(PutBitContext *s, int n, unsigned int value)
     s->bit_left = bit_left;
 }
 
+static inline void put_bits_le(PutBitContext *s, int n, unsigned int value)
+{
+    unsigned int bit_buf;
+    int bit_left;
+
+    av_assert2(n <= 31 && value < (1U << n));
+
+    bit_buf  = s->bit_buf;
+    bit_left = s->bit_left;
+
+    bit_buf |= value << (32 - bit_left);
+    if (n >= 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     = value >> bit_left;
+        bit_left   += 32;
+    }
+    bit_left -= n;
+
+    s->bit_buf  = bit_buf;
+    s->bit_left = bit_left;
+}
+
 static inline void put_sbits(PutBitContext *pb, int n, int32_t value)
 {
     av_assert2(n >= 0 && n <= 31);
@@ -209,15 +249,72 @@ 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;
+}
+
+/**
+ * Write up to 64 bits into a bitstream.
+ */
+static inline void put_bits64(PutBitContext *s, int n, uint64_t value)
+{
+    av_assert2((n == 64) || (n < 64 && value < (UINT64_C(1) << n)));
+
+    if (n < 32)
+        put_bits(s, n, value);
+    else if (n == 32)
+        put_bits32(s, value);
+    else if (n < 64) {
+        uint32_t lo = value & 0xffffffff;
+        uint32_t hi = value >> 32;
+#ifdef BITSTREAM_WRITER_LE
+        put_bits32(s, lo);
+        put_bits(s, n - 32, hi);
+#else
+        put_bits(s, n - 32, hi);
+        put_bits32(s, lo);
+#endif
+    } else {
+        uint32_t lo = value & 0xffffffff;
+        uint32_t hi = value >> 32;
+#ifdef BITSTREAM_WRITER_LE
+        put_bits32(s, lo);
+        put_bits32(s, hi);
+#else
+        put_bits32(s, hi);
+        put_bits32(s, lo);
+#endif
+
+    }
 }
 
 /**