Permalink
Browse files

Merge pull request #3594 from t-nelson/pivos_add_bitstream_writer

add bit stream writer
  • Loading branch information...
2 parents 7954dae + 37a563f commit 44824bc8e71b5a37fd8ef70692c55a080e51044f @t-nelson t-nelson committed Nov 11, 2013
Showing with 134 additions and 0 deletions.
  1. +115 −0 xbmc/utils/BitstreamConverter.cpp
  2. +19 −0 xbmc/utils/BitstreamConverter.h
@@ -901,6 +901,121 @@ uint32_t CBitstreamConverter::get_bits( bits_reader_t *br, int nbits )
return ret;
}
+////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////
+void CBitstreamConverter::init_bits_writer(bits_writer_t *s, uint8_t *buffer, int buffer_size, int writer_le)
+{
+ if (buffer_size < 0)
+ {
+ buffer_size = 0;
+ buffer = NULL;
+ }
+
+ s->size_in_bits = 8 * buffer_size;
+ s->buf = buffer;
+ s->buf_end = s->buf + buffer_size;
+ s->buf_ptr = s->buf;
+ s->bit_left = 32;
+ s->bit_buf = 0;
+ s->writer_le = writer_le;
+}
+
+void CBitstreamConverter::write_bits(bits_writer_t *s, int n, unsigned int value)
+{
+ // Write up to 32 bits into a bitstream.
+ unsigned int bit_buf;
+ int bit_left;
+
+ if (n == 32)
+ {
+ // Write exactly 32 bits into a bitstream.
+ // danger, recursion in play.
+ int lo = value & 0xffff;
+ int hi = value >> 16;
+ if (s->writer_le)
+ {
+ write_bits(s, 16, lo);
+ write_bits(s, 16, hi);
+ }
+ else
+ {
+ write_bits(s, 16, hi);
+ write_bits(s, 16, lo);
+ }
+ return;
+ }
+
+ bit_buf = s->bit_buf;
+ bit_left = s->bit_left;
+
+ if (s->writer_le)
+ {
+ bit_buf |= value << (32 - bit_left);
+ if (n >= bit_left) {
+ BS_WL32(s->buf_ptr, bit_buf);
+ s->buf_ptr += 4;
+ bit_buf = (bit_left == 32) ? 0 : value >> bit_left;
+ bit_left += 32;
+ }
+ bit_left -= n;
+ }
+ else
+ {
+ if (n < bit_left) {
+ bit_buf = (bit_buf << n) | value;
+ bit_left -= n;
+ } else {
+ bit_buf <<= bit_left;
+ bit_buf |= value >> (n - bit_left);
+ BS_WB32(s->buf_ptr, bit_buf);
+ s->buf_ptr += 4;
+ bit_left += 32 - n;
+ bit_buf = value;
+ }
+ }
+
+ s->bit_buf = bit_buf;
+ s->bit_left = bit_left;
+}
+
+void CBitstreamConverter::skip_bits(bits_writer_t *s, int n)
+{
+ // Skip the given number of bits.
+ // Must only be used if the actual values in the bitstream do not matter.
+ // If n is 0 the behavior is undefined.
+ s->bit_left -= n;
+ s->buf_ptr -= 4 * (s->bit_left >> 5);
+ s->bit_left &= 31;
+}
+
+void CBitstreamConverter::flush_bits(bits_writer_t *s)
+{
+ if (!s->writer_le)
+ {
+ if (s->bit_left < 32)
+ s->bit_buf <<= s->bit_left;
+ }
+ while (s->bit_left < 32)
+ {
+
+ if (s->writer_le)
+ {
+ *s->buf_ptr++ = s->bit_buf;
+ s->bit_buf >>= 8;
+ }
+ else
+ {
+ *s->buf_ptr++ = s->bit_buf >> 24;
+ s->bit_buf <<= 8;
+ }
+ s->bit_left += 8;
+ }
+ s->bit_left = 32;
+ s->bit_buf = 0;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////
bool CBitstreamConverter::mpeg2_sequence_header(const uint8_t *data, const uint32_t size, mpeg2_sequence *sequence)
{
// parse nal's until a sequence_header_code is found
@@ -28,6 +28,14 @@
#include "DllAvCodec.h"
typedef struct {
+ int writer_le;
+ uint32_t bit_buf;
+ int bit_left;
+ uint8_t *buf, *buf_ptr, *buf_end;
+ int size_in_bits;
+} bits_writer_t;
+
+typedef struct {
uint8_t *buffer, *start;
int offbits, length, oflow;
} bits_reader_t;
@@ -61,6 +69,12 @@ typedef struct {
((uint8_t*)(p))[1] = (d) >> 16; \
((uint8_t*)(p))[0] = (d) >> 24; }
+#define BS_WL32(p, d) { \
+ ((uint8_t*)(p))[0] = (d); \
+ ((uint8_t*)(p))[1] = (d) >> 8; \
+ ((uint8_t*)(p))[2] = (d) >> 16; \
+ ((uint8_t*)(p))[3] = (d) >> 24; }
+
typedef struct
{
const uint8_t *data;
@@ -147,6 +161,11 @@ class CBitstreamConverter
static void skip_bits( bits_reader_t *br, int nbits );
static uint32_t get_bits( bits_reader_t *br, int nbits );
+ static void init_bits_writer(bits_writer_t *s, uint8_t *buffer, int buffer_size, int writer_le);
+ static void write_bits(bits_writer_t *s, int n, unsigned int value);
+ static void skip_bits( bits_writer_t *s, int n);
+ static void flush_bits(bits_writer_t *s);
+
static void parseh264_sps(const uint8_t *sps, const uint32_t sps_size, bool *interlaced, int32_t *max_ref_frames);
static bool mpeg2_sequence_header(const uint8_t *data, const uint32_t size, mpeg2_sequence *sequence);

0 comments on commit 44824bc

Please sign in to comment.