FFmpeg
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
Examples
File List
Globals
•
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
libavcodec
rangecoder.h
Go to the documentation of this file.
1
/*
2
* Range coder
3
* Copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at>
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
* Range coder.
25
*/
26
27
#ifndef AVCODEC_RANGECODER_H
28
#define AVCODEC_RANGECODER_H
29
30
#include <stdint.h>
31
32
#include "
libavutil/common.h
"
33
#include "
libavutil/avassert.h
"
34
35
typedef
struct
RangeCoder
{
36
int
low
;
37
int
range
;
38
int
outstanding_count
;
39
int
outstanding_byte
;
40
uint8_t
zero_state
[256];
41
uint8_t
one_state
[256];
42
uint8_t
*
bytestream_start
;
43
uint8_t
*
bytestream
;
44
uint8_t
*
bytestream_end
;
45
}
RangeCoder
;
46
47
void
ff_init_range_encoder
(
RangeCoder
*
c
,
uint8_t
*
buf
,
int
buf_size);
48
void
ff_init_range_decoder
(
RangeCoder
*
c
,
const
uint8_t
*
buf
,
int
buf_size);
49
int
ff_rac_terminate
(
RangeCoder
*
c
);
50
void
ff_build_rac_states
(
RangeCoder
*
c
,
int
factor
,
int
max_p);
51
52
static
inline
void
renorm_encoder
(
RangeCoder
*
c
)
53
{
54
// FIXME: optimize
55
while
(c->
range
< 0x100) {
56
if
(c->
outstanding_byte
< 0) {
57
c->
outstanding_byte
= c->
low
>> 8;
58
}
else
if
(c->
low
<= 0xFF00) {
59
*c->
bytestream
++ = c->
outstanding_byte
;
60
for
(; c->
outstanding_count
; c->
outstanding_count
--)
61
*c->
bytestream
++ = 0xFF;
62
c->
outstanding_byte
= c->
low
>> 8;
63
}
else
if
(c->
low
>= 0x10000) {
64
*c->
bytestream
++ = c->
outstanding_byte
+ 1;
65
for
(; c->
outstanding_count
; c->
outstanding_count
--)
66
*c->
bytestream
++ = 0x00;
67
c->
outstanding_byte
= (c->
low
>> 8) & 0xFF;
68
}
else
{
69
c->
outstanding_count
++;
70
}
71
72
c->
low
= (c->
low
& 0xFF) << 8;
73
c->
range
<<= 8;
74
}
75
}
76
77
static
inline
int
get_rac_count
(
RangeCoder
*
c
)
78
{
79
int
x = c->
bytestream
- c->
bytestream_start
+ c->
outstanding_count
;
80
if
(c->
outstanding_byte
>= 0)
81
x++;
82
return
8 * x -
av_log2
(c->
range
);
83
}
84
85
static
inline
void
put_rac
(
RangeCoder
*
c
,
uint8_t
*
const
state
,
int
bit)
86
{
87
int
range1 = (c->
range
* (*state)) >> 8;
88
89
av_assert2
(*state);
90
av_assert2
(range1 < c->range);
91
av_assert2
(range1 > 0);
92
if
(!bit) {
93
c->
range
-= range1;
94
*state = c->
zero_state
[*
state
];
95
}
else
{
96
c->
low
+= c->
range
- range1;
97
c->
range
= range1;
98
*state = c->
one_state
[*
state
];
99
}
100
101
renorm_encoder
(c);
102
}
103
104
static
inline
void
refill
(
RangeCoder
*
c
)
105
{
106
if
(c->
range
< 0x100) {
107
c->
range
<<= 8;
108
c->
low
<<= 8;
109
if
(c->
bytestream
< c->
bytestream_end
)
110
c->
low
+= c->
bytestream
[0];
111
c->
bytestream
++;
112
}
113
}
114
115
static
inline
int
get_rac
(
RangeCoder
*
c
,
uint8_t
*
const
state
)
116
{
117
int
range1 = (c->
range
* (*state)) >> 8;
118
int
av_unused
one_mask;
119
120
c->
range
-= range1;
121
#if 1
122
if
(c->
low
< c->
range
) {
123
*state = c->
zero_state
[*
state
];
124
refill
(c);
125
return
0;
126
}
else
{
127
c->
low
-= c->
range
;
128
*state = c->
one_state
[*
state
];
129
c->
range
= range1;
130
refill
(c);
131
return
1;
132
}
133
#else
134
one_mask = (c->
range
- c->
low
- 1) >> 31;
135
136
c->
low
-= c->
range
& one_mask;
137
c->
range
+= (range1 - c->
range
) & one_mask;
138
139
*state = c->
zero_state
[(*state) + (256 & one_mask)];
140
141
refill
(c);
142
143
return
one_mask & 1;
144
#endif
145
}
146
147
#endif
/* AVCODEC_RANGECODER_H */
Generated on Sun Mar 23 2014 23:50:01 for FFmpeg by
1.8.2