Commit | Line | Data |
---|---|---|
2ba45a60 DM |
1 | /* |
2 | * FFV1 codec for libavcodec | |
3 | * | |
4 | * Copyright (c) 2003-2012 Michael Niedermayer <michaelni@gmx.at> | |
5 | * | |
6 | * This file is part of FFmpeg. | |
7 | * | |
8 | * FFmpeg is free software; you can redistribute it and/or | |
9 | * modify it under the terms of the GNU Lesser General Public | |
10 | * License as published by the Free Software Foundation; either | |
11 | * version 2.1 of the License, or (at your option) any later version. | |
12 | * | |
13 | * FFmpeg is distributed in the hope that it will be useful, | |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
16 | * Lesser General Public License for more details. | |
17 | * | |
18 | * You should have received a copy of the GNU Lesser General Public | |
19 | * License along with FFmpeg; if not, write to the Free Software | |
20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
21 | */ | |
22 | ||
23 | #ifndef AVCODEC_FFV1_H | |
24 | #define AVCODEC_FFV1_H | |
25 | ||
26 | /** | |
27 | * @file | |
28 | * FF Video Codec 1 (a lossless codec) | |
29 | */ | |
30 | ||
31 | #include "libavutil/avassert.h" | |
32 | #include "libavutil/crc.h" | |
33 | #include "libavutil/opt.h" | |
34 | #include "libavutil/imgutils.h" | |
35 | #include "libavutil/pixdesc.h" | |
36 | #include "libavutil/timer.h" | |
37 | #include "avcodec.h" | |
38 | #include "get_bits.h" | |
39 | #include "internal.h" | |
40 | #include "mathops.h" | |
41 | #include "put_bits.h" | |
42 | #include "rangecoder.h" | |
43 | #include "thread.h" | |
44 | ||
45 | #ifdef __INTEL_COMPILER | |
46 | #undef av_flatten | |
47 | #define av_flatten | |
48 | #endif | |
49 | ||
50 | #define MAX_PLANES 4 | |
51 | #define CONTEXT_SIZE 32 | |
52 | ||
53 | #define MAX_QUANT_TABLES 8 | |
54 | #define MAX_CONTEXT_INPUTS 5 | |
55 | ||
56 | typedef struct VlcState { | |
57 | int16_t drift; | |
58 | uint16_t error_sum; | |
59 | int8_t bias; | |
60 | uint8_t count; | |
61 | } VlcState; | |
62 | ||
63 | typedef struct PlaneContext { | |
64 | int16_t quant_table[MAX_CONTEXT_INPUTS][256]; | |
65 | int quant_table_index; | |
66 | int context_count; | |
67 | uint8_t (*state)[CONTEXT_SIZE]; | |
68 | VlcState *vlc_state; | |
69 | uint8_t interlace_bit_state[2]; | |
70 | } PlaneContext; | |
71 | ||
72 | #define MAX_SLICES 256 | |
73 | ||
74 | typedef struct FFV1Context { | |
75 | AVClass *class; | |
76 | AVCodecContext *avctx; | |
77 | RangeCoder c; | |
78 | GetBitContext gb; | |
79 | PutBitContext pb; | |
80 | uint64_t rc_stat[256][2]; | |
81 | uint64_t (*rc_stat2[MAX_QUANT_TABLES])[32][2]; | |
82 | int version; | |
83 | int micro_version; | |
84 | int width, height; | |
85 | int chroma_planes; | |
86 | int chroma_h_shift, chroma_v_shift; | |
87 | int transparency; | |
88 | int flags; | |
89 | int picture_number; | |
90 | ThreadFrame picture, last_picture; | |
91 | struct FFV1Context *fsrc; | |
92 | ||
93 | AVFrame *cur; | |
94 | int plane_count; | |
95 | int ac; ///< 1=range coder <-> 0=golomb rice | |
96 | int ac_byte_count; ///< number of bytes used for AC coding | |
97 | PlaneContext plane[MAX_PLANES]; | |
98 | int16_t quant_table[MAX_CONTEXT_INPUTS][256]; | |
99 | int16_t quant_tables[MAX_QUANT_TABLES][MAX_CONTEXT_INPUTS][256]; | |
100 | int context_count[MAX_QUANT_TABLES]; | |
101 | uint8_t state_transition[256]; | |
102 | uint8_t (*initial_states[MAX_QUANT_TABLES])[32]; | |
103 | int run_index; | |
104 | int colorspace; | |
105 | int16_t *sample_buffer; | |
106 | ||
107 | int ec; | |
108 | int intra; | |
109 | int slice_damaged; | |
110 | int key_frame_ok; | |
111 | ||
112 | int bits_per_raw_sample; | |
113 | int packed_at_lsb; | |
114 | ||
115 | int gob_count; | |
116 | int quant_table_count; | |
117 | ||
118 | struct FFV1Context *slice_context[MAX_SLICES]; | |
119 | int slice_count; | |
120 | int num_v_slices; | |
121 | int num_h_slices; | |
122 | int slice_width; | |
123 | int slice_height; | |
124 | int slice_x; | |
125 | int slice_y; | |
126 | int slice_reset_contexts; | |
127 | int slice_coding_mode; | |
128 | int slice_rct_by_coef; | |
129 | int slice_rct_ry_coef; | |
130 | } FFV1Context; | |
131 | ||
132 | int ffv1_common_init(AVCodecContext *avctx); | |
133 | int ffv1_init_slice_state(FFV1Context *f, FFV1Context *fs); | |
134 | int ffv1_init_slices_state(FFV1Context *f); | |
135 | int ffv1_init_slice_contexts(FFV1Context *f); | |
136 | int ffv1_allocate_initial_states(FFV1Context *f); | |
137 | void ffv1_clear_slice_state(FFV1Context *f, FFV1Context *fs); | |
138 | int ffv1_close(AVCodecContext *avctx); | |
139 | ||
140 | static av_always_inline int fold(int diff, int bits) | |
141 | { | |
142 | if (bits == 8) | |
143 | diff = (int8_t)diff; | |
144 | else { | |
145 | diff += 1 << (bits - 1); | |
146 | diff &= (1 << bits) - 1; | |
147 | diff -= 1 << (bits - 1); | |
148 | } | |
149 | ||
150 | return diff; | |
151 | } | |
152 | ||
153 | static inline int predict(int16_t *src, int16_t *last) | |
154 | { | |
155 | const int LT = last[-1]; | |
156 | const int T = last[0]; | |
157 | const int L = src[-1]; | |
158 | ||
159 | return mid_pred(L, L + T - LT, T); | |
160 | } | |
161 | ||
162 | static inline int get_context(PlaneContext *p, int16_t *src, | |
163 | int16_t *last, int16_t *last2) | |
164 | { | |
165 | const int LT = last[-1]; | |
166 | const int T = last[0]; | |
167 | const int RT = last[1]; | |
168 | const int L = src[-1]; | |
169 | ||
170 | if (p->quant_table[3][127]) { | |
171 | const int TT = last2[0]; | |
172 | const int LL = src[-2]; | |
173 | return p->quant_table[0][(L - LT) & 0xFF] + | |
174 | p->quant_table[1][(LT - T) & 0xFF] + | |
175 | p->quant_table[2][(T - RT) & 0xFF] + | |
176 | p->quant_table[3][(LL - L) & 0xFF] + | |
177 | p->quant_table[4][(TT - T) & 0xFF]; | |
178 | } else | |
179 | return p->quant_table[0][(L - LT) & 0xFF] + | |
180 | p->quant_table[1][(LT - T) & 0xFF] + | |
181 | p->quant_table[2][(T - RT) & 0xFF]; | |
182 | } | |
183 | ||
184 | static inline void update_vlc_state(VlcState *const state, const int v) | |
185 | { | |
186 | int drift = state->drift; | |
187 | int count = state->count; | |
188 | state->error_sum += FFABS(v); | |
189 | drift += v; | |
190 | ||
191 | if (count == 128) { // FIXME: variable | |
192 | count >>= 1; | |
193 | drift >>= 1; | |
194 | state->error_sum >>= 1; | |
195 | } | |
196 | count++; | |
197 | ||
198 | if (drift <= -count) { | |
199 | if (state->bias > -128) | |
200 | state->bias--; | |
201 | ||
202 | drift += count; | |
203 | if (drift <= -count) | |
204 | drift = -count + 1; | |
205 | } else if (drift > 0) { | |
206 | if (state->bias < 127) | |
207 | state->bias++; | |
208 | ||
209 | drift -= count; | |
210 | if (drift > 0) | |
211 | drift = 0; | |
212 | } | |
213 | ||
214 | state->drift = drift; | |
215 | state->count = count; | |
216 | } | |
217 | ||
218 | #endif /* AVCODEC_FFV1_H */ |