Skip to content

Commit

Permalink
Bitstream refactor / VC1Bitstream parser
Browse files Browse the repository at this point in the history
  • Loading branch information
peak3d committed Jan 16, 2017
1 parent 571d039 commit e6f1ca2
Show file tree
Hide file tree
Showing 11 changed files with 584 additions and 303 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
#include "messaging/ApplicationMessenger.h"
#include "DVDClock.h"
#include "utils/BitstreamConverter.h"
#include "utils/BitstreamWriter.h"

#include "utils/CPUInfo.h"
#include "utils/log.h"
#include "settings/AdvancedSettings.h"
Expand Down
1 change: 1 addition & 0 deletions xbmc/cores/VideoPlayer/DVDCodecs/Video/VTB.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include "utils/log.h"
#include "VTB.h"
#include "utils/BitstreamConverter.h"
#include "utils/BitstreamReader.h"

extern "C" {
#include "libavcodec/videotoolbox.h"
Expand Down
255 changes: 17 additions & 238 deletions xbmc/utils/BitstreamConverter.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2010-2013 Team XBMC
* Copyright (C) 2010-2017 Team XBMC
* http://xbmc.org
*
* This Program is free software; you can redistribute it and/or modify
Expand All @@ -26,6 +26,8 @@
#endif

#include "BitstreamConverter.h"
#include "BitstreamReader.h"
#include "BitstreamWriter.h"

enum {
AVC_NAL_SLICE=1,
Expand Down Expand Up @@ -128,9 +130,9 @@ static uint32_t nal_bs_read(nal_bitstream *bs, int n)

// bring the required bits down and truncate
if ((shift = bs->head - n) > 0)
res = bs->cache >> shift;
res = static_cast<uint32_t>(bs->cache >> shift);
else
res = bs->cache;
res = static_cast<uint32_t>(bs->cache);

// mask out required bits
if (n < 32)
Expand Down Expand Up @@ -211,50 +213,6 @@ CBitstreamParser::CBitstreamParser()
{
}

CBitstreamParser::~CBitstreamParser()
{
Close();
}

bool CBitstreamParser::Open()
{
return true;
}

void CBitstreamParser::Close()
{
}

const uint8_t* CBitstreamParser::find_start_code(const uint8_t *p,
const uint8_t *end, uint32_t *state)
{
assert(p <= end);
if (p >= end)
return end;

for (int i = 0; i < 3; i++) {
uint32_t tmp = *state << 8;
*state = tmp + *(p++);
if (tmp == 0x100 || p == end)
return p;
}

while (p < end) {
if (p[-1] > 1 ) p += 3;
else if (p[-2] ) p += 2;
else if (p[-3]|(p[-1]-1)) p++;
else {
p++;
break;
}
}

p = FFMIN(p, end) - 4;
*state = BS_RB32(p);

return p + 4;
}

bool CBitstreamParser::FindIdrSlice(const uint8_t *buf, int buf_size)
{
if (!buf)
Expand Down Expand Up @@ -1068,185 +1026,6 @@ const int CBitstreamConverter::isom_write_avcc(AVIOContext *pb, const uint8_t *d
return 0;
}

void CBitstreamConverter::bits_reader_set( bits_reader_t *br, uint8_t *buf, int len )
{
br->buffer = br->start = buf;
br->offbits = 0;
br->length = len;
br->oflow = 0;
}

uint32_t CBitstreamConverter::read_bits( bits_reader_t *br, int nbits )
{
int i, nbytes;
uint32_t ret = 0;
uint8_t *buf;

buf = br->buffer;
nbytes = (br->offbits + nbits)/8;
if ( ((br->offbits + nbits) %8 ) > 0 )
nbytes++;
if ( (buf + nbytes) > (br->start + br->length) ) {
br->oflow = 1;
return 0;
}
for ( i=0; i<nbytes; i++ )
ret += buf[i]<<((nbytes-i-1)*8);
i = (4-nbytes)*8+br->offbits;
ret = ((ret<<i)>>i)>>((nbytes*8)-nbits-br->offbits);

br->offbits += nbits;
br->buffer += br->offbits / 8;
br->offbits %= 8;

return ret;
}

void CBitstreamConverter::skip_bits( bits_reader_t *br, int nbits )
{
br->offbits += nbits;
br->buffer += br->offbits / 8;
br->offbits %= 8;
if ( br->buffer > (br->start + br->length) ) {
br->oflow = 1;
}
}

uint32_t CBitstreamConverter::get_bits( bits_reader_t *br, int nbits )
{
int i, nbytes;
uint32_t ret = 0;
uint8_t *buf;

buf = br->buffer;
nbytes = (br->offbits + nbits)/8;
if ( ((br->offbits + nbits) %8 ) > 0 )
nbytes++;
if ( (buf + nbytes) > (br->start + br->length) ) {
br->oflow = 1;
return 0;
}
for ( i=0; i<nbytes; i++ )
ret += buf[i]<<((nbytes-i-1)*8);
i = (4-nbytes)*8+br->offbits;
ret = ((ret<<i)>>i)>>((nbytes*8)-nbits-br->offbits);

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)
Expand Down Expand Up @@ -1299,17 +1078,17 @@ bool CBitstreamConverter::mpeg2_sequence_header(const uint8_t *data, const uint3
switch(ratio_info)
{
case 0x01:
ratio = 1.0;
ratio = 1.0f;
break;
default:
case 0x02:
ratio = 4.0/3.0;
ratio = 4.0f/3;
break;
case 0x03:
ratio = 16.0/9.0;
ratio = 16.0f/9;
break;
case 0x04:
ratio = 2.21;
ratio = 2.21f;
break;
}
if (ratio_info != sequence->ratio_info)
Expand All @@ -1327,28 +1106,28 @@ bool CBitstreamConverter::mpeg2_sequence_header(const uint8_t *data, const uint3
{
default:
case 0x01:
rate = 24000.0 / 1001.0;
rate = static_cast<float>(24000.0 / 1001.0);
break;
case 0x02:
rate = 24000.0 / 1000.0;
rate = 24.0f;
break;
case 0x03:
rate = 25000.0 / 1000.0;
rate = 25.0f;
break;
case 0x04:
rate = 30000.0 / 1001.0;
rate = static_cast<float>(30000.0 / 1001.0);
break;
case 0x05:
rate = 30000.0 / 1000.0;
rate = 30.0f;
break;
case 0x06:
rate = 50000.0 / 1000.0;
rate = 50.0f;
break;
case 0x07:
rate = 60000.0 / 1001.0;
rate = static_cast<float>(60000.0 / 1001.0);
break;
case 0x08:
rate = 60000.0 / 1000.0;
rate = 60.0f;
break;
}
if (rate_info != sequence->rate_info)
Expand Down

0 comments on commit e6f1ca2

Please sign in to comment.