Move and wrap the old vpx boolcoder.
This should make room for compile time pluggable replacements.
Change-Id: Ib7afcffa93bf664b89a49da21a20138127443292
(cherry picked from commit 9dd0b89824
)
This commit is contained in:
Родитель
e54fd03c5a
Коммит
eb00cb289b
|
@ -22,7 +22,8 @@ DSP_SRCS-yes += prob.c
|
||||||
|
|
||||||
ifeq ($(CONFIG_ENCODERS),yes)
|
ifeq ($(CONFIG_ENCODERS),yes)
|
||||||
DSP_SRCS-yes += bitwriter.h
|
DSP_SRCS-yes += bitwriter.h
|
||||||
DSP_SRCS-yes += bitwriter.c
|
DSP_SRCS-yes += dkboolwriter.h
|
||||||
|
DSP_SRCS-yes += dkboolwriter.c
|
||||||
DSP_SRCS-yes += bitwriter_buffer.c
|
DSP_SRCS-yes += bitwriter_buffer.c
|
||||||
DSP_SRCS-yes += bitwriter_buffer.h
|
DSP_SRCS-yes += bitwriter_buffer.h
|
||||||
DSP_SRCS-yes += psnr.c
|
DSP_SRCS-yes += psnr.c
|
||||||
|
@ -35,7 +36,8 @@ endif
|
||||||
|
|
||||||
ifeq ($(CONFIG_DECODERS),yes)
|
ifeq ($(CONFIG_DECODERS),yes)
|
||||||
DSP_SRCS-yes += bitreader.h
|
DSP_SRCS-yes += bitreader.h
|
||||||
DSP_SRCS-yes += bitreader.c
|
DSP_SRCS-yes += dkboolreader.h
|
||||||
|
DSP_SRCS-yes += dkboolreader.c
|
||||||
DSP_SRCS-yes += bitreader_buffer.c
|
DSP_SRCS-yes += bitreader_buffer.c
|
||||||
DSP_SRCS-yes += bitreader_buffer.h
|
DSP_SRCS-yes += bitreader_buffer.h
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -12,147 +12,45 @@
|
||||||
#ifndef AOM_DSP_BITREADER_H_
|
#ifndef AOM_DSP_BITREADER_H_
|
||||||
#define AOM_DSP_BITREADER_H_
|
#define AOM_DSP_BITREADER_H_
|
||||||
|
|
||||||
#include <limits.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
#include "./aom_config.h"
|
#include "./aom_config.h"
|
||||||
|
|
||||||
#if CONFIG_BITSTREAM_DEBUG
|
|
||||||
#include <assert.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#endif // CONFIG_BITSTREAM_DEBUG
|
|
||||||
|
|
||||||
#include "aom_ports/mem.h"
|
|
||||||
#include "aom/aomdx.h"
|
#include "aom/aomdx.h"
|
||||||
#include "aom/aom_integer.h"
|
#include "aom/aom_integer.h"
|
||||||
|
#include "aom_dsp/dkboolreader.h"
|
||||||
#include "aom_dsp/prob.h"
|
#include "aom_dsp/prob.h"
|
||||||
#include "aom_util/debug_util.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef size_t BD_VALUE;
|
typedef struct aom_dk_reader aom_reader;
|
||||||
|
|
||||||
#define BD_VALUE_SIZE ((int)sizeof(BD_VALUE) * CHAR_BIT)
|
static INLINE int aom_reader_init(aom_reader *r, const uint8_t *buffer,
|
||||||
|
size_t size, aom_decrypt_cb decrypt_cb,
|
||||||
|
void *decrypt_state) {
|
||||||
|
return aom_dk_reader_init(r, buffer, size, decrypt_cb, decrypt_state);
|
||||||
|
}
|
||||||
|
|
||||||
// This is meant to be a large, positive constant that can still be efficiently
|
static INLINE const uint8_t *aom_reader_find_end(aom_reader *r) {
|
||||||
// loaded as an immediate (on platforms like ARM, for example).
|
return aom_dk_reader_find_end(r);
|
||||||
// Even relatively modest values like 100 would work fine.
|
}
|
||||||
#define LOTS_OF_BITS 0x40000000
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
// Be careful when reordering this struct, it may impact the cache negatively.
|
|
||||||
BD_VALUE value;
|
|
||||||
unsigned int range;
|
|
||||||
int count;
|
|
||||||
const uint8_t *buffer_end;
|
|
||||||
const uint8_t *buffer;
|
|
||||||
aom_decrypt_cb decrypt_cb;
|
|
||||||
void *decrypt_state;
|
|
||||||
uint8_t clear_buffer[sizeof(BD_VALUE) + 1];
|
|
||||||
} aom_reader;
|
|
||||||
|
|
||||||
int aom_reader_init(aom_reader *r, const uint8_t *buffer, size_t size,
|
|
||||||
aom_decrypt_cb decrypt_cb, void *decrypt_state);
|
|
||||||
|
|
||||||
void aom_reader_fill(aom_reader *r);
|
|
||||||
|
|
||||||
const uint8_t *aom_reader_find_end(aom_reader *r);
|
|
||||||
|
|
||||||
static INLINE int aom_reader_has_error(aom_reader *r) {
|
static INLINE int aom_reader_has_error(aom_reader *r) {
|
||||||
// Check if we have reached the end of the buffer.
|
return aom_dk_reader_has_error(r);
|
||||||
//
|
|
||||||
// Variable 'count' stores the number of bits in the 'value' buffer, minus
|
|
||||||
// 8. The top byte is part of the algorithm, and the remainder is buffered
|
|
||||||
// to be shifted into it. So if count == 8, the top 16 bits of 'value' are
|
|
||||||
// occupied, 8 for the algorithm and 8 in the buffer.
|
|
||||||
//
|
|
||||||
// When reading a byte from the user's buffer, count is filled with 8 and
|
|
||||||
// one byte is filled into the value buffer. When we reach the end of the
|
|
||||||
// data, count is additionally filled with LOTS_OF_BITS. So when
|
|
||||||
// count == LOTS_OF_BITS - 1, the user's data has been exhausted.
|
|
||||||
//
|
|
||||||
// 1 if we have tried to decode bits after the end of stream was encountered.
|
|
||||||
// 0 No error.
|
|
||||||
return r->count > BD_VALUE_SIZE && r->count < LOTS_OF_BITS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static INLINE int aom_read(aom_reader *r, int prob) {
|
static INLINE int aom_read(aom_reader *r, int prob) {
|
||||||
unsigned int bit = 0;
|
return aom_dk_read(r, prob);
|
||||||
BD_VALUE value;
|
|
||||||
BD_VALUE bigsplit;
|
|
||||||
int count;
|
|
||||||
unsigned int range;
|
|
||||||
unsigned int split = (r->range * prob + (256 - prob)) >> CHAR_BIT;
|
|
||||||
|
|
||||||
if (r->count < 0) aom_reader_fill(r);
|
|
||||||
|
|
||||||
value = r->value;
|
|
||||||
count = r->count;
|
|
||||||
|
|
||||||
bigsplit = (BD_VALUE)split << (BD_VALUE_SIZE - CHAR_BIT);
|
|
||||||
|
|
||||||
range = split;
|
|
||||||
|
|
||||||
if (value >= bigsplit) {
|
|
||||||
range = r->range - split;
|
|
||||||
value = value - bigsplit;
|
|
||||||
bit = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
register int shift = aom_norm[range];
|
|
||||||
range <<= shift;
|
|
||||||
value <<= shift;
|
|
||||||
count -= shift;
|
|
||||||
}
|
|
||||||
r->value = value;
|
|
||||||
r->count = count;
|
|
||||||
r->range = range;
|
|
||||||
|
|
||||||
#if CONFIG_BITSTREAM_DEBUG
|
|
||||||
{
|
|
||||||
int ref_bit, ref_prob;
|
|
||||||
const int queue_r = bitstream_queue_get_read();
|
|
||||||
const int frame_idx = bitstream_queue_get_frame_read();
|
|
||||||
bitstream_queue_pop(&ref_bit, &ref_prob);
|
|
||||||
if (prob != ref_prob) {
|
|
||||||
fprintf(
|
|
||||||
stderr,
|
|
||||||
"\n *** prob error, frame_idx_r %d prob %d ref_prob %d queue_r %d\n",
|
|
||||||
frame_idx, prob, ref_prob, queue_r);
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
if ((int)bit != ref_bit) {
|
|
||||||
fprintf(stderr, "\n *** bit error, frame_idx_r %d bit %d ref_bit %d\n",
|
|
||||||
frame_idx, bit, ref_bit);
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif // CONFIG_BITSTREAM_DEBUG
|
|
||||||
return bit;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static INLINE int aom_read_bit(aom_reader *r) {
|
static INLINE int aom_read_bit(aom_reader *r) { return aom_dk_read_bit(r); }
|
||||||
return aom_read(r, 128); // aom_prob_half
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE int aom_read_literal(aom_reader *r, int bits) {
|
static INLINE int aom_read_literal(aom_reader *r, int bits) {
|
||||||
int literal = 0, bit;
|
return aom_dk_read_literal(r, bits);
|
||||||
|
|
||||||
for (bit = bits - 1; bit >= 0; bit--) literal |= aom_read_bit(r) << bit;
|
|
||||||
|
|
||||||
return literal;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static INLINE int aom_read_tree(aom_reader *r, const aom_tree_index *tree,
|
static INLINE int aom_read_tree(aom_reader *r, const aom_tree_index *tree,
|
||||||
const aom_prob *probs) {
|
const aom_prob *probs) {
|
||||||
aom_tree_index i = 0;
|
return aom_dk_read_tree(r, tree, probs);
|
||||||
|
|
||||||
while ((i = tree[i + aom_read(r, probs[i >> 1])]) > 0) continue;
|
|
||||||
|
|
||||||
return -i;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
@ -12,103 +12,33 @@
|
||||||
#ifndef AOM_DSP_BITWRITER_H_
|
#ifndef AOM_DSP_BITWRITER_H_
|
||||||
#define AOM_DSP_BITWRITER_H_
|
#define AOM_DSP_BITWRITER_H_
|
||||||
|
|
||||||
#include "./aom_config.h"
|
#include "aom_dsp/dkboolwriter.h"
|
||||||
|
|
||||||
#if CONFIG_BITSTREAM_DEBUG
|
|
||||||
#include <stdio.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "aom_ports/mem.h"
|
|
||||||
#include "aom_dsp/prob.h"
|
#include "aom_dsp/prob.h"
|
||||||
#include "aom_util/debug_util.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct aom_writer {
|
typedef struct aom_dk_writer aom_writer;
|
||||||
unsigned int lowvalue;
|
|
||||||
unsigned int range;
|
|
||||||
int count;
|
|
||||||
unsigned int pos;
|
|
||||||
uint8_t *buffer;
|
|
||||||
} aom_writer;
|
|
||||||
|
|
||||||
void aom_start_encode(aom_writer *bc, uint8_t *buffer);
|
static INLINE void aom_start_encode(aom_writer *bc, uint8_t *buffer) {
|
||||||
void aom_stop_encode(aom_writer *bc);
|
aom_dk_start_encode(bc, buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
static INLINE void aom_stop_encode(aom_writer *bc) { aom_dk_stop_encode(bc); }
|
||||||
|
|
||||||
static INLINE void aom_write(aom_writer *br, int bit, int probability) {
|
static INLINE void aom_write(aom_writer *br, int bit, int probability) {
|
||||||
unsigned int split;
|
aom_dk_write(br, bit, probability);
|
||||||
int count = br->count;
|
|
||||||
unsigned int range = br->range;
|
|
||||||
unsigned int lowvalue = br->lowvalue;
|
|
||||||
register int shift;
|
|
||||||
|
|
||||||
#if CONFIG_BITSTREAM_DEBUG
|
|
||||||
// int queue_r = 0;
|
|
||||||
// int frame_idx_r = 0;
|
|
||||||
// int queue_w = bitstream_queue_get_write();
|
|
||||||
// int frame_idx_w = bitstream_queue_get_frame_write();
|
|
||||||
// if (frame_idx_w == frame_idx_r && queue_w == queue_r) {
|
|
||||||
// fprintf(stderr, "\n *** bitstream queue at frame_idx_w %d queue_w %d\n",
|
|
||||||
// frame_idx_w, queue_w);
|
|
||||||
// }
|
|
||||||
bitstream_queue_push(bit, probability);
|
|
||||||
#endif // CONFIG_BITSTREAM_DEBUG
|
|
||||||
|
|
||||||
split = 1 + (((range - 1) * probability) >> 8);
|
|
||||||
|
|
||||||
range = split;
|
|
||||||
|
|
||||||
if (bit) {
|
|
||||||
lowvalue += split;
|
|
||||||
range = br->range - split;
|
|
||||||
}
|
|
||||||
|
|
||||||
shift = aom_norm[range];
|
|
||||||
|
|
||||||
range <<= shift;
|
|
||||||
count += shift;
|
|
||||||
|
|
||||||
if (count >= 0) {
|
|
||||||
int offset = shift - count;
|
|
||||||
|
|
||||||
if ((lowvalue << (offset - 1)) & 0x80000000) {
|
|
||||||
int x = br->pos - 1;
|
|
||||||
|
|
||||||
while (x >= 0 && br->buffer[x] == 0xff) {
|
|
||||||
br->buffer[x] = 0;
|
|
||||||
x--;
|
|
||||||
}
|
|
||||||
|
|
||||||
br->buffer[x] += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
br->buffer[br->pos++] = (lowvalue >> (24 - offset));
|
|
||||||
lowvalue <<= offset;
|
|
||||||
shift = count;
|
|
||||||
lowvalue &= 0xffffff;
|
|
||||||
count -= 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
lowvalue <<= shift;
|
|
||||||
br->count = count;
|
|
||||||
br->lowvalue = lowvalue;
|
|
||||||
br->range = range;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static INLINE void aom_write_bit(aom_writer *w, int bit) {
|
static INLINE void aom_write_bit(aom_writer *w, int bit) {
|
||||||
aom_write(w, bit, 128); // aom_prob_half
|
aom_dk_write_bit(w, bit);
|
||||||
}
|
}
|
||||||
|
|
||||||
static INLINE void aom_write_literal(aom_writer *w, int data, int bits) {
|
static INLINE void aom_write_literal(aom_writer *w, int data, int bits) {
|
||||||
int bit;
|
aom_dk_write_literal(w, data, bits);
|
||||||
|
|
||||||
for (bit = bits - 1; bit >= 0; bit--) aom_write_bit(w, 1 & (data >> bit));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define aom_write_prob(w, v) aom_write_literal((w), (v), 8)
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -11,15 +11,16 @@
|
||||||
|
|
||||||
#include "./aom_config.h"
|
#include "./aom_config.h"
|
||||||
|
|
||||||
#include "aom_dsp/bitreader.h"
|
#include "aom_dsp/dkboolreader.h"
|
||||||
#include "aom_dsp/prob.h"
|
#include "aom_dsp/prob.h"
|
||||||
#include "aom_dsp/aom_dsp_common.h"
|
#include "aom_dsp/aom_dsp_common.h"
|
||||||
#include "aom_ports/mem.h"
|
#include "aom_ports/mem.h"
|
||||||
#include "aom_mem/aom_mem.h"
|
#include "aom_mem/aom_mem.h"
|
||||||
#include "aom_util/endian_inl.h"
|
#include "aom_util/endian_inl.h"
|
||||||
|
|
||||||
int aom_reader_init(aom_reader *r, const uint8_t *buffer, size_t size,
|
int aom_dk_reader_init(struct aom_dk_reader *r, const uint8_t *buffer,
|
||||||
aom_decrypt_cb decrypt_cb, void *decrypt_state) {
|
size_t size, aom_decrypt_cb decrypt_cb,
|
||||||
|
void *decrypt_state) {
|
||||||
if (size && !buffer) {
|
if (size && !buffer) {
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
|
@ -30,12 +31,12 @@ int aom_reader_init(aom_reader *r, const uint8_t *buffer, size_t size,
|
||||||
r->range = 255;
|
r->range = 255;
|
||||||
r->decrypt_cb = decrypt_cb;
|
r->decrypt_cb = decrypt_cb;
|
||||||
r->decrypt_state = decrypt_state;
|
r->decrypt_state = decrypt_state;
|
||||||
aom_reader_fill(r);
|
aom_dk_reader_fill(r);
|
||||||
return aom_read_bit(r) != 0; // marker bit
|
return aom_dk_read_bit(r) != 0; // marker bit
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void aom_reader_fill(aom_reader *r) {
|
void aom_dk_reader_fill(struct aom_dk_reader *r) {
|
||||||
const uint8_t *const buffer_end = r->buffer_end;
|
const uint8_t *const buffer_end = r->buffer_end;
|
||||||
const uint8_t *buffer = r->buffer;
|
const uint8_t *buffer = r->buffer;
|
||||||
const uint8_t *buffer_start = buffer;
|
const uint8_t *buffer_start = buffer;
|
||||||
|
@ -90,7 +91,7 @@ void aom_reader_fill(aom_reader *r) {
|
||||||
r->count = count;
|
r->count = count;
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint8_t *aom_reader_find_end(aom_reader *r) {
|
const uint8_t *aom_dk_reader_find_end(struct aom_dk_reader *r) {
|
||||||
// Find the end of the coded buffer
|
// Find the end of the coded buffer
|
||||||
while (r->count > CHAR_BIT && r->count < BD_VALUE_SIZE) {
|
while (r->count > CHAR_BIT && r->count < BD_VALUE_SIZE) {
|
||||||
r->count -= CHAR_BIT;
|
r->count -= CHAR_BIT;
|
|
@ -0,0 +1,164 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||||
|
*
|
||||||
|
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||||
|
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||||
|
* was not distributed with this source code in the LICENSE file, you can
|
||||||
|
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||||
|
* Media Patent License 1.0 was not distributed with this source code in the
|
||||||
|
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef AOM_DSP_DKBOOLREADER_H_
|
||||||
|
#define AOM_DSP_DKBOOLREADER_H_
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
|
#include "./aom_config.h"
|
||||||
|
#if CONFIG_BITSTREAM_DEBUG
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#endif // CONFIG_BITSTREAM_DEBUG
|
||||||
|
|
||||||
|
#include "aom_ports/mem.h"
|
||||||
|
#include "aom/aomdx.h"
|
||||||
|
#include "aom/aom_integer.h"
|
||||||
|
#include "aom_dsp/prob.h"
|
||||||
|
#include "aom_util/debug_util.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef size_t BD_VALUE;
|
||||||
|
|
||||||
|
#define BD_VALUE_SIZE ((int)sizeof(BD_VALUE) * CHAR_BIT)
|
||||||
|
|
||||||
|
// This is meant to be a large, positive constant that can still be efficiently
|
||||||
|
// loaded as an immediate (on platforms like ARM, for example).
|
||||||
|
// Even relatively modest values like 100 would work fine.
|
||||||
|
#define LOTS_OF_BITS 0x40000000
|
||||||
|
|
||||||
|
struct aom_dk_reader {
|
||||||
|
// Be careful when reordering this struct, it may impact the cache negatively.
|
||||||
|
BD_VALUE value;
|
||||||
|
unsigned int range;
|
||||||
|
int count;
|
||||||
|
const uint8_t *buffer_end;
|
||||||
|
const uint8_t *buffer;
|
||||||
|
aom_decrypt_cb decrypt_cb;
|
||||||
|
void *decrypt_state;
|
||||||
|
uint8_t clear_buffer[sizeof(BD_VALUE) + 1];
|
||||||
|
};
|
||||||
|
|
||||||
|
int aom_dk_reader_init(struct aom_dk_reader *r, const uint8_t *buffer,
|
||||||
|
size_t size, aom_decrypt_cb decrypt_cb,
|
||||||
|
void *decrypt_state);
|
||||||
|
|
||||||
|
void aom_dk_reader_fill(struct aom_dk_reader *r);
|
||||||
|
|
||||||
|
const uint8_t *aom_dk_reader_find_end(struct aom_dk_reader *r);
|
||||||
|
|
||||||
|
static INLINE int aom_dk_reader_has_error(struct aom_dk_reader *r) {
|
||||||
|
// Check if we have reached the end of the buffer.
|
||||||
|
//
|
||||||
|
// Variable 'count' stores the number of bits in the 'value' buffer, minus
|
||||||
|
// 8. The top byte is part of the algorithm, and the remainder is buffered
|
||||||
|
// to be shifted into it. So if count == 8, the top 16 bits of 'value' are
|
||||||
|
// occupied, 8 for the algorithm and 8 in the buffer.
|
||||||
|
//
|
||||||
|
// When reading a byte from the user's buffer, count is filled with 8 and
|
||||||
|
// one byte is filled into the value buffer. When we reach the end of the
|
||||||
|
// data, count is additionally filled with LOTS_OF_BITS. So when
|
||||||
|
// count == LOTS_OF_BITS - 1, the user's data has been exhausted.
|
||||||
|
//
|
||||||
|
// 1 if we have tried to decode bits after the end of stream was encountered.
|
||||||
|
// 0 No error.
|
||||||
|
return r->count > BD_VALUE_SIZE && r->count < LOTS_OF_BITS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static INLINE int aom_dk_read(struct aom_dk_reader *r, int prob) {
|
||||||
|
unsigned int bit = 0;
|
||||||
|
BD_VALUE value;
|
||||||
|
BD_VALUE bigsplit;
|
||||||
|
int count;
|
||||||
|
unsigned int range;
|
||||||
|
unsigned int split = (r->range * prob + (256 - prob)) >> CHAR_BIT;
|
||||||
|
|
||||||
|
if (r->count < 0) aom_dk_reader_fill(r);
|
||||||
|
|
||||||
|
value = r->value;
|
||||||
|
count = r->count;
|
||||||
|
|
||||||
|
bigsplit = (BD_VALUE)split << (BD_VALUE_SIZE - CHAR_BIT);
|
||||||
|
|
||||||
|
range = split;
|
||||||
|
|
||||||
|
if (value >= bigsplit) {
|
||||||
|
range = r->range - split;
|
||||||
|
value = value - bigsplit;
|
||||||
|
bit = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
register int shift = aom_norm[range];
|
||||||
|
range <<= shift;
|
||||||
|
value <<= shift;
|
||||||
|
count -= shift;
|
||||||
|
}
|
||||||
|
r->value = value;
|
||||||
|
r->count = count;
|
||||||
|
r->range = range;
|
||||||
|
|
||||||
|
#if CONFIG_BITSTREAM_DEBUG
|
||||||
|
{
|
||||||
|
int ref_bit, ref_prob;
|
||||||
|
const int queue_r = bitstream_queue_get_read();
|
||||||
|
const int frame_idx = bitstream_queue_get_frame_read();
|
||||||
|
bitstream_queue_pop(&ref_bit, &ref_prob);
|
||||||
|
if (prob != ref_prob) {
|
||||||
|
fprintf(
|
||||||
|
stderr,
|
||||||
|
"\n *** prob error, frame_idx_r %d prob %d ref_prob %d queue_r %d\n",
|
||||||
|
frame_idx, prob, ref_prob, queue_r);
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
if ((int)bit != ref_bit) {
|
||||||
|
fprintf(stderr, "\n *** bit error, frame_idx_r %d bit %d ref_bit %d\n",
|
||||||
|
frame_idx, bit, ref_bit);
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // CONFIG_BITSTREAM_DEBUG
|
||||||
|
|
||||||
|
return bit;
|
||||||
|
}
|
||||||
|
|
||||||
|
static INLINE int aom_dk_read_bit(struct aom_dk_reader *r) {
|
||||||
|
return aom_dk_read(r, 128); // aom_prob_half
|
||||||
|
}
|
||||||
|
|
||||||
|
static INLINE int aom_dk_read_literal(struct aom_dk_reader *r, int bits) {
|
||||||
|
int literal = 0, bit;
|
||||||
|
|
||||||
|
for (bit = bits - 1; bit >= 0; bit--) literal |= aom_dk_read_bit(r) << bit;
|
||||||
|
|
||||||
|
return literal;
|
||||||
|
}
|
||||||
|
|
||||||
|
static INLINE int aom_dk_read_tree(struct aom_dk_reader *r,
|
||||||
|
const aom_tree_index *tree,
|
||||||
|
const aom_prob *probs) {
|
||||||
|
aom_tree_index i = 0;
|
||||||
|
|
||||||
|
while ((i = tree[i + aom_dk_read(r, probs[i >> 1])]) > 0) continue;
|
||||||
|
|
||||||
|
return -i;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} // extern "C"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // AOM_DSP_DKBOOLREADER_H_
|
|
@ -10,25 +10,25 @@
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#include "./bitwriter.h"
|
#include "./dkboolwriter.h"
|
||||||
|
|
||||||
void aom_start_encode(aom_writer *br, uint8_t *source) {
|
void aom_dk_start_encode(aom_dk_writer *br, uint8_t *source) {
|
||||||
br->lowvalue = 0;
|
br->lowvalue = 0;
|
||||||
br->range = 255;
|
br->range = 255;
|
||||||
br->count = -24;
|
br->count = -24;
|
||||||
br->buffer = source;
|
br->buffer = source;
|
||||||
br->pos = 0;
|
br->pos = 0;
|
||||||
aom_write_bit(br, 0);
|
aom_dk_write_bit(br, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void aom_stop_encode(aom_writer *br) {
|
void aom_dk_stop_encode(aom_dk_writer *br) {
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
#if CONFIG_BITSTREAM_DEBUG
|
#if CONFIG_BITSTREAM_DEBUG
|
||||||
bitstream_queue_set_skip_write(1);
|
bitstream_queue_set_skip_write(1);
|
||||||
#endif // CONFIG_BITSTREAM_DEBUG
|
#endif // CONFIG_BITSTREAM_DEBUG
|
||||||
|
|
||||||
for (i = 0; i < 32; i++) aom_write_bit(br, 0);
|
for (i = 0; i < 32; i++) aom_dk_write_bit(br, 0);
|
||||||
|
|
||||||
#if CONFIG_BITSTREAM_DEBUG
|
#if CONFIG_BITSTREAM_DEBUG
|
||||||
bitstream_queue_set_skip_write(0);
|
bitstream_queue_set_skip_write(0);
|
|
@ -0,0 +1,114 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||||
|
*
|
||||||
|
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||||
|
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||||
|
* was not distributed with this source code in the LICENSE file, you can
|
||||||
|
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||||
|
* Media Patent License 1.0 was not distributed with this source code in the
|
||||||
|
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef AOM_DSP_DKBOOLWRITER_H_
|
||||||
|
#define AOM_DSP_DKBOOLWRITER_H_
|
||||||
|
|
||||||
|
#include "./aom_config.h"
|
||||||
|
|
||||||
|
#if CONFIG_BITSTREAM_DEBUG
|
||||||
|
#include <stdio.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "aom_dsp/prob.h"
|
||||||
|
#include "aom_ports/mem.h"
|
||||||
|
#include "aom_util/debug_util.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct aom_dk_writer {
|
||||||
|
unsigned int lowvalue;
|
||||||
|
unsigned int range;
|
||||||
|
int count;
|
||||||
|
unsigned int pos;
|
||||||
|
uint8_t *buffer;
|
||||||
|
} aom_dk_writer;
|
||||||
|
|
||||||
|
void aom_dk_start_encode(aom_dk_writer *bc, uint8_t *buffer);
|
||||||
|
void aom_dk_stop_encode(aom_dk_writer *bc);
|
||||||
|
|
||||||
|
static INLINE void aom_dk_write(aom_dk_writer *br, int bit, int probability) {
|
||||||
|
unsigned int split;
|
||||||
|
int count = br->count;
|
||||||
|
unsigned int range = br->range;
|
||||||
|
unsigned int lowvalue = br->lowvalue;
|
||||||
|
register int shift;
|
||||||
|
|
||||||
|
#if CONFIG_BITSTREAM_DEBUG
|
||||||
|
// int queue_r = 0;
|
||||||
|
// int frame_idx_r = 0;
|
||||||
|
// int queue_w = bitstream_queue_get_write();
|
||||||
|
// int frame_idx_w = bitstream_queue_get_frame_write();
|
||||||
|
// if (frame_idx_w == frame_idx_r && queue_w == queue_r) {
|
||||||
|
// fprintf(stderr, "\n *** bitstream queue at frame_idx_w %d queue_w %d\n",
|
||||||
|
// frame_idx_w, queue_w);
|
||||||
|
// }
|
||||||
|
bitstream_queue_push(bit, probability);
|
||||||
|
#endif // CONFIG_BITSTREAM_DEBUG
|
||||||
|
|
||||||
|
split = 1 + (((range - 1) * probability) >> 8);
|
||||||
|
|
||||||
|
range = split;
|
||||||
|
|
||||||
|
if (bit) {
|
||||||
|
lowvalue += split;
|
||||||
|
range = br->range - split;
|
||||||
|
}
|
||||||
|
|
||||||
|
shift = aom_norm[range];
|
||||||
|
|
||||||
|
range <<= shift;
|
||||||
|
count += shift;
|
||||||
|
|
||||||
|
if (count >= 0) {
|
||||||
|
int offset = shift - count;
|
||||||
|
|
||||||
|
if ((lowvalue << (offset - 1)) & 0x80000000) {
|
||||||
|
int x = br->pos - 1;
|
||||||
|
|
||||||
|
while (x >= 0 && br->buffer[x] == 0xff) {
|
||||||
|
br->buffer[x] = 0;
|
||||||
|
x--;
|
||||||
|
}
|
||||||
|
|
||||||
|
br->buffer[x] += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
br->buffer[br->pos++] = (lowvalue >> (24 - offset));
|
||||||
|
lowvalue <<= offset;
|
||||||
|
shift = count;
|
||||||
|
lowvalue &= 0xffffff;
|
||||||
|
count -= 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
lowvalue <<= shift;
|
||||||
|
br->count = count;
|
||||||
|
br->lowvalue = lowvalue;
|
||||||
|
br->range = range;
|
||||||
|
}
|
||||||
|
|
||||||
|
static INLINE void aom_dk_write_bit(aom_dk_writer *w, int bit) {
|
||||||
|
aom_dk_write(w, bit, 128); // aom_prob_half
|
||||||
|
}
|
||||||
|
|
||||||
|
static INLINE void aom_dk_write_literal(aom_dk_writer *w, int data, int bits) {
|
||||||
|
int bit;
|
||||||
|
|
||||||
|
for (bit = bits - 1; bit >= 0; bit--) aom_dk_write_bit(w, 1 & (data >> bit));
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} // extern "C"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // AOM_DSP_DKBOOLWRITER_H_
|
Загрузка…
Ссылка в новой задаче