Skip to content

Commit 13d6308

Browse files
authored
64bit Bitstream reading and writing for very large codeword (#184)
* intial code (doesn't wokr) Signed-off-by: kp5.choi@samsung.com <kp5.choi@samsung.com> * intial working code Signed-off-by: kp5.choi@samsung.com <kp5.choi@samsung.com> * removed unused function Signed-off-by: kp5.choi@samsung.com <kp5.choi@samsung.com> --------- Signed-off-by: kp5.choi@samsung.com <kp5.choi@samsung.com>
1 parent 192317a commit 13d6308

4 files changed

Lines changed: 130 additions & 104 deletions

File tree

‎src/oapv.c‎

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -813,10 +813,11 @@ static int enc_tile_comp(oapv_bs_t *bs, oapve_tile_t *tile, oapve_ctx_t *ctx, oa
813813
oapv_bsw_write1(bs, 0);
814814
}
815815

816-
/* de-init BSW */
817-
oapv_bsw_deinit(bs);
816+
int enc_bytes = (u8*)oapv_bsw_sink(bs) - bs_cur;
817+
oapv_assert(enc_bytes > 0);
818818

819-
return (int)(bs->cur - bs_cur);
819+
oapv_bsw_deinit(bs);
820+
return enc_bytes;
820821
}
821822

822823
static int enc_tile(oapve_ctx_t *ctx, oapve_core_t *core, oapve_tile_t *tile)
@@ -906,15 +907,15 @@ static int enc_tile(oapve_ctx_t *ctx, oapve_core_t *core, oapve_tile_t *tile)
906907
tile->th.tile_data_size[c] = enc_tile_comp(&bs, tile, ctx, core, c, s_org, org, s_rec, rec);
907908
}
908909

