FFmpeg
Loading...
Searching...
No Matches
dirac_arith.h
Go to the documentation of this file.
1/*
2 * Copyright (C) 2007 Marco Gerards <marco@gnu.org>
3 * Copyright (C) 2009 David Conrad
4 *
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22/**
23 * @file
24 * Arithmetic decoder for Dirac
25 * @author Marco Gerards <marco@gnu.org>
26 */
27
28#ifndef AVCODEC_DIRAC_ARITH_H
29#define AVCODEC_DIRAC_ARITH_H
30
31#include "config.h"
32
33#include "bytestream.h"
34#include "get_bits.h"
35
62
63// Dirac resets the arith decoder between decoding various types of data,
64// so many contexts are never used simultaneously. Thus, we can reduce
65// the number of contexts needed by reusing them.
66#define CTX_SB_F1 CTX_ZP_F5
67#define CTX_SB_DATA 0
68#define CTX_PMODE_REF1 0
69#define CTX_PMODE_REF2 1
70#define CTX_GLOBAL_BLOCK 2
71#define CTX_MV_F1 CTX_ZP_F2
72#define CTX_MV_DATA 0
73#define CTX_DC_F1 CTX_ZP_F5
74#define CTX_DC_DATA 0
75
76typedef struct {
77 unsigned low;
78 uint16_t range;
79 int16_t counter;
80
81 const uint8_t *bytestream;
82 const uint8_t *bytestream_end;
83
85 int error;
88
89extern const uint8_t ff_dirac_next_ctx[DIRAC_CTX_COUNT];
90extern int16_t ff_dirac_prob_branchless[256][2];
91
92static inline void renorm(DiracArith *c)
93{
94#if HAVE_FAST_CLZ
95 int shift = 14 - av_log2_16bit(c->range-1) + ((c->range-1)>>15);
96
97 c->low <<= shift;
98 c->range <<= shift;
99 c->counter += shift;
100#else
101 while (c->range <= 0x4000) {
102 c->low <<= 1;
103 c->range <<= 1;
104 c->counter++;
105 }
106#endif
107}
108
109static inline void refill(DiracArith *c)
110{
111 int counter = c->counter;
112
113 if (counter >= 0) {
114 int new = bytestream_get_be16(&c->bytestream);
115
116 // the spec defines overread bits to be 1, and streams rely on this
117 if (c->bytestream > c->bytestream_end) {
118 new |= 0xff;
119 if (c->bytestream > c->bytestream_end+1)
120 new |= 0xff00;
121
122 c->bytestream = c->bytestream_end;
123 c->overread ++;
124 if (c->overread > 4)
125 c->error = AVERROR_INVALIDDATA;
126 }
127
128 c->low += new << counter;
129 counter -= 16;
130 }
131 c->counter = counter;
132}
133
134static inline int dirac_get_arith_bit(DiracArith *c, int ctx)
135{
136 int prob_zero = c->contexts[ctx];
137 int range_times_prob, bit;
138 unsigned low = c->low;
139 int range = c->range;
140
141 range_times_prob = (c->range * prob_zero) >> 16;
142
143#if ARCH_X86 && HAVE_FAST_CMOV && HAVE_INLINE_ASM && HAVE_X86_6REGS
144 low -= range_times_prob << 16;
145 range -= range_times_prob;
146 bit = 0;
147 __asm__(
148 "cmpl %5, %4 \n\t"
149 "setae %b0 \n\t"
150 "cmovb %3, %2 \n\t"
151 "cmovb %5, %1 \n\t"
152 : "+q"(bit), "+r"(range), "+r"(low)
153 : "r"(c->low), "r"(c->low>>16),
154 "r"(range_times_prob)
155 );
156#else
157 bit = (low >> 16) >= range_times_prob;
158 if (bit) {
159 low -= range_times_prob << 16;
160 range -= range_times_prob;
161 } else {
162 range = range_times_prob;
163 }
164#endif
165
166 c->contexts[ctx] += ff_dirac_prob_branchless[prob_zero>>8][bit];
167 c->low = low;
168 c->range = range;
169
170 renorm(c);
171 refill(c);
172 return bit;
173}
174
175static inline int dirac_get_arith_uint(DiracArith *c, int follow_ctx, int data_ctx)
176{
177 int ret = 1;
178 while (!dirac_get_arith_bit(c, follow_ctx)) {
179 if (ret >= 0x40000000) {
180 av_log(NULL, AV_LOG_ERROR, "dirac_get_arith_uint overflow\n");
181 c->error = AVERROR_INVALIDDATA;
182 return -1;
183 }
184 ret <<= 1;
185 ret += dirac_get_arith_bit(c, data_ctx);
186 follow_ctx = ff_dirac_next_ctx[follow_ctx];
187 }
188 return ret-1;
189}
190
191static inline int dirac_get_arith_int(DiracArith *c, int follow_ctx, int data_ctx)
192{
193 int ret = dirac_get_arith_uint(c, follow_ctx, data_ctx);
194 if (ret && dirac_get_arith_bit(c, data_ctx+1))
195 ret = -ret;
196 return ret;
197}
198
201
202#endif /* AVCODEC_DIRAC_ARITH_H */
__asm__(".macro parse_r var r\n\t" "\\var = -1\n\t" _IFC_REG(0) _IFC_REG(1) _IFC_REG(2) _IFC_REG(3) _IFC_REG(4) _IFC_REG(5) _IFC_REG(6) _IFC_REG(7) _IFC_REG(8) _IFC_REG(9) _IFC_REG(10) _IFC_REG(11) _IFC_REG(12) _IFC_REG(13) _IFC_REG(14) _IFC_REG(15) _IFC_REG(16) _IFC_REG(17) _IFC_REG(18) _IFC_REG(19) _IFC_REG(20) _IFC_REG(21) _IFC_REG(22) _IFC_REG(23) _IFC_REG(24) _IFC_REG(25) _IFC_REG(26) _IFC_REG(27) _IFC_REG(28) _IFC_REG(29) _IFC_REG(30) _IFC_REG(31) ".iflt \\var\n\t" ".error \"Unable to parse register name \\r\"\n\t" ".endif\n\t" ".endm")
#define bit(string, value)
Definition cbs_mpeg2.c:56
#define NULL
Definition coverity.c:32
const uint8_t ff_dirac_next_ctx[DIRAC_CTX_COUNT]
Definition dirac_arith.c:66
int16_t ff_dirac_prob_branchless[256][2]
Definition dirac_arith.c:84
static int dirac_get_arith_uint(DiracArith *c, int follow_ctx, int data_ctx)
void ff_dirac_init_arith_tables(void)
Definition dirac_arith.c:86
static void renorm(DiracArith *c)
Definition dirac_arith.h:92
void ff_dirac_init_arith_decoder(DiracArith *c, GetBitContext *gb, int length)
Definition dirac_arith.c:96
dirac_arith_contexts
Definition dirac_arith.h:36
@ CTX_SIGN_ZERO
Definition dirac_arith.h:53
@ CTX_DELTA_Q_DATA
Definition dirac_arith.h:57
@ CTX_ZP_F3
Definition dirac_arith.h:42
@ CTX_NP_F5
Definition dirac_arith.h:49
@ CTX_NP_F3
Definition dirac_arith.h:47
@ CTX_SIGN_POS
Definition dirac_arith.h:54
@ CTX_NP_F4
Definition dirac_arith.h:48
@ CTX_NP_F2
Definition dirac_arith.h:46
@ CTX_ZPZN_F1
Definition dirac_arith.h:37
@ CTX_COEFF_DATA
Definition dirac_arith.h:51
@ CTX_ZP_F5
Definition dirac_arith.h:44
@ CTX_DELTA_Q_SIGN
Definition dirac_arith.h:58
@ DIRAC_CTX_COUNT
Definition dirac_arith.h:60
@ CTX_NPNN_F1
Definition dirac_arith.h:40
@ CTX_DELTA_Q_F
Definition dirac_arith.h:56
@ CTX_ZP_F2
Definition dirac_arith.h:41
@ CTX_ZERO_BLOCK
Definition dirac_arith.h:55
@ CTX_SIGN_NEG
Definition dirac_arith.h:52
@ CTX_NP_F6
Definition dirac_arith.h:50
@ CTX_NPZN_F1
Definition dirac_arith.h:39
@ CTX_ZPNN_F1
Definition dirac_arith.h:38
@ CTX_ZP_F4
Definition dirac_arith.h:43
@ CTX_ZP_F6
Definition dirac_arith.h:45
static int dirac_get_arith_bit(DiracArith *c, int ctx)
static void refill(DiracArith *c)
static int dirac_get_arith_int(DiracArith *c, int follow_ctx, int data_ctx)
bitstream reader API header.
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition error.h:61
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
#define av_log2_16bit
Definition intmath.h:85
static int shift(int a, int b)
Definition bonk.c:261
enum AVColorRange range
int16_t counter
Definition dirac_arith.h:79
unsigned low
Definition dirac_arith.h:77
const uint8_t * bytestream_end
Definition dirac_arith.h:82
uint16_t contexts[DIRAC_CTX_COUNT]
Definition dirac_arith.h:84
const uint8_t * bytestream
Definition dirac_arith.h:81
uint16_t range
Definition dirac_arith.h:78
#define av_log(a,...)
static AVFormatContext * ctx
Definition movenc.c:49
static double c[64]