blob: ae3286c95ae2f75b90ccbea7562164b14726c63b [file] [log] [blame]
Yaowu Xuc27fc142016-08-22 16:08:15 -07001/*
Alex Converse7fe2ae82016-09-28 11:33:20 -07002 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
Yaowu Xuc27fc142016-08-22 16:08:15 -07003 *
Alex Converse7fe2ae82016-09-28 11:33:20 -07004 * This source code is subject to the terms of the BSD 2 Clause License and
5 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6 * was not distributed with this source code in the LICENSE file, you can
7 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8 * Media Patent License 1.0 was not distributed with this source code in the
9 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
Yaowu Xuc27fc142016-08-22 16:08:15 -070010 */
11
Alex Converse1ac1ae72016-09-17 15:11:16 -070012#ifndef AOM_DSP_BUF_ANS_H_
13#define AOM_DSP_BUF_ANS_H_
Yaowu Xuc27fc142016-08-22 16:08:15 -070014// Buffered forward ANS writer.
Alex Converse7fe2ae82016-09-28 11:33:20 -070015// Symbols are written to the writer in forward (decode) order and serialized
Yaowu Xuc27fc142016-08-22 16:08:15 -070016// backwards due to ANS's stack like behavior.
17
18#include <assert.h>
Yaowu Xuf883b422016-08-30 14:01:10 -070019#include "./aom_config.h"
20#include "aom/aom_integer.h"
Alex Converse1ac1ae72016-09-17 15:11:16 -070021#include "aom_dsp/ans.h"
Alex Converse7fe2ae82016-09-28 11:33:20 -070022#include "aom_dsp/answriter.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070023
24#ifdef __cplusplus
25extern "C" {
26#endif // __cplusplus
27
Alex Conversec54692b2017-01-25 16:41:05 -080028#define ANS_METHOD_RABS 0
Yaowu Xuc27fc142016-08-22 16:08:15 -070029#define ANS_METHOD_RANS 1
30
31struct buffered_ans_symbol {
Alex Conversec54692b2017-01-25 16:41:05 -080032 unsigned int method : 1; // one of ANS_METHOD_RABS or ANS_METHOD_RANS
Alex Converse7fe2ae82016-09-28 11:33:20 -070033 // TODO(aconverse): Should be possible to write this in terms of start for ABS
34 unsigned int val_start : RANS_PROB_BITS; // Boolean value for ABS
35 // start in symbol cycle for Rans
36 unsigned int prob : RANS_PROB_BITS; // Probability of this symbol
Yaowu Xuc27fc142016-08-22 16:08:15 -070037};
38
39struct BufAnsCoder {
Alex Converse1ac1ae72016-09-17 15:11:16 -070040 struct aom_internal_error_info *error;
Yaowu Xuc27fc142016-08-22 16:08:15 -070041 struct buffered_ans_symbol *buf;
Alex Converse2a1b3af2016-10-26 13:11:26 -070042 struct AnsCoder ans;
Yaowu Xuc27fc142016-08-22 16:08:15 -070043 int size;
44 int offset;
Alex Converse2a1b3af2016-10-26 13:11:26 -070045 int output_bytes;
Alex Converse2cdf0d82016-12-13 13:53:09 -080046#if ANS_MAX_SYMBOLS
47 int window_size;
48#endif
Alex Converse30f0e152017-03-28 10:13:27 -070049 int pos; // Dummy variable to store the output buffer after closing
Yunqing Wang0e141b52017-11-02 15:08:58 -070050 uint8_t allow_update_cdf;
Yaowu Xuc27fc142016-08-22 16:08:15 -070051};
52
Alex Converse2cdf0d82016-12-13 13:53:09 -080053// Allocate a buffered ANS coder to store size symbols.
54// When ANS_MAX_SYMBOLS is turned on, the size is the fixed size of each ANS
55// partition.
56// When ANS_MAX_SYMBOLS is turned off, size is merely an initial hint and the
57// buffer will grow on demand
Alex Converse1ac1ae72016-09-17 15:11:16 -070058void aom_buf_ans_alloc(struct BufAnsCoder *c,
Alex Converse30f0e152017-03-28 10:13:27 -070059 struct aom_internal_error_info *error);
Yaowu Xuc27fc142016-08-22 16:08:15 -070060
Alex Converse1ac1ae72016-09-17 15:11:16 -070061void aom_buf_ans_free(struct BufAnsCoder *c);
Yaowu Xuc27fc142016-08-22 16:08:15 -070062
Alex Converse2cdf0d82016-12-13 13:53:09 -080063#if !ANS_MAX_SYMBOLS
Alex Converse1ac1ae72016-09-17 15:11:16 -070064void aom_buf_ans_grow(struct BufAnsCoder *c);
Alex Converse2cdf0d82016-12-13 13:53:09 -080065#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -070066
Alex Converse1ecdf2b2016-11-30 15:51:12 -080067void aom_buf_ans_flush(struct BufAnsCoder *const c);
68
Alex Converse2a1b3af2016-10-26 13:11:26 -070069static INLINE void buf_ans_write_init(struct BufAnsCoder *const c,
70 uint8_t *const output_buffer) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070071 c->offset = 0;
Alex Converse2a1b3af2016-10-26 13:11:26 -070072 c->output_bytes = 0;
73 ans_write_init(&c->ans, output_buffer);
Yaowu Xuc27fc142016-08-22 16:08:15 -070074}
75
Alex Conversec54692b2017-01-25 16:41:05 -080076static INLINE void buf_rabs_write(struct BufAnsCoder *const c, uint8_t val,
Yaowu Xuc27fc142016-08-22 16:08:15 -070077 AnsP8 prob) {
78 assert(c->offset <= c->size);
Alex Converse2cdf0d82016-12-13 13:53:09 -080079#if !ANS_MAX_SYMBOLS
Yaowu Xuc27fc142016-08-22 16:08:15 -070080 if (c->offset == c->size) {
Alex Converse1ac1ae72016-09-17 15:11:16 -070081 aom_buf_ans_grow(c);
Yaowu Xuc27fc142016-08-22 16:08:15 -070082 }
Alex Converse2cdf0d82016-12-13 13:53:09 -080083#endif
Alex Conversec54692b2017-01-25 16:41:05 -080084 c->buf[c->offset].method = ANS_METHOD_RABS;
Yaowu Xuc27fc142016-08-22 16:08:15 -070085 c->buf[c->offset].val_start = val;
86 c->buf[c->offset].prob = prob;
87 ++c->offset;
Alex Converseb0be6412016-11-30 15:51:50 -080088#if ANS_MAX_SYMBOLS
Alex Converse2cdf0d82016-12-13 13:53:09 -080089 if (c->offset == c->size) aom_buf_ans_flush(c);
Alex Converseb0be6412016-11-30 15:51:50 -080090#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -070091}
92
Alex Converse8c687d22017-02-07 15:55:24 -080093// Buffer one symbol for encoding using rANS.
94// cum_prob: The cumulative probability before this symbol (the offset of
95// the symbol in the symbol cycle)
96// prob: The probability of this symbol (l_s from the paper)
97// RANS_PRECISION takes the place of m from the paper.
Yaowu Xuc27fc142016-08-22 16:08:15 -070098static INLINE void buf_rans_write(struct BufAnsCoder *const c,
Alex Converse8c687d22017-02-07 15:55:24 -080099 aom_cdf_prob cum_prob, aom_cdf_prob prob) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700100 assert(c->offset <= c->size);
Alex Converse2cdf0d82016-12-13 13:53:09 -0800101#if !ANS_MAX_SYMBOLS
Yaowu Xuc27fc142016-08-22 16:08:15 -0700102 if (c->offset == c->size) {
Alex Converse1ac1ae72016-09-17 15:11:16 -0700103 aom_buf_ans_grow(c);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700104 }
Alex Converse2cdf0d82016-12-13 13:53:09 -0800105#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700106 c->buf[c->offset].method = ANS_METHOD_RANS;
Alex Converse8c687d22017-02-07 15:55:24 -0800107 c->buf[c->offset].val_start = cum_prob;
108 c->buf[c->offset].prob = prob;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700109 ++c->offset;
Alex Converseb0be6412016-11-30 15:51:50 -0800110#if ANS_MAX_SYMBOLS
Alex Converse2cdf0d82016-12-13 13:53:09 -0800111 if (c->offset == c->size) aom_buf_ans_flush(c);
Alex Converseb0be6412016-11-30 15:51:50 -0800112#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700113}
114
Alex Conversec54692b2017-01-25 16:41:05 -0800115static INLINE void buf_rabs_write_bit(struct BufAnsCoder *c, int bit) {
116 buf_rabs_write(c, bit, 128);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700117}
118
Alex Conversec54692b2017-01-25 16:41:05 -0800119static INLINE void buf_rabs_write_literal(struct BufAnsCoder *c, int literal,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700120 int bits) {
121 int bit;
122
123 assert(bits < 31);
124 for (bit = bits - 1; bit >= 0; bit--)
Alex Conversec54692b2017-01-25 16:41:05 -0800125 buf_rabs_write_bit(c, 1 & (literal >> bit));
Yaowu Xuc27fc142016-08-22 16:08:15 -0700126}
Alex Converse2a1b3af2016-10-26 13:11:26 -0700127
128static INLINE int buf_ans_write_end(struct BufAnsCoder *const c) {
129 assert(c->offset == 0);
130 return c->output_bytes;
131}
Yaowu Xuc27fc142016-08-22 16:08:15 -0700132#ifdef __cplusplus
133} // extern "C"
134#endif // __cplusplus
Alex Converse1ac1ae72016-09-17 15:11:16 -0700135#endif // AOM_DSP_BUF_ANS_H_