mirror of
https://github.com/vgmstream/vgmstream.git
synced 2024-11-28 00:20:47 +01:00
cleanup: move bitstream reader
This commit is contained in:
parent
514517b812
commit
c46e23fa1f
@ -1,6 +1,6 @@
|
||||
#ifdef VGM_USE_MPEG
|
||||
#include "mpeg_decoder.h"
|
||||
#include "mpeg_bitreader.h"
|
||||
#include "../util/bitstream_msb.h"
|
||||
#include "coding.h"
|
||||
|
||||
#define MPEG_AHX_EXPECTED_FRAME_SIZE 0x414
|
||||
@ -39,25 +39,25 @@ static int ahx_decrypt(uint8_t* buf, int curr_size, crikey_t* crikey) {
|
||||
bitstream_t ib = {0};
|
||||
bitstream_t ob = {0};
|
||||
|
||||
init_bitstream(&ib, buf, curr_size); /* frame */
|
||||
init_bitstream(&ob, buf, curr_size); /* decrypted frame */
|
||||
bm_setup(&ib, buf, curr_size); /* frame */
|
||||
bm_setup(&ob, buf, curr_size); /* decrypted frame */
|
||||
|
||||
/* MPEG header (fixed in AHX, otherwise layer/bitrate/channels sets bands+tables) */
|
||||
bs_skip(&ib, 32);
|
||||
bs_skip(&ob, 32);
|
||||
bm_skip(&ib, 32);
|
||||
bm_skip(&ob, 32);
|
||||
|
||||
/* read bit allocs for later */
|
||||
for (int i = 0; i < AHX_BANDS; i++) {
|
||||
int ba_bits = AHX_BITALLOC_TABLE[i];
|
||||
|
||||
rb_bits(&ib, ba_bits, &bit_alloc[i]);
|
||||
bs_skip(&ob, ba_bits);
|
||||
bm_get (&ib, ba_bits, &bit_alloc[i]);
|
||||
bm_skip(&ob, ba_bits);
|
||||
}
|
||||
|
||||
/* get first scalefactor info to decide key */
|
||||
if (bit_alloc[0]) {
|
||||
rb_bits(&ib, 2, &scfsi[0]);
|
||||
bs_skip(&ob, 2);
|
||||
bm_get (&ib, 2, &scfsi[0]);
|
||||
bm_skip(&ob, 2);
|
||||
}
|
||||
|
||||
uint16_t key;
|
||||
@ -71,9 +71,9 @@ static int ahx_decrypt(uint8_t* buf, int curr_size, crikey_t* crikey) {
|
||||
/* decrypt rest of scalefactors (only first ones are encrypted though) */
|
||||
for (int i = 1; i < AHX_BANDS; i++) {
|
||||
if (bit_alloc[i]) {
|
||||
rb_bits(&ib, 2, &scfsi[i]);
|
||||
bm_get (&ib, 2, &scfsi[i]);
|
||||
scfsi[i] ^= (key & 3);
|
||||
wb_bits(&ob, 2, scfsi[i]);
|
||||
bm_put(&ob, 2, scfsi[i]);
|
||||
}
|
||||
key >>= 2;
|
||||
}
|
||||
@ -84,10 +84,10 @@ static int ahx_decrypt(uint8_t* buf, int curr_size, crikey_t* crikey) {
|
||||
continue;
|
||||
|
||||
switch(scfsi[i]) {
|
||||
case 0: bs_skip(&ib, 6 * 3); break;
|
||||
case 0: bm_skip(&ib, 6 * 3); break;
|
||||
case 1:
|
||||
case 3: bs_skip(&ib, 6 * 2); break;
|
||||
case 2: bs_skip(&ib, 6 * 1); break;
|
||||
case 3: bm_skip(&ib, 6 * 2); break;
|
||||
case 2: bm_skip(&ib, 6 * 1); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
@ -108,21 +108,21 @@ static int ahx_decrypt(uint8_t* buf, int curr_size, crikey_t* crikey) {
|
||||
else
|
||||
qbits = qbits * 3; /* 3 qs */
|
||||
|
||||
int ok = bs_skip(&ib, qbits);
|
||||
int ok = bm_skip(&ib, qbits);
|
||||
if (!ok) goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
/* read padding */
|
||||
{
|
||||
int bpos = bs_pos(&ib);
|
||||
int bpos = bm_pos(&ib);
|
||||
if (bpos % 8) {
|
||||
bs_skip(&ib, 8 - (bpos % 8));
|
||||
bm_skip(&ib, 8 - (bpos % 8));
|
||||
}
|
||||
}
|
||||
|
||||
/* if file was properly read/decrypted this size should land in next frame header or near EOF */
|
||||
return bs_pos(&ib) / 8;
|
||||
return bm_pos(&ib) / 8;
|
||||
fail:
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
#include "mpeg_decoder.h"
|
||||
#include "mpeg_bitreader.h"
|
||||
#include "../util/bitstream_msb.h"
|
||||
|
||||
#ifdef VGM_USE_MPEG
|
||||
|
||||
@ -108,7 +108,7 @@ int mpeg_custom_setup_init_ealayer3(STREAMFILE* sf, off_t start_offset, mpeg_cod
|
||||
{
|
||||
ib.sf = sf;
|
||||
ib.offset = start_offset;
|
||||
ib.is.buf = ib.buf;
|
||||
bm_setup(&ib.is, ib.buf, 0); // filled later
|
||||
|
||||
ok = ealayer3_parse_frame(data, -1, &ib, &eaf);
|
||||
if (!ok) goto fail;
|
||||
@ -156,7 +156,7 @@ int mpeg_custom_parse_frame_ealayer3(VGMSTREAMCHANNEL* stream, mpeg_codec_data*
|
||||
|
||||
ib_0.sf = stream->streamfile;
|
||||
ib_0.offset = stream->offset;
|
||||
ib_0.is.buf = ib_0.buf;
|
||||
bm_setup(&ib_0.is, ib_0.buf, 0); // filled later
|
||||
|
||||
ok = ealayer3_parse_frame(data, num_stream, &ib_0, &eaf_0);
|
||||
if (!ok) goto fail;
|
||||
@ -199,7 +199,7 @@ int mpeg_custom_parse_frame_ealayer3(VGMSTREAMCHANNEL* stream, mpeg_codec_data*
|
||||
|
||||
ib_1.sf = stream->streamfile;
|
||||
ib_1.offset = stream->offset;
|
||||
ib_1.is.buf = ib_1.buf;
|
||||
bm_setup(&ib_1.is, ib_1.buf, 0); // filled later
|
||||
|
||||
ok = ealayer3_parse_frame(data, num_stream, &ib_1, &eaf_1);
|
||||
if (!ok) goto fail;
|
||||
@ -222,12 +222,12 @@ int mpeg_custom_parse_frame_ealayer3(VGMSTREAMCHANNEL* stream, mpeg_codec_data*
|
||||
{
|
||||
bitstream_t os = {0};
|
||||
|
||||
init_bitstream(&os, ms->buffer, ms->buffer_size);
|
||||
bm_setup(&os, ms->buffer, ms->buffer_size);
|
||||
|
||||
ok = ealayer3_rebuild_mpeg_frame(&ib_0.is, &eaf_0, &ib_1.is, &eaf_1, &os);
|
||||
if (!ok) goto fail;
|
||||
|
||||
ms->bytes_in_buffer = os.b_off / 8; /* wrote full MPEG frame, hopefully */
|
||||
ms->bytes_in_buffer = bm_pos(&os) / 8; /* wrote full MPEG frame, hopefully */
|
||||
}
|
||||
|
||||
return 1;
|
||||
@ -267,8 +267,8 @@ static void fill_buf(ealayer3_buffer_t* ib, int bits) {
|
||||
|
||||
//;VGM_LOG("filled: %lx + %x (b=%i, m=%i)\n", ib->offset, bytes_size, bits, (mod > 0 ? 8 - mod : 0));
|
||||
|
||||
read_size = read_streamfile(ib->buf + ib->is.bufsize, ib->offset, bytes_size, ib->sf);
|
||||
ib->is.bufsize += read_size;
|
||||
read_size = read_streamfile(ib->buf + ib->is.bufsize, ib->offset, bytes_size, ib->sf); //TODO don't access internals
|
||||
bm_fill(&ib->is, read_size);
|
||||
ib->offset += read_size;
|
||||
ib->leftover_bits = (mod > 0 ? 8 - mod : 0);
|
||||
}
|
||||
@ -309,7 +309,7 @@ static int ealayer3_parse_frame_v1(ealayer3_buffer_t* ib, ealayer3_frame_t* eaf,
|
||||
|
||||
/* read EA-frame V1 header */
|
||||
fill_buf(ib, 8);
|
||||
rb_bits(is, 8,&eaf->v1_pcm_flag);
|
||||
bm_get(is, 8,&eaf->v1_pcm_flag);
|
||||
|
||||
eaf->pre_size = 1; /* 8b */
|
||||
|
||||
@ -331,15 +331,15 @@ static int ealayer3_parse_frame_v1(ealayer3_buffer_t* ib, ealayer3_frame_t* eaf,
|
||||
/* check PCM block */
|
||||
if (eaf->v1_pcm_flag == 0xEE) {
|
||||
fill_buf(ib, 32);
|
||||
rb_bits(is, 16,&eaf->v1_offset_samples); /* PCM block offset in the buffer */
|
||||
rb_bits(is, 16,&eaf->v1_pcm_samples); /* number of PCM samples, can be 0 */
|
||||
bm_get(is, 16,&eaf->v1_offset_samples); /* PCM block offset in the buffer */
|
||||
bm_get(is, 16,&eaf->v1_pcm_samples); /* number of PCM samples, can be 0 */
|
||||
|
||||
eaf->pre_size += 2+2; /* 16b+16b */
|
||||
eaf->pcm_size = (2*eaf->v1_pcm_samples * channels_per_frame);
|
||||
|
||||
if (is_v1b) { /* extra 32b in v1b */
|
||||
fill_buf(ib, 32);
|
||||
rb_bits(is, 32,&eaf->v1_pcm_unknown);
|
||||
bm_get(is, 32,&eaf->v1_pcm_unknown);
|
||||
|
||||
eaf->pre_size += 4; /* 32b */
|
||||
|
||||
@ -363,19 +363,19 @@ static int ealayer3_parse_frame_v2(ealayer3_buffer_t* ib, ealayer3_frame_t* eaf)
|
||||
|
||||
/* read EA-frame V2 header */
|
||||
fill_buf(ib, 16);
|
||||
rb_bits(is, 1,&eaf->v2_extended_flag);
|
||||
rb_bits(is, 1,&eaf->v2_stereo_flag);
|
||||
rb_bits(is, 2,&eaf->v2_reserved);
|
||||
rb_bits(is, 12,&eaf->v2_frame_size);
|
||||
bm_get(is, 1,&eaf->v2_extended_flag);
|
||||
bm_get(is, 1,&eaf->v2_stereo_flag);
|
||||
bm_get(is, 2,&eaf->v2_reserved);
|
||||
bm_get(is, 12,&eaf->v2_frame_size);
|
||||
|
||||
eaf->pre_size = 2; /* 16b */
|
||||
|
||||
if (eaf->v2_extended_flag) {
|
||||
fill_buf(ib, 32);
|
||||
rb_bits(is, 2,&eaf->v2_offset_mode);
|
||||
rb_bits(is, 10,&eaf->v2_offset_samples);
|
||||
rb_bits(is, 10,&eaf->v2_pcm_samples);
|
||||
rb_bits(is, 10,&eaf->v2_common_size);
|
||||
bm_get(is, 2,&eaf->v2_offset_mode);
|
||||
bm_get(is, 10,&eaf->v2_offset_samples);
|
||||
bm_get(is, 10,&eaf->v2_pcm_samples);
|
||||
bm_get(is, 10,&eaf->v2_common_size);
|
||||
|
||||
eaf->pre_size += 4; /* 32b */
|
||||
}
|
||||
@ -423,16 +423,16 @@ static int ealayer3_parse_frame_common(ealayer3_buffer_t* ib, ealayer3_frame_t*
|
||||
static const int channel_table[4] = { 2,2,2, 1 }; /* [channel_mode] */
|
||||
|
||||
bitstream_t* is = &ib->is;
|
||||
off_t start_b_off = is->b_off;
|
||||
off_t start_b_off = bm_pos(is);
|
||||
int i, fill_bits, others_2_bits;
|
||||
|
||||
|
||||
/* read main header */
|
||||
fill_buf(ib, 8);
|
||||
rb_bits(is, 2,&eaf->version_index);
|
||||
rb_bits(is, 2,&eaf->sample_rate_index);
|
||||
rb_bits(is, 2,&eaf->channel_mode);
|
||||
rb_bits(is, 2,&eaf->mode_extension);
|
||||
bm_get(is, 2,&eaf->version_index);
|
||||
bm_get(is, 2,&eaf->sample_rate_index);
|
||||
bm_get(is, 2,&eaf->channel_mode);
|
||||
bm_get(is, 2,&eaf->mode_extension);
|
||||
|
||||
|
||||
/* check empty frame */
|
||||
@ -460,7 +460,7 @@ static int ealayer3_parse_frame_common(ealayer3_buffer_t* ib, ealayer3_frame_t*
|
||||
|
||||
/* read side info */
|
||||
fill_buf(ib, 1);
|
||||
rb_bits(is, 1,&eaf->granule_index);
|
||||
bm_get(is, 1,&eaf->granule_index);
|
||||
|
||||
fill_bits = (eaf->mpeg1 && eaf->granule_index == 1) ? 4 * eaf->channels : 0;
|
||||
fill_bits = fill_bits + (12 + 32 + others_2_bits) * eaf->channels;
|
||||
@ -468,21 +468,21 @@ static int ealayer3_parse_frame_common(ealayer3_buffer_t* ib, ealayer3_frame_t*
|
||||
|
||||
if (eaf->mpeg1 && eaf->granule_index == 1) {
|
||||
for (i = 0; i < eaf->channels; i++) {
|
||||
rb_bits(is, 4,&eaf->scfsi[i]);
|
||||
bm_get(is, 4,&eaf->scfsi[i]);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < eaf->channels; i++) {
|
||||
rb_bits(is, 12,&eaf->main_data_size[i]);
|
||||
bm_get(is, 12,&eaf->main_data_size[i]);
|
||||
/* divided in 47b=32+15 (MPEG1) or 51b=32+19 (MPEG2), arbitrarily */
|
||||
rb_bits(is, 32,&eaf->others_1[i]);
|
||||
rb_bits(is, others_2_bits,&eaf->others_2[i]);
|
||||
bm_get(is, 32,&eaf->others_1[i]);
|
||||
bm_get(is, others_2_bits,&eaf->others_2[i]);
|
||||
}
|
||||
|
||||
|
||||
/* derived */
|
||||
eaf->data_offset_b = is->b_off; /* header size + above size */
|
||||
eaf->base_size_b = (is->b_off - start_b_off); /* above size without header */
|
||||
eaf->data_offset_b = bm_pos(is); /* header size + above size */
|
||||
eaf->base_size_b = (bm_pos(is) - start_b_off); /* above size without header */
|
||||
for (i = 0; i < eaf->channels; i++) {
|
||||
eaf->data_size_b += eaf->main_data_size[i]; /* can be 0, meaning a micro EA-frame */
|
||||
}
|
||||
@ -490,7 +490,7 @@ static int ealayer3_parse_frame_common(ealayer3_buffer_t* ib, ealayer3_frame_t*
|
||||
eaf->padding_size_b = 8 - ((eaf->base_size_b+eaf->data_size_b) % 8);
|
||||
|
||||
fill_buf(ib, eaf->data_size_b + eaf->padding_size_b); /* read MPEG data (not PCM block) */
|
||||
is->b_off += eaf->data_size_b + eaf->padding_size_b;
|
||||
bm_skip(is, eaf->data_size_b + eaf->padding_size_b);
|
||||
|
||||
eaf->common_size = (eaf->base_size_b + eaf->data_size_b + eaf->padding_size_b)/8;
|
||||
|
||||
@ -542,55 +542,55 @@ static int ealayer3_rebuild_mpeg_frame(bitstream_t* is_0, ealayer3_frame_t* eaf_
|
||||
#endif
|
||||
|
||||
/* write MPEG1/2 frame header */
|
||||
wb_bits(os, 11, 0x7FF); /* sync */
|
||||
wb_bits(os, 2, eaf_0->version_index);
|
||||
wb_bits(os, 2, 0x01); /* layer III index */
|
||||
wb_bits(os, 1, 1); /* "no CRC" flag */
|
||||
wb_bits(os, 4, expected_bitrate_index);
|
||||
wb_bits(os, 2, eaf_0->sample_rate_index);
|
||||
wb_bits(os, 1, 0); /* padding */
|
||||
wb_bits(os, 1, 0); /* private */
|
||||
wb_bits(os, 2, eaf_0->channel_mode);
|
||||
wb_bits(os, 2, eaf_0->mode_extension);
|
||||
wb_bits(os, 1, 1); /* copyrighted */
|
||||
wb_bits(os, 1, 1); /* original */
|
||||
wb_bits(os, 2, 0); /* emphasis */
|
||||
bm_put(os, 11, 0x7FF); /* sync */
|
||||
bm_put(os, 2, eaf_0->version_index);
|
||||
bm_put(os, 2, 0x01); /* layer III index */
|
||||
bm_put(os, 1, 1); /* "no CRC" flag */
|
||||
bm_put(os, 4, expected_bitrate_index);
|
||||
bm_put(os, 2, eaf_0->sample_rate_index);
|
||||
bm_put(os, 1, 0); /* padding */
|
||||
bm_put(os, 1, 0); /* private */
|
||||
bm_put(os, 2, eaf_0->channel_mode);
|
||||
bm_put(os, 2, eaf_0->mode_extension);
|
||||
bm_put(os, 1, 1); /* copyrighted */
|
||||
bm_put(os, 1, 1); /* original */
|
||||
bm_put(os, 2, 0); /* emphasis */
|
||||
|
||||
if (eaf_0->mpeg1) {
|
||||
int private_bits = (eaf_0->channels==1 ? 5 : 3);
|
||||
|
||||
/* write MPEG1 side info */
|
||||
wb_bits(os, 9, 0); /* main data start (no bit reservoir) */
|
||||
wb_bits(os, private_bits, 0);
|
||||
bm_put(os, 9, 0); /* main data start (no bit reservoir) */
|
||||
bm_put(os, private_bits, 0);
|
||||
|
||||
for (i = 0; i < eaf_1->channels; i++) {
|
||||
wb_bits(os, 4, eaf_1->scfsi[i]); /* saved in granule1 only */
|
||||
bm_put(os, 4, eaf_1->scfsi[i]); /* saved in granule1 only */
|
||||
}
|
||||
for (i = 0; i < eaf_0->channels; i++) { /* granule0 */
|
||||
wb_bits(os, 12, eaf_0->main_data_size[i]);
|
||||
wb_bits(os, 32, eaf_0->others_1[i]);
|
||||
wb_bits(os, 47-32, eaf_0->others_2[i]);
|
||||
bm_put(os, 12, eaf_0->main_data_size[i]);
|
||||
bm_put(os, 32, eaf_0->others_1[i]);
|
||||
bm_put(os, 47-32, eaf_0->others_2[i]);
|
||||
}
|
||||
for (i = 0; i < eaf_1->channels; i++) { /* granule1 */
|
||||
wb_bits(os, 12, eaf_1->main_data_size[i]);
|
||||
wb_bits(os, 32, eaf_1->others_1[i]);
|
||||
wb_bits(os, 47-32, eaf_1->others_2[i]);
|
||||
bm_put(os, 12, eaf_1->main_data_size[i]);
|
||||
bm_put(os, 32, eaf_1->others_1[i]);
|
||||
bm_put(os, 47-32, eaf_1->others_2[i]);
|
||||
}
|
||||
|
||||
/* write MPEG1 main data */
|
||||
is_0->b_off = eaf_0->data_offset_b;
|
||||
bm_set(is_0, eaf_0->data_offset_b);
|
||||
for (i = 0; i < eaf_0->channels; i++) { /* granule0 */
|
||||
for (j = 0; j < eaf_0->main_data_size[i]; j++) {
|
||||
rb_bits(is_0, 1, &c);
|
||||
wb_bits(os, 1, c);
|
||||
bm_get(is_0, 1, &c);
|
||||
bm_put(os, 1, c);
|
||||
}
|
||||
}
|
||||
|
||||
is_1->b_off = eaf_1->data_offset_b;
|
||||
bm_set(is_1, eaf_1->data_offset_b);
|
||||
for (i = 0; i < eaf_1->channels; i++) { /* granule1 */
|
||||
for (j = 0; j < eaf_1->main_data_size[i]; j++) {
|
||||
rb_bits(is_1, 1, &c);
|
||||
wb_bits(os, 1, c);
|
||||
bm_get(is_1, 1, &c);
|
||||
bm_put(os, 1, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -598,43 +598,42 @@ static int ealayer3_rebuild_mpeg_frame(bitstream_t* is_0, ealayer3_frame_t* eaf_
|
||||
int private_bits = (eaf_0->channels==1 ? 1 : 2);
|
||||
|
||||
/* write MPEG2 side info */
|
||||
wb_bits(os, 8, 0); /* main data start (no bit reservoir) */
|
||||
wb_bits(os, private_bits, 0);
|
||||
bm_put(os, 8, 0); /* main data start (no bit reservoir) */
|
||||
bm_put(os, private_bits, 0);
|
||||
|
||||
for (i = 0; i < eaf_0->channels; i++) {
|
||||
wb_bits(os, 12, eaf_0->main_data_size[i]);
|
||||
wb_bits(os, 32, eaf_0->others_1[i]);
|
||||
wb_bits(os, 51-32, eaf_0->others_2[i]);
|
||||
bm_put(os, 12, eaf_0->main_data_size[i]);
|
||||
bm_put(os, 32, eaf_0->others_1[i]);
|
||||
bm_put(os, 51-32, eaf_0->others_2[i]);
|
||||
}
|
||||
|
||||
/* write MPEG2 main data */
|
||||
is_0->b_off = eaf_0->data_offset_b;
|
||||
bm_set(is_0, eaf_0->data_offset_b);
|
||||
for (i = 0; i < eaf_0->channels; i++) {
|
||||
for (j = 0; j < eaf_0->main_data_size[i]; j++) {
|
||||
rb_bits(is_0, 1, &c);
|
||||
wb_bits(os, 1, c);
|
||||
bm_get(is_0, 1, &c);
|
||||
bm_put(os, 1, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* align to closest 8b */
|
||||
if (os->b_off % 8) {
|
||||
int align_bits = 8 - (os->b_off % 8);
|
||||
wb_bits(os, align_bits, 0);
|
||||
if (bm_pos(os) % 8) {
|
||||
int align_bits = 8 - (bm_pos(os) % 8);
|
||||
bm_put(os, align_bits, 0);
|
||||
}
|
||||
|
||||
|
||||
if (os->b_off/8 > expected_frame_size) {
|
||||
if (bm_pos(os) / 8 > expected_frame_size) {
|
||||
/* bit reservoir! shouldn't happen with free bitrate, otherwise it's hard to fix as needs complex buffering/calcs */
|
||||
VGM_LOG("EAL3: written 0x%x but expected less than 0x%x\n", (uint32_t)(os->b_off/8), expected_frame_size);
|
||||
VGM_LOG("EAL3: written 0x%x but expected less than 0x%x\n", (uint32_t)(bm_pos(os) / 8), expected_frame_size);
|
||||
}
|
||||
else {
|
||||
/* fill ancillary data (should be ignored, but 0x00 seems to improve mpg123's free bitrate detection) */
|
||||
memset(os->buf + os->b_off/8, 0x00, expected_frame_size - os->b_off/8);
|
||||
memset(os->buf + bm_pos(os) / 8, 0x00, expected_frame_size - bm_pos(os) / 8);
|
||||
}
|
||||
|
||||
os->b_off = expected_frame_size*8;
|
||||
|
||||
bm_set(os, expected_frame_size * 8);
|
||||
|
||||
return 1;
|
||||
fail:
|
||||
@ -835,7 +834,7 @@ static int ealayer3_skip_data(VGMSTREAMCHANNEL* stream, mpeg_codec_data* data, i
|
||||
for (i = 0; i < skips; i++) {
|
||||
ib.sf = stream->streamfile;
|
||||
ib.offset = stream->offset;
|
||||
ib.is.buf = ib.buf;
|
||||
bm_setup(&ib.is, ib.buf, 0); // filled later
|
||||
|
||||
ok = ealayer3_parse_frame(data, num_stream, &ib, &eaf);
|
||||
if (!ok) goto fail;
|
||||
|
@ -84,7 +84,7 @@
|
||||
<ItemGroup>
|
||||
<ClInclude Include="coding\hca_decoder_clhca.h" />
|
||||
<ClInclude Include="coding\ice_decoder_icelib.h" />
|
||||
<ClInclude Include="coding\mpeg_bitreader.h" />
|
||||
<ClInclude Include="util\bitstream_msb.h" />
|
||||
<ClInclude Include="coding\mpeg_decoder.h" />
|
||||
<ClInclude Include="coding\vorbis_bitreader.h" />
|
||||
<ClInclude Include="coding\vorbis_custom_data_fsb.h" />
|
||||
|
@ -275,8 +275,8 @@
|
||||
<ClInclude Include="coding\hca_decoder_icelib.h">
|
||||
<Filter>coding\Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="coding\mpeg_bitreader.h">
|
||||
<Filter>coding\Header Files</Filter>
|
||||
<ClInclude Include="util\bitstream_msb.h">
|
||||
<Filter>util\Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="coding\mpeg_decoder.h">
|
||||
<Filter>coding\Header Files</Filter>
|
||||
|
@ -1,9 +1,10 @@
|
||||
#ifndef _MPEG_BITREADER_H
|
||||
#define _MPEG_BITREADER_H
|
||||
#ifndef _BITSTREAM_MSB_H
|
||||
#define _BITSTREAM_MSB_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* Simple bitreader for MPEG/standard bit format.
|
||||
* Kept in .h since it's slightly faster (compiler can optimize statics better) */
|
||||
|
||||
* Kept in .h since it's slightly faster (compiler can optimize better) */
|
||||
|
||||
typedef struct {
|
||||
uint8_t* buf; /* buffer to read/write */
|
||||
@ -12,15 +13,38 @@ typedef struct {
|
||||
uint32_t b_off; /* current offset in bits inside buffer */
|
||||
} bitstream_t;
|
||||
|
||||
/* convenience util */
|
||||
static inline void init_bitstream(bitstream_t* b, uint8_t* buf, size_t bufsize) {
|
||||
b->buf = buf;
|
||||
b->bufsize = bufsize;
|
||||
b->b_max = bufsize * 8;
|
||||
b->b_off = 0;
|
||||
|
||||
static inline void bm_setup(bitstream_t* bs, uint8_t* buf, size_t bufsize) {
|
||||
bs->buf = buf;
|
||||
bs->bufsize = bufsize;
|
||||
bs->b_max = bufsize * 8;
|
||||
bs->b_off = 0;
|
||||
}
|
||||
|
||||
static inline int bs_skip(bitstream_t* bs, uint32_t bits) {
|
||||
static inline int bm_set(bitstream_t* bs, uint32_t b_off) {
|
||||
if (bs->b_off > bs->b_max)
|
||||
goto fail;
|
||||
|
||||
bs->b_off = b_off;
|
||||
|
||||
return 1;
|
||||
fail:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int bm_fill(bitstream_t* bs, uint32_t bytes) {
|
||||
if (bs->b_off > bs->b_max)
|
||||
goto fail;
|
||||
|
||||
bs->bufsize += bytes;
|
||||
bs->b_max += bytes * 8;
|
||||
|
||||
return 1;
|
||||
fail:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int bm_skip(bitstream_t* bs, uint32_t bits) {
|
||||
if (bs->b_off + bits > bs->b_max)
|
||||
goto fail;
|
||||
|
||||
@ -31,12 +55,12 @@ fail:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int bs_pos(bitstream_t* bs) {
|
||||
static inline int bm_pos(bitstream_t* bs) {
|
||||
return bs->b_off;
|
||||
}
|
||||
|
||||
/* Read bits (max 32) from buf and update the bit offset. Order is BE (MSF). */
|
||||
static inline int rb_bits(bitstream_t* ib, uint32_t bits, uint32_t* value) {
|
||||
/* Read bits (max 32) from buf and update the bit offset. Order is BE (MSB). */
|
||||
static inline int bm_get(bitstream_t* ib, uint32_t bits, uint32_t* value) {
|
||||
uint32_t shift, pos, val;
|
||||
int i, bit_buf, bit_val;
|
||||
|
||||
@ -65,14 +89,13 @@ static inline int rb_bits(bitstream_t* ib, uint32_t bits, uint32_t* value) {
|
||||
ib->b_off += bits;
|
||||
return 1;
|
||||
fail:
|
||||
VGM_LOG("BITREADER: read fail\n");
|
||||
//VGM_LOG("BITREADER: read fail\n");
|
||||
*value = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef BITSTREAM_READ_ONLY
|
||||
/* Write bits (max 32) to buf and update the bit offset. Order is BE (MSF). */
|
||||
static inline int wb_bits(bitstream_t* ob, uint32_t bits, uint32_t value) {
|
||||
/* Write bits (max 32) to buf and update the bit offset. Order is BE (MSB). */
|
||||
static inline int bm_put(bitstream_t* ob, uint32_t bits, uint32_t value) {
|
||||
uint32_t shift, pos;
|
||||
int i, bit_val, bit_buf;
|
||||
|
||||
@ -103,6 +126,5 @@ static inline int wb_bits(bitstream_t* ob, uint32_t bits, uint32_t value) {
|
||||
fail:
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user