909-
u32 bs_size = (int)(bs.cur - bs.beg);
910-
if(bs_size > tile->bs_buf_max) {
910+
u32 remained_bs_size = (int)((u8*)oapv_bsw_sink(&bs) - bs.beg);
911+
if(remained_bs_size > tile->bs_buf_max) {
911912
return OAPV_ERR_OUT_OF_BS_BUF;
912913
}
913-
tile->bs_size = bs_size;
914+
tile->bs_size = remained_bs_size;
914915

915916
oapv_bs_t bs_th;
916917
oapv_bsw_init(&bs_th, tile->bs_buf, tile->bs_size, NULL);
917-
tile->tile_size = bs_size - OAPV_TILE_SIZE_LEN;
918+
tile->tile_size = remained_bs_size - OAPV_TILE_SIZE_LEN;
918919

919920
DUMP_SAVE(1);
920921
DUMP_LOAD(0);
@@ -1124,8 +1125,7 @@ static int enc_frame(oapve_ctx_t *ctx, oapv_bs_t *bs)
11241125
oapve_set_frame_header(ctx, &ctx->fh);
11251126
oapve_vlc_frame_header(bs, ctx, &ctx->fh);
11261127

1127-
/* de-init BSW */
1128-
oapv_bsw_deinit(bs);
1128+
u8 *bs_tile_pos = oapv_bsw_sink(bs);
11291129

11301130
/* rc init */
11311131
u64 cost_sum = 0;
@@ -1171,16 +1171,16 @@ static int enc_frame(oapve_ctx_t *ctx, oapv_bs_t *bs)
11711171
/****************************************************/
11721172

11731173
for(int i = 0; i < ctx->num_tiles; i++) {
1174-
oapv_mcpy(bs->cur, ctx->tile[i].bs_buf, ctx->tile[i].bs_size);
1175-
bs->cur = bs->cur + ctx->tile[i].bs_size;
1174+
oapv_mcpy(bs_tile_pos, ctx->tile[i].bs_buf, ctx->tile[i].bs_size);
1175+
bs_tile_pos = bs_tile_pos + ctx->tile[i].bs_size;
11761176
ctx->fh.tile_size[i] = ctx->tile[i].bs_size - OAPV_TILE_SIZE_LEN;
11771177
}
1178+
BSW_MOVE_CUR(bs, bs_tile_pos); // move bs to at the end of tiles
11781179

11791180
/* rewrite frame header */
11801181
if(ctx->fh.tile_size_present_in_fh_flag) {
11811182
oapve_vlc_frame_header(&bs_fh, ctx, &ctx->fh);
1182-
/* de-init BSW */
1183-
oapv_bsw_sink(&bs_fh);
1183+
oapv_bsw_sink(&bs_fh); // make sure write bits to bs buffer
11841184
}
11851185
if(ctx->param->rc_type != 0) {
11861186
oapve_rc_update_after_pic(ctx, cost_sum);
@@ -1293,7 +1293,7 @@ int oapve_encode(oapve_t eid, oapv_frms_t *ifrms, oapvm_t mid, oapv_bitb_t *bitb
12931293
oapv_bs_t bsw;
12941294
oapve_ctx_t *ctx;
12951295
oapv_frm_t *frm;
1296-
oapv_bs_t *bs, bs_pbu_beg;
1296+
oapv_bs_t *bs;
12971297
int i, ret;
12981298
u8 *bs_pos_pbu_beg, *bs_pos_au_beg;
12991299

@@ -1320,10 +1320,8 @@ int oapve_encode(oapve_t eid, oapv_frms_t *ifrms, oapvm_t mid, oapv_bitb_t *bitb
13201320

13211321
// write headers
13221322
bs_pos_pbu_beg = oapv_bsw_sink(bs); /* store pbu pos to calculate size */
1323-
oapv_mcpy(&bs_pbu_beg, bs, sizeof(oapv_bs_t)); /* store pbu pos of ai to re-write */
1324-
13251323
DUMP_SAVE(0);
1326-
oapve_vlc_pbu_size(bs, 0);
1324+
oapv_bsw_write(bs, 0, 32); /* skip pbu_size syntax (later re-write) */
13271325
oapve_vlc_pbu_header(bs, frm->pbu_type, frm->group_id);
13281326
// encode a frame
13291327
ret = enc_frame(ctx, bs);
@@ -1333,7 +1331,8 @@ int oapve_encode(oapve_t eid, oapv_frms_t *ifrms, oapvm_t mid, oapv_bitb_t *bitb
13331331
int pbu_size = ((u8 *)oapv_bsw_sink(bs)) - bs_pos_pbu_beg - 4;
13341332
DUMP_SAVE(1);
13351333
DUMP_LOAD(0);
1336-
oapve_vlc_pbu_size(&bs_pbu_beg, pbu_size);
1334+
oapv_bsw_write_direct(bs_pos_pbu_beg, pbu_size, 32);
1335+
DUMP_HLS(pbu_size, pbu_size);
13371336
DUMP_LOAD(1);
13381337

13391338
stat->frm_size[i] = pbu_size + 4 /* PUB size length*/;
@@ -1362,18 +1361,17 @@ int oapve_encode(oapve_t eid, oapv_frms_t *ifrms, oapvm_t mid, oapv_bitb_t *bitb
13621361
for(i = 0; i < num_md; i++) {
13631362
int group_id = md_list->md_arr[i].group_id;
13641363
bs_pos_pbu_beg = oapv_bsw_sink(bs); /* store pbu pos to calculate size */
1365-
oapv_mcpy(&bs_pbu_beg, bs, sizeof(oapv_bs_t)); /* store pbu pos of ai to re-write */
13661364
DUMP_SAVE(0);
1367-
1368-
oapve_vlc_pbu_size(bs, 0);
1365+
oapv_bsw_write(bs, 0, 32); /* skip pbu_size syntax (later re-write) */
13691366
oapve_vlc_pbu_header(bs, OAPV_PBU_TYPE_METADATA, group_id);
13701367
oapve_vlc_metadata(&md_list->md_arr[i], bs);
13711368

13721369
// rewrite pbu_size
13731370
int pbu_size = ((u8 *)oapv_bsw_sink(bs)) - bs_pos_pbu_beg - 4;
13741371
DUMP_SAVE(1);
13751372
DUMP_LOAD(0);
1376-
oapve_vlc_pbu_size(&bs_pbu_beg, pbu_size);
1373+
oapv_bsw_write_direct(bs_pos_pbu_beg, pbu_size, 32);
1374+
DUMP_HLS(pbu_size, pbu_size);
13771375
DUMP_LOAD(1);
13781376
}
13791377
}

‎src/oapv_bs.c‎

Lines changed: 30 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
#if ENABLE_ENCODER
3737
///////////////////////////////////////////////////////////////////////////////
3838
/* number of bytes to be sunk */
39-
#define BSW_GET_SINK_BYTE(bs) ((32 - (bs)->leftbits + 7) >> 3)
39+
#define BSW_GET_SINK_BYTE(bs) ((64 - (bs)->leftbits + 7) >> 3)
4040

4141
static int bsw_flush(oapv_bs_t *bs, int bytes)
4242
{
@@ -46,11 +46,11 @@ static int bsw_flush(oapv_bs_t *bs, int bytes)
4646
oapv_assert_rv(bs->cur + bytes <= bs->end, -1);
4747

4848
while(bytes--) {
49-
*bs->cur++ = (bs->code >> 24) & 0xFF;
49+
*bs->cur++ = (bs->code >> 56) & 0xFF;
5050
bs->code <<= 8;
5151
}
5252

53-
bs->leftbits = 32;
53+
bs->leftbits = 64;
5454

5555
return 0;
5656
}
@@ -62,7 +62,7 @@ void oapv_bsw_init(oapv_bs_t *bs, u8 *buf, int size, oapv_bs_fn_flush_t fn_flush
6262
bs->cur = buf;
6363
bs->end = buf + size;
6464
bs->code = 0;
65-
bs->leftbits = 32;
65+
bs->leftbits = 64;
6666
bs->fn_flush = (fn_flush == NULL ? bsw_flush : fn_flush);
6767
}
6868

@@ -76,7 +76,7 @@ void *oapv_bsw_sink(oapv_bs_t *bs)
7676
oapv_assert_rv(bs->cur + BSW_GET_SINK_BYTE(bs) < bs->end, NULL);
7777
bs->fn_flush(bs, 0);
7878
bs->code = 0;
79-
bs->leftbits = 32;
79+
bs->leftbits = 64;
8080
return (void *)bs->cur;
8181
}
8282

@@ -107,32 +107,31 @@ int oapv_bsw_write1(oapv_bs_t *bs, int val)
107107
bs->fn_flush(bs, 0);
108108

109109
bs->code = 0;
110-
bs->leftbits = 32;
110+
bs->leftbits = 64;
111111
}
112112

113113
return 0;
114114
}
115115

116-
int oapv_bsw_write(oapv_bs_t *bs, u32 val, int len) /* len(1 ~ 32) */
116+
int oapv_bsw_write(oapv_bs_t *bs, u32 val, int len)
117117
{
118118
int leftbits;
119+
u64 code_t;
119120

120121
oapv_assert(bs);
121122

122123
leftbits = bs->leftbits;
123-
val <<= (32 - len);
124-
bs->code |= (val >> (32 - leftbits));
124+
code_t = ((u64)val) << (64 - len);
125+
bs->code |= (code_t >> (64 - leftbits));
125126

126127
if(len < leftbits) {
127128
bs->leftbits -= len;
128129
}
129130
else {
130-
bs->leftbits = 0;
131-
bs->fn_flush(bs, 0);
132-
bs->code = (leftbits < 32 ? val << leftbits : 0);
133-
bs->leftbits = 32 - (len - leftbits);
131+
bs->fn_flush(bs, 8);
132+
bs->code = code_t << leftbits;
133+
bs->leftbits = 64 - (len - leftbits);
134134
}
135-
136135
return 0;
137136
}
138137

@@ -156,7 +155,7 @@ static void inline bsr_skip_code(oapv_bs_t *bs, int size)
156155
{
157156
oapv_assert(size <= 32);
158157
oapv_assert(bs->leftbits >= size);
159-
if(size == 32) {
158+
if(size == 64) {
160159
bs->code = 0;
161160
bs->leftbits = 0;
162161
}
@@ -168,8 +167,8 @@ static void inline bsr_skip_code(oapv_bs_t *bs, int size)
168167

169168
static int bsr_flush(oapv_bs_t *bs, int byte)
170169
{
171-
int shift = 24, remained;
172-
u32 code = 0;
170+
int shift = 56, remained;
171+
u64 code = 0;
173172

174173
oapv_assert(byte);
175174

@@ -186,7 +185,7 @@ static int bsr_flush(oapv_bs_t *bs, int byte)
186185
bs->leftbits = byte << 3;
187186

188187
while(byte) {
189-
code |= *(bs->cur++) << shift;
188+
code |= (u64)(*(bs->cur++)) << shift;
190189
byte--;
191190
shift -= 8;
192191
}
@@ -210,11 +209,11 @@ int oapv_bsr_clz_in_code(u32 code)
210209
int clz, bits4, shift;
211210

212211
if(code == 0)
213-
return 32; /* to protect infinite loop */
212+
return 64; /* to protect infinite loop */
214213

215214
bits4 = 0;
216215
clz = 0;
217-
shift = 28;
216+
shift = 56;
218217

219218
while(bits4 == 0 && shift >= 0) {
220219
bits4 = (code >> shift) & 0xf;
@@ -229,7 +228,7 @@ int oapv_bsr_clz(oapv_bs_t *bs)
229228
int clz;
230229
u32 code;
231230

232-
code = oapv_bsr_peek(bs, 32);
231+
code = oapv_bsr_peek(bs, 64); /* supports max 64bit codeword */
233232
oapv_assert(code != 0);
234233
clz = oapv_bsr_clz_in_code(code);
235234
return clz;
@@ -256,7 +255,7 @@ void oapv_bsr_skip(oapv_bs_t *bs, int size)
256255

257256
if(bs->leftbits < size) {
258257
size -= bs->leftbits;
259-
if(bs->fn_flush(bs, 4)) {
258+
if(bs->fn_flush(bs, 8)) {
260259
// oapv_trace("already reached the end of bitstream\n"); /* should be updated */
261260
return;
262261
}
@@ -270,7 +269,7 @@ u32 oapv_bsr_peek(oapv_bs_t *bs, int size)
270269
u32 code = 0;
271270

272271
if(bs->leftbits < size) {
273-
byte = (32 - bs->leftbits) >> 3;
272+
byte = (64 - bs->leftbits) >> 3;
274273

275274
/* We should not check the return value
276275
because this function could be failed at the EOB. */
@@ -286,9 +285,9 @@ u32 oapv_bsr_peek(oapv_bs_t *bs, int size)
286285
}
287286
}
288287

289-
oapv_assert(bs->leftbits <= 32);
288+
oapv_assert(bs->leftbits <= 64);
290289

291-
code = bs->code >> (32 - size);
290+
code = bs->code >> (64 - size);
292291
size -= bs->leftbits;
293292

294293
if(size > 0) {
@@ -327,14 +326,14 @@ u32 oapv_bsr_read(oapv_bs_t *bs, int size)
327326
oapv_assert(size > 0);
328327

329328
if(bs->leftbits < size) {
330-
code = bs->code >> (32 - size);
329+
code = bs->code >> (64 - size);
331330
size -= bs->leftbits;
332-
if(bs->fn_flush(bs, 4)) {
331+
if(bs->fn_flush(bs, 8)) {
333332
oapv_trace("already reached the end of bitstream\n"); /* should be updated */
334333
return (u32)(-1);
335334
}
336335
}
337-
code |= bs->code >> (32 - size);
336+
code |= (u32)(bs->code >> (64 - size));
338337

339338
bsr_skip_code(bs, size);
340339

@@ -345,12 +344,12 @@ int oapv_bsr_read1(oapv_bs_t *bs)
345344
{
346345
int code;
347346
if(bs->leftbits == 0) {
348-
if(bs->fn_flush(bs, 4)) {
347+
if(bs->fn_flush(bs, 8)) {
349348
oapv_trace("already reached the end of bitstream\n"); /* should be updated */
350349
return -1;
351350
}
352351
}
353-
code = (int)(bs->code >> 31);
352+
code = (int)(bs->code >> 63);
354353

355354
bs->code <<= 1;
356355
bs->leftbits -= 1;
@@ -373,8 +372,7 @@ u32 oapv_bsr_read_direct(void *addr, int len)
373372
byte--;
374373
p++;
375374
}
376-
code = code >> (32 - len);
377-
return code;
375+
return (code >> (32 - len));
378376
}
379377

380378

‎src/oapv_bs.h‎

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ typedef struct oapv_bs oapv_bs_t;
3838
typedef int (*oapv_bs_fn_flush_t)(oapv_bs_t *bs, int byte);
3939

4040
struct oapv_bs {
41-
u32 code; // intermediate code buffer
41+
u64 code; // intermediate code buffer
4242
int leftbits; // left bits count in code
4343
u8 *cur; // address of current bitstream position
4444
u8 *end; // address of bitstream end
@@ -54,6 +54,12 @@ struct oapv_bs {
5454
#if ENABLE_ENCODER
5555
///////////////////////////////////////////////////////////////////////////////
5656

57+
/* move current write position to a specific bitstream address */
58+
#define BSW_MOVE_CUR(bs, addr) \
59+
(bs)->cur = addr; \
60+
(bs)->code = 0; \
61+
(bs)->leftbits = 64;
62+
5763
static inline bool bsw_is_align8(oapv_bs_t *bs)
5864
{
5965
return (bool)(!((bs)->leftbits & 0x7));
@@ -94,7 +100,8 @@ should set zero in that case. */
94100
#endif
95101
#else
96102
#define BSR_SKIP_CODE(bs, size) \
97-
oapv_assert((bs)->leftbits >= (size) && (size) <= 32); \
103+
/* 64bit is missing here to avoid the arithmetic left shift */ \
104+
oapv_assert((bs)->leftbits >= (size) && (size) < 64); \
98105
(bs)->code <<= (size); (bs)->leftbits -= (size);
99106
#endif
100107

0 commit comments

Comments
 (0)