ffmpeg / libavcodec / dv.c @ 5509bffa
History | View | Annotate | Download (31.8 KB)
1 | 5d2231ee | Fabrice Bellard | /*
|
---|---|---|---|
2 | * DV decoder
|
||
3 | * Copyright (c) 2002 Fabrice Bellard.
|
||
4 | 901ee2be | Roman Shaposhnik | * Copyright (c) 2004 Roman Shaposhnik.
|
5 | 5d2231ee | Fabrice Bellard | *
|
6 | 115329f1 | Diego Biurrun | * DV encoder
|
7 | 4fa1c4fa | Roman Shaposhnik | * Copyright (c) 2003 Roman Shaposhnik.
|
8 | *
|
||
9 | * Many thanks to Dan Dennedy <dan@dennedy.org> for providing wealth
|
||
10 | * of DV technical info.
|
||
11 | *
|
||
12 | 5d2231ee | Fabrice Bellard | * This library is free software; you can redistribute it and/or
|
13 | * modify it under the terms of the GNU Lesser General Public
|
||
14 | * License as published by the Free Software Foundation; either
|
||
15 | * version 2 of the License, or (at your option) any later version.
|
||
16 | *
|
||
17 | * This library is distributed in the hope that it will be useful,
|
||
18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
20 | * Lesser General Public License for more details.
|
||
21 | *
|
||
22 | * You should have received a copy of the GNU Lesser General Public
|
||
23 | * License along with this library; if not, write to the Free Software
|
||
24 | 5509bffa | Diego Biurrun | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
25 | 5d2231ee | Fabrice Bellard | */
|
26 | 983e3246 | Michael Niedermayer | |
27 | /**
|
||
28 | * @file dv.c
|
||
29 | 4fa1c4fa | Roman Shaposhnik | * DV codec.
|
30 | 983e3246 | Michael Niedermayer | */
|
31 | 5d2231ee | Fabrice Bellard | #include "avcodec.h" |
32 | #include "dsputil.h" |
||
33 | #include "mpegvideo.h" |
||
34 | #include "simple_idct.h" |
||
35 | 7458ccbb | Roman Shaposhnik | #include "dvdata.h" |
36 | 5d2231ee | Fabrice Bellard | |
37 | c619ff6d | Michael Niedermayer | //#undef NDEBUG
|
38 | //#include <assert.h>
|
||
39 | |||
40 | 6faa4645 | Roman Shaposhnik | typedef struct DVVideoContext { |
41 | 7458ccbb | Roman Shaposhnik | const DVprofile* sys;
|
42 | 492cd3a9 | Michael Niedermayer | AVFrame picture; |
43 | c619ff6d | Michael Niedermayer | AVCodecContext *avctx; |
44 | 6faa4645 | Roman Shaposhnik | uint8_t *buf; |
45 | 115329f1 | Diego Biurrun | |
46 | 0c1a9eda | Zdenek Kabelac | uint8_t dv_zigzag[2][64]; |
47 | 901ee2be | Roman Shaposhnik | uint8_t dv_idct_shift[2][2][22][64]; |
48 | 115329f1 | Diego Biurrun | |
49 | 7458ccbb | Roman Shaposhnik | void (*get_pixels)(DCTELEM *block, const uint8_t *pixels, int line_size); |
50 | 10acc479 | Roman Shaposhnik | void (*fdct[2])(DCTELEM *block); |
51 | 0c1a9eda | Zdenek Kabelac | void (*idct_put[2])(uint8_t *dest, int line_size, DCTELEM *block); |
52 | 6faa4645 | Roman Shaposhnik | } DVVideoContext; |
53 | 5d2231ee | Fabrice Bellard | |
54 | aa066582 | Roman Shaposhnik | /* MultiThreading - applies to entire DV codec, not just the avcontext */
|
55 | uint8_t** dv_anchor; |
||
56 | |||
57 | 7458ccbb | Roman Shaposhnik | #define TEX_VLC_BITS 9 |
58 | e15c3302 | Roman Shaposhnik | |
59 | #ifdef DV_CODEC_TINY_TARGET
|
||
60 | #define DV_VLC_MAP_RUN_SIZE 15 |
||
61 | #define DV_VLC_MAP_LEV_SIZE 23 |
||
62 | #else
|
||
63 | 115329f1 | Diego Biurrun | #define DV_VLC_MAP_RUN_SIZE 64 |
64 | c619ff6d | Michael Niedermayer | #define DV_VLC_MAP_LEV_SIZE 512 //FIXME sign was removed so this should be /2 but needs check |
65 | e15c3302 | Roman Shaposhnik | #endif
|
66 | |||
67 | 5d2231ee | Fabrice Bellard | /* XXX: also include quantization */
|
68 | 380fd6b1 | Roman Shaposhnik | static RL_VLC_ELEM *dv_rl_vlc;
|
69 | e15c3302 | Roman Shaposhnik | /* VLC encoding lookup table */
|
70 | static struct dv_vlc_pair { |
||
71 | uint32_t vlc; |
||
72 | uint8_t size; |
||
73 | } (*dv_vlc_map)[DV_VLC_MAP_LEV_SIZE] = NULL;
|
||
74 | 5d2231ee | Fabrice Bellard | |
75 | 6faa4645 | Roman Shaposhnik | static void dv_build_unquantize_tables(DVVideoContext *s, uint8_t* perm) |
76 | 5d2231ee | Fabrice Bellard | { |
77 | 7be166e4 | Fabrice Bellard | int i, q, j;
|
78 | 5d2231ee | Fabrice Bellard | |
79 | /* NOTE: max left shift is 6 */
|
||
80 | 7be166e4 | Fabrice Bellard | for(q = 0; q < 22; q++) { |
81 | 10acc479 | Roman Shaposhnik | /* 88DCT */
|
82 | 7be166e4 | Fabrice Bellard | for(i = 1; i < 64; i++) { |
83 | /* 88 table */
|
||
84 | 10acc479 | Roman Shaposhnik | j = perm[i]; |
85 | 901ee2be | Roman Shaposhnik | s->dv_idct_shift[0][0][q][j] = |
86 | 7be166e4 | Fabrice Bellard | dv_quant_shifts[q][dv_88_areas[i]] + 1;
|
87 | bb270c08 | Diego Biurrun | s->dv_idct_shift[1][0][q][j] = s->dv_idct_shift[0][0][q][j] + 1; |
88 | 7be166e4 | Fabrice Bellard | } |
89 | 115329f1 | Diego Biurrun | |
90 | 10acc479 | Roman Shaposhnik | /* 248DCT */
|
91 | 7be166e4 | Fabrice Bellard | for(i = 1; i < 64; i++) { |
92 | /* 248 table */
|
||
93 | 115329f1 | Diego Biurrun | s->dv_idct_shift[0][1][q][i] = |
94 | 10acc479 | Roman Shaposhnik | dv_quant_shifts[q][dv_248_areas[i]] + 1;
|
95 | bb270c08 | Diego Biurrun | s->dv_idct_shift[1][1][q][i] = s->dv_idct_shift[0][1][q][i] + 1; |
96 | 5d2231ee | Fabrice Bellard | } |
97 | } |
||
98 | } |
||
99 | |||
100 | 4fa1c4fa | Roman Shaposhnik | static int dvvideo_init(AVCodecContext *avctx) |
101 | 5d2231ee | Fabrice Bellard | { |
102 | 6faa4645 | Roman Shaposhnik | DVVideoContext *s = avctx->priv_data; |
103 | 10acc479 | Roman Shaposhnik | DSPContext dsp; |
104 | 7604246d | Wolfgang Hesseler | static int done=0; |
105 | e15c3302 | Roman Shaposhnik | int i, j;
|
106 | 5d2231ee | Fabrice Bellard | |
107 | if (!done) {
|
||
108 | 7458ccbb | Roman Shaposhnik | VLC dv_vlc; |
109 | 901ee2be | Roman Shaposhnik | uint16_t new_dv_vlc_bits[NB_DV_VLC*2];
|
110 | uint8_t new_dv_vlc_len[NB_DV_VLC*2];
|
||
111 | uint8_t new_dv_vlc_run[NB_DV_VLC*2];
|
||
112 | int16_t new_dv_vlc_level[NB_DV_VLC*2];
|
||
113 | 5d2231ee | Fabrice Bellard | |
114 | done = 1;
|
||
115 | |||
116 | 5b2bf943 | Burkhard Plaum | dv_vlc_map = av_mallocz_static(DV_VLC_MAP_LEV_SIZE*DV_VLC_MAP_RUN_SIZE*sizeof(struct dv_vlc_pair)); |
117 | bb270c08 | Diego Biurrun | if (!dv_vlc_map)
|
118 | return -ENOMEM;
|
||
119 | |||
120 | /* dv_anchor lets each thread know its Id */
|
||
121 | aa066582 | Roman Shaposhnik | dv_anchor = av_malloc(12*27*sizeof(void*)); |
122 | if (!dv_anchor) {
|
||
123 | bb270c08 | Diego Biurrun | return -ENOMEM;
|
124 | } |
||
125 | for (i=0; i<12*27; i++) |
||
126 | aa066582 | Roman Shaposhnik | dv_anchor[i] = (void*)(size_t)i;
|
127 | bb270c08 | Diego Biurrun | |
128 | /* it's faster to include sign bit in a generic VLC parsing scheme */
|
||
129 | for (i=0, j=0; i<NB_DV_VLC; i++, j++) { |
||
130 | new_dv_vlc_bits[j] = dv_vlc_bits[i]; |
||
131 | new_dv_vlc_len[j] = dv_vlc_len[i]; |
||
132 | new_dv_vlc_run[j] = dv_vlc_run[i]; |
||
133 | new_dv_vlc_level[j] = dv_vlc_level[i]; |
||
134 | |||
135 | if (dv_vlc_level[i]) {
|
||
136 | new_dv_vlc_bits[j] <<= 1;
|
||
137 | new_dv_vlc_len[j]++; |
||
138 | |||
139 | j++; |
||
140 | new_dv_vlc_bits[j] = (dv_vlc_bits[i] << 1) | 1; |
||
141 | new_dv_vlc_len[j] = dv_vlc_len[i] + 1;
|
||
142 | new_dv_vlc_run[j] = dv_vlc_run[i]; |
||
143 | new_dv_vlc_level[j] = -dv_vlc_level[i]; |
||
144 | } |
||
145 | } |
||
146 | 115329f1 | Diego Biurrun | |
147 | 5d2231ee | Fabrice Bellard | /* NOTE: as a trick, we use the fact the no codes are unused
|
148 | to accelerate the parsing of partial codes */
|
||
149 | 115329f1 | Diego Biurrun | init_vlc(&dv_vlc, TEX_VLC_BITS, j, |
150 | 073c2593 | Burkhard Plaum | new_dv_vlc_len, 1, 1, new_dv_vlc_bits, 2, 2, 0); |
151 | 5d2231ee | Fabrice Bellard | |
152 | c842aa37 | Burkhard Plaum | dv_rl_vlc = av_mallocz_static(dv_vlc.table_size * sizeof(RL_VLC_ELEM));
|
153 | aa066582 | Roman Shaposhnik | if (!dv_rl_vlc)
|
154 | bb270c08 | Diego Biurrun | return -ENOMEM;
|
155 | aa066582 | Roman Shaposhnik | |
156 | 5d2231ee | Fabrice Bellard | for(i = 0; i < dv_vlc.table_size; i++){ |
157 | int code= dv_vlc.table[i][0]; |
||
158 | int len = dv_vlc.table[i][1]; |
||
159 | int level, run;
|
||
160 | 115329f1 | Diego Biurrun | |
161 | 5d2231ee | Fabrice Bellard | if(len<0){ //more bits needed |
162 | run= 0;
|
||
163 | level= code; |
||
164 | } else {
|
||
165 | 901ee2be | Roman Shaposhnik | run= new_dv_vlc_run[code] + 1;
|
166 | level= new_dv_vlc_level[code]; |
||
167 | 5d2231ee | Fabrice Bellard | } |
168 | 380fd6b1 | Roman Shaposhnik | dv_rl_vlc[i].len = len; |
169 | dv_rl_vlc[i].level = level; |
||
170 | dv_rl_vlc[i].run = run; |
||
171 | 5d2231ee | Fabrice Bellard | } |
172 | bb270c08 | Diego Biurrun | free_vlc(&dv_vlc); |
173 | 7458ccbb | Roman Shaposhnik | |
174 | bb270c08 | Diego Biurrun | for (i = 0; i < NB_DV_VLC - 1; i++) { |
175 | 5da42be1 | Michael Niedermayer | if (dv_vlc_run[i] >= DV_VLC_MAP_RUN_SIZE)
|
176 | bb270c08 | Diego Biurrun | continue;
|
177 | 5da42be1 | Michael Niedermayer | #ifdef DV_CODEC_TINY_TARGET
|
178 | if (dv_vlc_level[i] >= DV_VLC_MAP_LEV_SIZE)
|
||
179 | bb270c08 | Diego Biurrun | continue;
|
180 | 5da42be1 | Michael Niedermayer | #endif
|
181 | 115329f1 | Diego Biurrun | |
182 | bb270c08 | Diego Biurrun | if (dv_vlc_map[dv_vlc_run[i]][dv_vlc_level[i]].size != 0) |
183 | continue;
|
||
184 | 115329f1 | Diego Biurrun | |
185 | bb270c08 | Diego Biurrun | dv_vlc_map[dv_vlc_run[i]][dv_vlc_level[i]].vlc = dv_vlc_bits[i] << |
186 | (!!dv_vlc_level[i]); |
||
187 | dv_vlc_map[dv_vlc_run[i]][dv_vlc_level[i]].size = dv_vlc_len[i] + |
||
188 | (!!dv_vlc_level[i]); |
||
189 | } |
||
190 | for (i = 0; i < DV_VLC_MAP_RUN_SIZE; i++) { |
||
191 | e15c3302 | Roman Shaposhnik | #ifdef DV_CODEC_TINY_TARGET
|
192 | bb270c08 | Diego Biurrun | for (j = 1; j < DV_VLC_MAP_LEV_SIZE; j++) { |
193 | if (dv_vlc_map[i][j].size == 0) { |
||
194 | dv_vlc_map[i][j].vlc = dv_vlc_map[0][j].vlc |
|
||
195 | (dv_vlc_map[i-1][0].vlc << (dv_vlc_map[0][j].size)); |
||
196 | dv_vlc_map[i][j].size = dv_vlc_map[i-1][0].size + |
||
197 | dv_vlc_map[0][j].size;
|
||
198 | } |
||
199 | } |
||
200 | e15c3302 | Roman Shaposhnik | #else
|
201 | bb270c08 | Diego Biurrun | for (j = 1; j < DV_VLC_MAP_LEV_SIZE/2; j++) { |
202 | if (dv_vlc_map[i][j].size == 0) { |
||
203 | dv_vlc_map[i][j].vlc = dv_vlc_map[0][j].vlc |
|
||
204 | (dv_vlc_map[i-1][0].vlc << (dv_vlc_map[0][j].size)); |
||
205 | dv_vlc_map[i][j].size = dv_vlc_map[i-1][0].size + |
||
206 | dv_vlc_map[0][j].size;
|
||
207 | } |
||
208 | dv_vlc_map[i][((uint16_t)(-j))&0x1ff].vlc =
|
||
209 | dv_vlc_map[i][j].vlc | 1;
|
||
210 | dv_vlc_map[i][((uint16_t)(-j))&0x1ff].size =
|
||
211 | dv_vlc_map[i][j].size; |
||
212 | } |
||
213 | e15c3302 | Roman Shaposhnik | #endif
|
214 | bb270c08 | Diego Biurrun | } |
215 | 5d2231ee | Fabrice Bellard | } |
216 | 7be166e4 | Fabrice Bellard | |
217 | 10acc479 | Roman Shaposhnik | /* Generic DSP setup */
|
218 | dsputil_init(&dsp, avctx); |
||
219 | s->get_pixels = dsp.get_pixels; |
||
220 | 7be166e4 | Fabrice Bellard | |
221 | 10acc479 | Roman Shaposhnik | /* 88DCT setup */
|
222 | s->fdct[0] = dsp.fdct;
|
||
223 | s->idct_put[0] = dsp.idct_put;
|
||
224 | for (i=0; i<64; i++) |
||
225 | s->dv_zigzag[0][i] = dsp.idct_permutation[ff_zigzag_direct[i]];
|
||
226 | 7be166e4 | Fabrice Bellard | |
227 | 10acc479 | Roman Shaposhnik | /* 248DCT setup */
|
228 | s->fdct[1] = dsp.fdct248;
|
||
229 | s->idct_put[1] = simple_idct248_put; // FIXME: need to add it to DSP |
||
230 | 4325ffd0 | Michael Niedermayer | if(avctx->lowres){
|
231 | for (i=0; i<64; i++){ |
||
232 | int j= ff_zigzag248_direct[i];
|
||
233 | s->dv_zigzag[1][i] = dsp.idct_permutation[(j&7) + (j&8)*4 + (j&48)/2]; |
||
234 | } |
||
235 | }else
|
||
236 | memcpy(s->dv_zigzag[1], ff_zigzag248_direct, 64); |
||
237 | 7be166e4 | Fabrice Bellard | |
238 | 5d2231ee | Fabrice Bellard | /* XXX: do it only for constant case */
|
239 | 10acc479 | Roman Shaposhnik | dv_build_unquantize_tables(s, dsp.idct_permutation); |
240 | 7458ccbb | Roman Shaposhnik | |
241 | 4fa1c4fa | Roman Shaposhnik | /* FIXME: I really don't think this should be here */
|
242 | if (dv_codec_profile(avctx))
|
||
243 | bb270c08 | Diego Biurrun | avctx->pix_fmt = dv_codec_profile(avctx)->pix_fmt; |
244 | 2744ca9a | Roman Shaposhnik | avctx->coded_frame = &s->picture; |
245 | c619ff6d | Michael Niedermayer | s->avctx= avctx; |
246 | 115329f1 | Diego Biurrun | |
247 | 5d2231ee | Fabrice Bellard | return 0; |
248 | } |
||
249 | |||
250 | 7458ccbb | Roman Shaposhnik | // #define VLC_DEBUG
|
251 | 901ee2be | Roman Shaposhnik | // #define printf(...) av_log(NULL, AV_LOG_ERROR, __VA_ARGS__)
|
252 | 5d2231ee | Fabrice Bellard | |
253 | 7be166e4 | Fabrice Bellard | typedef struct BlockInfo { |
254 | 0c1a9eda | Zdenek Kabelac | const uint8_t *shift_table;
|
255 | const uint8_t *scan_table;
|
||
256 | uint8_t pos; /* position in block */
|
||
257 | uint8_t dct_mode; |
||
258 | uint8_t partial_bit_count; |
||
259 | uint16_t partial_bit_buffer; |
||
260 | 7be166e4 | Fabrice Bellard | int shift_offset;
|
261 | } BlockInfo; |
||
262 | 5d2231ee | Fabrice Bellard | |
263 | /* block size in bits */
|
||
264 | 0c1a9eda | Zdenek Kabelac | static const uint16_t block_sizes[6] = { |
265 | 5d2231ee | Fabrice Bellard | 112, 112, 112, 112, 80, 80 |
266 | }; |
||
267 | e15c3302 | Roman Shaposhnik | /* bit budget for AC only in 5 MBs */
|
268 | static const int vs_total_ac_bits = (100 * 4 + 68*2) * 5; |
||
269 | /* see dv_88_areas and dv_248_areas for details */
|
||
270 | 115329f1 | Diego Biurrun | static const int mb_area_start[5] = { 1, 6, 21, 43, 64 }; |
271 | 5d2231ee | Fabrice Bellard | |
272 | #ifndef ALT_BITSTREAM_READER
|
||
273 | 924311cd | Michael Niedermayer | #warning only works with ALT_BITSTREAM_READER
|
274 | 5bb8a0da | Michael Niedermayer | static int re_index; //Hack to make it compile |
275 | 5d2231ee | Fabrice Bellard | #endif
|
276 | |||
277 | 58254257 | Roman Shaposhnik | static inline int get_bits_left(GetBitContext *s) |
278 | { |
||
279 | return s->size_in_bits - get_bits_count(s);
|
||
280 | } |
||
281 | |||
282 | static inline int get_bits_size(GetBitContext *s) |
||
283 | { |
||
284 | return s->size_in_bits;
|
||
285 | } |
||
286 | |||
287 | static inline int put_bits_left(PutBitContext* s) |
||
288 | { |
||
289 | return (s->buf_end - s->buf) * 8 - put_bits_count(s); |
||
290 | } |
||
291 | |||
292 | 5d2231ee | Fabrice Bellard | /* decode ac coefs */
|
293 | 6faa4645 | Roman Shaposhnik | static void dv_decode_ac(GetBitContext *gb, BlockInfo *mb, DCTELEM *block) |
294 | 5d2231ee | Fabrice Bellard | { |
295 | 6faa4645 | Roman Shaposhnik | int last_index = get_bits_size(gb);
|
296 | 0c1a9eda | Zdenek Kabelac | const uint8_t *scan_table = mb->scan_table;
|
297 | const uint8_t *shift_table = mb->shift_table;
|
||
298 | 7be166e4 | Fabrice Bellard | int pos = mb->pos;
|
299 | 901ee2be | Roman Shaposhnik | int partial_bit_count = mb->partial_bit_count;
|
300 | int level, pos1, run, vlc_len, index;
|
||
301 | 115329f1 | Diego Biurrun | |
302 | 6faa4645 | Roman Shaposhnik | OPEN_READER(re, gb); |
303 | 901ee2be | Roman Shaposhnik | UPDATE_CACHE(re, gb); |
304 | 115329f1 | Diego Biurrun | |
305 | 5d2231ee | Fabrice Bellard | /* if we must parse a partial vlc, we do it here */
|
306 | if (partial_bit_count > 0) { |
||
307 | 901ee2be | Roman Shaposhnik | re_cache = ((unsigned)re_cache >> partial_bit_count) |
|
308 | bb270c08 | Diego Biurrun | (mb->partial_bit_buffer << (sizeof(re_cache)*8 - partial_bit_count)); |
309 | re_index -= partial_bit_count; |
||
310 | mb->partial_bit_count = 0;
|
||
311 | 5d2231ee | Fabrice Bellard | } |
312 | |||
313 | /* get the AC coefficients until last_index is reached */
|
||
314 | for(;;) {
|
||
315 | #ifdef VLC_DEBUG
|
||
316 | 901ee2be | Roman Shaposhnik | printf("%2d: bits=%04x index=%d\n", pos, SHOW_UBITS(re, gb, 16), re_index); |
317 | 5d2231ee | Fabrice Bellard | #endif
|
318 | 901ee2be | Roman Shaposhnik | /* our own optimized GET_RL_VLC */
|
319 | index = NEG_USR32(re_cache, TEX_VLC_BITS); |
||
320 | bb270c08 | Diego Biurrun | vlc_len = dv_rl_vlc[index].len; |
321 | 901ee2be | Roman Shaposhnik | if (vlc_len < 0) { |
322 | index = NEG_USR32((unsigned)re_cache << TEX_VLC_BITS, -vlc_len) + dv_rl_vlc[index].level;
|
||
323 | vlc_len = TEX_VLC_BITS - vlc_len; |
||
324 | } |
||
325 | level = dv_rl_vlc[index].level; |
||
326 | bb270c08 | Diego Biurrun | run = dv_rl_vlc[index].run; |
327 | |||
328 | /* gotta check if we're still within gb boundaries */
|
||
329 | if (re_index + vlc_len > last_index) {
|
||
330 | /* should be < 16 bits otherwise a codeword could have been parsed */
|
||
331 | mb->partial_bit_count = last_index - re_index; |
||
332 | mb->partial_bit_buffer = NEG_USR32(re_cache, mb->partial_bit_count); |
||
333 | re_index = last_index; |
||
334 | break;
|
||
335 | } |
||
336 | re_index += vlc_len; |
||
337 | 901ee2be | Roman Shaposhnik | |
338 | #ifdef VLC_DEBUG
|
||
339 | bb270c08 | Diego Biurrun | printf("run=%d level=%d\n", run, level);
|
340 | 901ee2be | Roman Shaposhnik | #endif
|
341 | bb270c08 | Diego Biurrun | pos += run; |
342 | if (pos >= 64) |
||
343 | break;
|
||
344 | 115329f1 | Diego Biurrun | |
345 | c619ff6d | Michael Niedermayer | assert(level); |
346 | pos1 = scan_table[pos]; |
||
347 | block[pos1] = level << shift_table[pos1]; |
||
348 | 901ee2be | Roman Shaposhnik | |
349 | UPDATE_CACHE(re, gb); |
||
350 | 5d2231ee | Fabrice Bellard | } |
351 | 6faa4645 | Roman Shaposhnik | CLOSE_READER(re, gb); |
352 | 7be166e4 | Fabrice Bellard | mb->pos = pos; |
353 | 5d2231ee | Fabrice Bellard | } |
354 | |||
355 | 380fd6b1 | Roman Shaposhnik | static inline void bit_copy(PutBitContext *pb, GetBitContext *gb) |
356 | 5d2231ee | Fabrice Bellard | { |
357 | 380fd6b1 | Roman Shaposhnik | int bits_left = get_bits_left(gb);
|
358 | c619ff6d | Michael Niedermayer | while (bits_left >= MIN_CACHE_BITS) {
|
359 | put_bits(pb, MIN_CACHE_BITS, get_bits(gb, MIN_CACHE_BITS)); |
||
360 | bits_left -= MIN_CACHE_BITS; |
||
361 | 5d2231ee | Fabrice Bellard | } |
362 | if (bits_left > 0) { |
||
363 | put_bits(pb, bits_left, get_bits(gb, bits_left)); |
||
364 | } |
||
365 | } |
||
366 | |||
367 | /* mb_x and mb_y are in units of 8 pixels */
|
||
368 | 115329f1 | Diego Biurrun | static inline void dv_decode_video_segment(DVVideoContext *s, |
369 | uint8_t *buf_ptr1, |
||
370 | 0c1a9eda | Zdenek Kabelac | const uint16_t *mb_pos_ptr)
|
371 | 5d2231ee | Fabrice Bellard | { |
372 | int quant, dc, dct_mode, class1, j;
|
||
373 | int mb_index, mb_x, mb_y, v, last_index;
|
||
374 | DCTELEM *block, *block1; |
||
375 | 380fd6b1 | Roman Shaposhnik | int c_offset;
|
376 | 0c1a9eda | Zdenek Kabelac | uint8_t *y_ptr; |
377 | void (*idct_put)(uint8_t *dest, int line_size, DCTELEM *block); |
||
378 | uint8_t *buf_ptr; |
||
379 | 5d2231ee | Fabrice Bellard | PutBitContext pb, vs_pb; |
380 | 6faa4645 | Roman Shaposhnik | GetBitContext gb; |
381 | BlockInfo mb_data[5 * 6], *mb, *mb1; |
||
382 | DCTELEM sblock[5*6][64] __align8; |
||
383 | c619ff6d | Michael Niedermayer | uint8_t mb_bit_buffer[80 + 4] __align8; /* allow some slack */ |
384 | uint8_t vs_bit_buffer[5 * 80 + 4] __align8; /* allow some slack */ |
||
385 | 4325ffd0 | Michael Niedermayer | const int log2_blocksize= 3-s->avctx->lowres; |
386 | 115329f1 | Diego Biurrun | |
387 | c619ff6d | Michael Niedermayer | assert((((int)mb_bit_buffer)&7)==0); |
388 | assert((((int)vs_bit_buffer)&7)==0); |
||
389 | 115329f1 | Diego Biurrun | |
390 | 6faa4645 | Roman Shaposhnik | memset(sblock, 0, sizeof(sblock)); |
391 | 5d2231ee | Fabrice Bellard | |
392 | /* pass 1 : read DC and AC coefficients in blocks */
|
||
393 | buf_ptr = buf_ptr1; |
||
394 | 6faa4645 | Roman Shaposhnik | block1 = &sblock[0][0]; |
395 | 7be166e4 | Fabrice Bellard | mb1 = mb_data; |
396 | ed7debda | Alex Beregszaszi | init_put_bits(&vs_pb, vs_bit_buffer, 5 * 80); |
397 | 380fd6b1 | Roman Shaposhnik | for(mb_index = 0; mb_index < 5; mb_index++, mb1 += 6, block1 += 6 * 64) { |
398 | 5d2231ee | Fabrice Bellard | /* skip header */
|
399 | quant = buf_ptr[3] & 0x0f; |
||
400 | buf_ptr += 4;
|
||
401 | ed7debda | Alex Beregszaszi | init_put_bits(&pb, mb_bit_buffer, 80);
|
402 | 7be166e4 | Fabrice Bellard | mb = mb1; |
403 | 5d2231ee | Fabrice Bellard | block = block1; |
404 | for(j = 0;j < 6; j++) { |
||
405 | 380fd6b1 | Roman Shaposhnik | last_index = block_sizes[j]; |
406 | bb270c08 | Diego Biurrun | init_get_bits(&gb, buf_ptr, last_index); |
407 | 115329f1 | Diego Biurrun | |
408 | 5d2231ee | Fabrice Bellard | /* get the dc */
|
409 | 21e19131 | Jeff Muizelaar | dc = get_sbits(&gb, 9);
|
410 | 6faa4645 | Roman Shaposhnik | dct_mode = get_bits1(&gb); |
411 | 7be166e4 | Fabrice Bellard | mb->dct_mode = dct_mode; |
412 | mb->scan_table = s->dv_zigzag[dct_mode]; |
||
413 | 6faa4645 | Roman Shaposhnik | class1 = get_bits(&gb, 2);
|
414 | 901ee2be | Roman Shaposhnik | mb->shift_table = s->dv_idct_shift[class1 == 3][dct_mode]
|
415 | 5d2231ee | Fabrice Bellard | [quant + dv_quant_offset[class1]]; |
416 | dc = dc << 2;
|
||
417 | /* convert to unsigned because 128 is not added in the
|
||
418 | standard IDCT */
|
||
419 | dc += 1024;
|
||
420 | block[0] = dc;
|
||
421 | buf_ptr += last_index >> 3;
|
||
422 | 7be166e4 | Fabrice Bellard | mb->pos = 0;
|
423 | mb->partial_bit_count = 0;
|
||
424 | 5d2231ee | Fabrice Bellard | |
425 | 4fa1c4fa | Roman Shaposhnik | #ifdef VLC_DEBUG
|
426 | printf("MB block: %d, %d ", mb_index, j);
|
||
427 | #endif
|
||
428 | 6faa4645 | Roman Shaposhnik | dv_decode_ac(&gb, mb, block); |
429 | 5d2231ee | Fabrice Bellard | |
430 | /* write the remaining bits in a new buffer only if the
|
||
431 | block is finished */
|
||
432 | 380fd6b1 | Roman Shaposhnik | if (mb->pos >= 64) |
433 | 6faa4645 | Roman Shaposhnik | bit_copy(&pb, &gb); |
434 | 115329f1 | Diego Biurrun | |
435 | 5d2231ee | Fabrice Bellard | block += 64;
|
436 | 7be166e4 | Fabrice Bellard | mb++; |
437 | 5d2231ee | Fabrice Bellard | } |
438 | 115329f1 | Diego Biurrun | |
439 | 5d2231ee | Fabrice Bellard | /* pass 2 : we can do it just after */
|
440 | #ifdef VLC_DEBUG
|
||
441 | 380fd6b1 | Roman Shaposhnik | printf("***pass 2 size=%d MB#=%d\n", put_bits_count(&pb), mb_index);
|
442 | 5d2231ee | Fabrice Bellard | #endif
|
443 | block = block1; |
||
444 | 7be166e4 | Fabrice Bellard | mb = mb1; |
445 | 6faa4645 | Roman Shaposhnik | init_get_bits(&gb, mb_bit_buffer, put_bits_count(&pb)); |
446 | bb270c08 | Diego Biurrun | flush_put_bits(&pb); |
447 | 380fd6b1 | Roman Shaposhnik | for(j = 0;j < 6; j++, block += 64, mb++) { |
448 | 6faa4645 | Roman Shaposhnik | if (mb->pos < 64 && get_bits_left(&gb) > 0) { |
449 | dv_decode_ac(&gb, mb, block); |
||
450 | 5d2231ee | Fabrice Bellard | /* if still not finished, no need to parse other blocks */
|
451 | 380fd6b1 | Roman Shaposhnik | if (mb->pos < 64) |
452 | break;
|
||
453 | 5d2231ee | Fabrice Bellard | } |
454 | } |
||
455 | /* all blocks are finished, so the extra bytes can be used at
|
||
456 | the video segment level */
|
||
457 | 380fd6b1 | Roman Shaposhnik | if (j >= 6) |
458 | bb270c08 | Diego Biurrun | bit_copy(&vs_pb, &gb); |
459 | 5d2231ee | Fabrice Bellard | } |
460 | |||
461 | /* we need a pass other the whole video segment */
|
||
462 | #ifdef VLC_DEBUG
|
||
463 | 380fd6b1 | Roman Shaposhnik | printf("***pass 3 size=%d\n", put_bits_count(&vs_pb));
|
464 | 5d2231ee | Fabrice Bellard | #endif
|
465 | 6faa4645 | Roman Shaposhnik | block = &sblock[0][0]; |
466 | 5d2231ee | Fabrice Bellard | mb = mb_data; |
467 | 6faa4645 | Roman Shaposhnik | init_get_bits(&gb, vs_bit_buffer, put_bits_count(&vs_pb)); |
468 | 380fd6b1 | Roman Shaposhnik | flush_put_bits(&vs_pb); |
469 | 5d2231ee | Fabrice Bellard | for(mb_index = 0; mb_index < 5; mb_index++) { |
470 | for(j = 0;j < 6; j++) { |
||
471 | 380fd6b1 | Roman Shaposhnik | if (mb->pos < 64) { |
472 | 5d2231ee | Fabrice Bellard | #ifdef VLC_DEBUG
|
473 | printf("start %d:%d\n", mb_index, j);
|
||
474 | #endif
|
||
475 | 6faa4645 | Roman Shaposhnik | dv_decode_ac(&gb, mb, block); |
476 | 5d2231ee | Fabrice Bellard | } |
477 | bb270c08 | Diego Biurrun | if (mb->pos >= 64 && mb->pos < 127) |
478 | av_log(NULL, AV_LOG_ERROR, "AC EOB marker is absent pos=%d\n", mb->pos); |
||
479 | 5d2231ee | Fabrice Bellard | block += 64;
|
480 | 7be166e4 | Fabrice Bellard | mb++; |
481 | 5d2231ee | Fabrice Bellard | } |
482 | } |
||
483 | 115329f1 | Diego Biurrun | |
484 | 5d2231ee | Fabrice Bellard | /* compute idct and place blocks */
|
485 | 6faa4645 | Roman Shaposhnik | block = &sblock[0][0]; |
486 | 5d2231ee | Fabrice Bellard | mb = mb_data; |
487 | for(mb_index = 0; mb_index < 5; mb_index++) { |
||
488 | v = *mb_pos_ptr++; |
||
489 | mb_x = v & 0xff;
|
||
490 | mb_y = v >> 8;
|
||
491 | 4325ffd0 | Michael Niedermayer | y_ptr = s->picture.data[0] + ((mb_y * s->picture.linesize[0] + mb_x)<<log2_blocksize); |
492 | 7458ccbb | Roman Shaposhnik | if (s->sys->pix_fmt == PIX_FMT_YUV411P)
|
493 | 4325ffd0 | Michael Niedermayer | c_offset = ((mb_y * s->picture.linesize[1] + (mb_x >> 2))<<log2_blocksize); |
494 | 5d2231ee | Fabrice Bellard | else
|
495 | 4325ffd0 | Michael Niedermayer | c_offset = (((mb_y >> 1) * s->picture.linesize[1] + (mb_x >> 1))<<log2_blocksize); |
496 | 5d2231ee | Fabrice Bellard | for(j = 0;j < 6; j++) { |
497 | 4325ffd0 | Michael Niedermayer | idct_put = s->idct_put[mb->dct_mode && log2_blocksize==3];
|
498 | 5d2231ee | Fabrice Bellard | if (j < 4) { |
499 | 7458ccbb | Roman Shaposhnik | if (s->sys->pix_fmt == PIX_FMT_YUV411P && mb_x < (704 / 8)) { |
500 | 1c05e11d | Fabrice Bellard | /* NOTE: at end of line, the macroblock is handled as 420 */
|
501 | 4325ffd0 | Michael Niedermayer | idct_put(y_ptr + (j<<log2_blocksize), s->picture.linesize[0], block);
|
502 | 5d2231ee | Fabrice Bellard | } else {
|
503 | 4325ffd0 | Michael Niedermayer | idct_put(y_ptr + (((j & 1) + (j >> 1) * s->picture.linesize[0])<<log2_blocksize), |
504 | 7458ccbb | Roman Shaposhnik | s->picture.linesize[0], block);
|
505 | 5d2231ee | Fabrice Bellard | } |
506 | } else {
|
||
507 | 7458ccbb | Roman Shaposhnik | if (s->sys->pix_fmt == PIX_FMT_YUV411P && mb_x >= (704 / 8)) { |
508 | 00c28046 | Roman Shaposhnik | uint64_t aligned_pixels[64/8]; |
509 | f539eb52 | Michael Niedermayer | uint8_t *pixels= (uint8_t*)aligned_pixels; |
510 | bb270c08 | Diego Biurrun | uint8_t *c_ptr, *c_ptr1, *ptr, *ptr1; |
511 | 4325ffd0 | Michael Niedermayer | int x, y, linesize;
|
512 | 1c05e11d | Fabrice Bellard | /* NOTE: at end of line, the macroblock is handled as 420 */
|
513 | idct_put(pixels, 8, block);
|
||
514 | 7458ccbb | Roman Shaposhnik | linesize = s->picture.linesize[6 - j];
|
515 | c_ptr = s->picture.data[6 - j] + c_offset;
|
||
516 | 1c05e11d | Fabrice Bellard | ptr = pixels; |
517 | 4325ffd0 | Michael Niedermayer | for(y = 0;y < (1<<log2_blocksize); y++) { |
518 | ptr1= ptr + (1<<(log2_blocksize-1)); |
||
519 | c_ptr1 = c_ptr + (linesize<<log2_blocksize); |
||
520 | for(x=0; x < (1<<(log2_blocksize-1)); x++){ |
||
521 | c_ptr[x]= ptr[x]; c_ptr1[x]= ptr1[x]; |
||
522 | } |
||
523 | 62cf114b | Michael Niedermayer | c_ptr += linesize; |
524 | 1c05e11d | Fabrice Bellard | ptr += 8;
|
525 | } |
||
526 | } else {
|
||
527 | /* don't ask me why they inverted Cb and Cr ! */
|
||
528 | 115329f1 | Diego Biurrun | idct_put(s->picture.data[6 - j] + c_offset,
|
529 | 7458ccbb | Roman Shaposhnik | s->picture.linesize[6 - j], block);
|
530 | 1c05e11d | Fabrice Bellard | } |
531 | 5d2231ee | Fabrice Bellard | } |
532 | block += 64;
|
||
533 | 7be166e4 | Fabrice Bellard | mb++; |
534 | 5d2231ee | Fabrice Bellard | } |
535 | } |
||
536 | } |
||
537 | |||
538 | e15c3302 | Roman Shaposhnik | #ifdef DV_CODEC_TINY_TARGET
|
539 | 4fa1c4fa | Roman Shaposhnik | /* Converts run and level (where level != 0) pair into vlc, returning bit size */
|
540 | c619ff6d | Michael Niedermayer | static always_inline int dv_rl2vlc(int run, int level, int sign, uint32_t* vlc) |
541 | 4fa1c4fa | Roman Shaposhnik | { |
542 | int size;
|
||
543 | e15c3302 | Roman Shaposhnik | if (run < DV_VLC_MAP_RUN_SIZE && level < DV_VLC_MAP_LEV_SIZE) {
|
544 | *vlc = dv_vlc_map[run][level].vlc | sign; |
||
545 | bb270c08 | Diego Biurrun | size = dv_vlc_map[run][level].size; |
546 | 4fa1c4fa | Roman Shaposhnik | } |
547 | 115329f1 | Diego Biurrun | else {
|
548 | e15c3302 | Roman Shaposhnik | if (level < DV_VLC_MAP_LEV_SIZE) {
|
549 | bb270c08 | Diego Biurrun | *vlc = dv_vlc_map[0][level].vlc | sign;
|
550 | size = dv_vlc_map[0][level].size;
|
||
551 | } else {
|
||
552 | e15c3302 | Roman Shaposhnik | *vlc = 0xfe00 | (level << 1) | sign; |
553 | bb270c08 | Diego Biurrun | size = 16;
|
554 | } |
||
555 | if (run) {
|
||
556 | *vlc |= ((run < 16) ? dv_vlc_map[run-1][0].vlc : |
||
557 | (0x1f80 | (run - 1))) << size; |
||
558 | size += (run < 16) ? dv_vlc_map[run-1][0].size : 13; |
||
559 | } |
||
560 | 4fa1c4fa | Roman Shaposhnik | } |
561 | 115329f1 | Diego Biurrun | |
562 | 4fa1c4fa | Roman Shaposhnik | return size;
|
563 | } |
||
564 | |||
565 | c619ff6d | Michael Niedermayer | static always_inline int dv_rl2vlc_size(int run, int level) |
566 | e15c3302 | Roman Shaposhnik | { |
567 | int size;
|
||
568 | 115329f1 | Diego Biurrun | |
569 | e15c3302 | Roman Shaposhnik | if (run < DV_VLC_MAP_RUN_SIZE && level < DV_VLC_MAP_LEV_SIZE) {
|
570 | bb270c08 | Diego Biurrun | size = dv_vlc_map[run][level].size; |
571 | e15c3302 | Roman Shaposhnik | } |
572 | 115329f1 | Diego Biurrun | else {
|
573 | bb270c08 | Diego Biurrun | size = (level < DV_VLC_MAP_LEV_SIZE) ? dv_vlc_map[0][level].size : 16; |
574 | if (run) {
|
||
575 | size += (run < 16) ? dv_vlc_map[run-1][0].size : 13; |
||
576 | } |
||
577 | e15c3302 | Roman Shaposhnik | } |
578 | return size;
|
||
579 | } |
||
580 | #else
|
||
581 | c619ff6d | Michael Niedermayer | static always_inline int dv_rl2vlc(int run, int l, int sign, uint32_t* vlc) |
582 | e15c3302 | Roman Shaposhnik | { |
583 | c619ff6d | Michael Niedermayer | *vlc = dv_vlc_map[run][l].vlc | sign; |
584 | return dv_vlc_map[run][l].size;
|
||
585 | e15c3302 | Roman Shaposhnik | } |
586 | |||
587 | static always_inline int dv_rl2vlc_size(int run, int l) |
||
588 | { |
||
589 | c619ff6d | Michael Niedermayer | return dv_vlc_map[run][l].size;
|
590 | e15c3302 | Roman Shaposhnik | } |
591 | #endif
|
||
592 | |||
593 | 4fa1c4fa | Roman Shaposhnik | typedef struct EncBlockInfo { |
594 | e15c3302 | Roman Shaposhnik | int area_q[4]; |
595 | int bit_size[4]; |
||
596 | c619ff6d | Michael Niedermayer | int prev[5]; |
597 | e15c3302 | Roman Shaposhnik | int cur_ac;
|
598 | 4fa1c4fa | Roman Shaposhnik | int cno;
|
599 | int dct_mode;
|
||
600 | c619ff6d | Michael Niedermayer | DCTELEM mb[64];
|
601 | uint8_t next[64];
|
||
602 | uint8_t sign[64];
|
||
603 | e15c3302 | Roman Shaposhnik | uint8_t partial_bit_count; |
604 | uint32_t partial_bit_buffer; /* we can't use uint16_t here */
|
||
605 | 4fa1c4fa | Roman Shaposhnik | } EncBlockInfo; |
606 | |||
607 | 115329f1 | Diego Biurrun | static always_inline PutBitContext* dv_encode_ac(EncBlockInfo* bi, PutBitContext* pb_pool,
|
608 | c619ff6d | Michael Niedermayer | PutBitContext* pb_end) |
609 | 4fa1c4fa | Roman Shaposhnik | { |
610 | c619ff6d | Michael Niedermayer | int prev;
|
611 | e15c3302 | Roman Shaposhnik | int bits_left;
|
612 | PutBitContext* pb = pb_pool; |
||
613 | int size = bi->partial_bit_count;
|
||
614 | uint32_t vlc = bi->partial_bit_buffer; |
||
615 | c619ff6d | Michael Niedermayer | |
616 | e15c3302 | Roman Shaposhnik | bi->partial_bit_count = bi->partial_bit_buffer = 0;
|
617 | c619ff6d | Michael Niedermayer | for(;;){
|
618 | e15c3302 | Roman Shaposhnik | /* Find suitable storage space */
|
619 | e7a18d5d | Roman Shaposhnik | for (; size > (bits_left = put_bits_left(pb)); pb++) {
|
620 | e15c3302 | Roman Shaposhnik | if (bits_left) {
|
621 | size -= bits_left; |
||
622 | bb270c08 | Diego Biurrun | put_bits(pb, bits_left, vlc >> size); |
623 | vlc = vlc & ((1<<size)-1); |
||
624 | } |
||
625 | if (pb + 1 >= pb_end) { |
||
626 | bi->partial_bit_count = size; |
||
627 | bi->partial_bit_buffer = vlc; |
||
628 | return pb;
|
||
629 | } |
||
630 | e15c3302 | Roman Shaposhnik | } |
631 | 115329f1 | Diego Biurrun | |
632 | e15c3302 | Roman Shaposhnik | /* Store VLC */
|
633 | put_bits(pb, size, vlc); |
||
634 | 115329f1 | Diego Biurrun | |
635 | c619ff6d | Michael Niedermayer | if(bi->cur_ac>=64) |
636 | break;
|
||
637 | 115329f1 | Diego Biurrun | |
638 | e15c3302 | Roman Shaposhnik | /* Construct the next VLC */
|
639 | c619ff6d | Michael Niedermayer | prev= bi->cur_ac; |
640 | bi->cur_ac = bi->next[prev]; |
||
641 | if(bi->cur_ac < 64){ |
||
642 | size = dv_rl2vlc(bi->cur_ac - prev - 1, bi->mb[bi->cur_ac], bi->sign[bi->cur_ac], &vlc);
|
||
643 | } else {
|
||
644 | e15c3302 | Roman Shaposhnik | size = 4; vlc = 6; /* End Of Block stamp */ |
645 | } |
||
646 | c619ff6d | Michael Niedermayer | } |
647 | return pb;
|
||
648 | 4fa1c4fa | Roman Shaposhnik | } |
649 | |||
650 | 115329f1 | Diego Biurrun | static always_inline void dv_set_class_number(DCTELEM* blk, EncBlockInfo* bi, |
651 | e15c3302 | Roman Shaposhnik | const uint8_t* zigzag_scan, int bias) |
652 | 4fa1c4fa | Roman Shaposhnik | { |
653 | e15c3302 | Roman Shaposhnik | int i, area;
|
654 | c619ff6d | Michael Niedermayer | static const int classes[] = {12, 24, 36, 0xffff}; |
655 | int max=12; |
||
656 | int prev=0; |
||
657 | e15c3302 | Roman Shaposhnik | |
658 | 115329f1 | Diego Biurrun | bi->mb[0] = blk[0]; |
659 | |||
660 | e15c3302 | Roman Shaposhnik | for (area = 0; area < 4; area++) { |
661 | c619ff6d | Michael Niedermayer | bi->prev[area] = prev; |
662 | bi->bit_size[area] = 1; // 4 areas 4 bits for EOB :) |
||
663 | e15c3302 | Roman Shaposhnik | for (i=mb_area_start[area]; i<mb_area_start[area+1]; i++) { |
664 | c619ff6d | Michael Niedermayer | int level = blk[zigzag_scan[i]];
|
665 | 115329f1 | Diego Biurrun | |
666 | c619ff6d | Michael Niedermayer | if (level+15 > 30U) { |
667 | bi->sign[i] = (level>>31)&1; |
||
668 | bi->mb[i] = level= ABS(level)>>4;
|
||
669 | if(level>max) max= level;
|
||
670 | bi->bit_size[area] += dv_rl2vlc_size(i - prev - 1, level);
|
||
671 | bi->next[prev]= i; |
||
672 | prev= i; |
||
673 | } |
||
674 | e15c3302 | Roman Shaposhnik | } |
675 | 4fa1c4fa | Roman Shaposhnik | } |
676 | c619ff6d | Michael Niedermayer | bi->next[prev]= i; |
677 | for(bi->cno = 0; max > classes[bi->cno]; bi->cno++); |
||
678 | |||
679 | e15c3302 | Roman Shaposhnik | bi->cno += bias; |
680 | 115329f1 | Diego Biurrun | |
681 | c619ff6d | Michael Niedermayer | if (bi->cno >= 3) { |
682 | 4fa1c4fa | Roman Shaposhnik | bi->cno = 3;
|
683 | c619ff6d | Michael Niedermayer | prev=0;
|
684 | i= bi->next[prev]; |
||
685 | for (area = 0; area < 4; area++) { |
||
686 | bi->prev[area] = prev; |
||
687 | bi->bit_size[area] = 1; // 4 areas 4 bits for EOB :) |
||
688 | for (; i<mb_area_start[area+1]; i= bi->next[i]) { |
||
689 | bi->mb[i] >>=1;
|
||
690 | 115329f1 | Diego Biurrun | |
691 | c619ff6d | Michael Niedermayer | if (bi->mb[i]) {
|
692 | bi->bit_size[area] += dv_rl2vlc_size(i - prev - 1, bi->mb[i]);
|
||
693 | bi->next[prev]= i; |
||
694 | prev= i; |
||
695 | } |
||
696 | } |
||
697 | } |
||
698 | bi->next[prev]= i; |
||
699 | e15c3302 | Roman Shaposhnik | } |
700 | 4fa1c4fa | Roman Shaposhnik | } |
701 | |||
702 | c619ff6d | Michael Niedermayer | //FIXME replace this by dsputil
|
703 | e15c3302 | Roman Shaposhnik | #define SC(x, y) ((s[x] - s[y]) ^ ((s[x] - s[y]) >> 7)) |
704 | static always_inline int dv_guess_dct_mode(DCTELEM *blk) { |
||
705 | DCTELEM *s; |
||
706 | int score88 = 0; |
||
707 | int score248 = 0; |
||
708 | int i;
|
||
709 | 115329f1 | Diego Biurrun | |
710 | e15c3302 | Roman Shaposhnik | /* Compute 8-8 score (small values give a better chance for 8-8 DCT) */
|
711 | s = blk; |
||
712 | for(i=0; i<7; i++) { |
||
713 | 115329f1 | Diego Biurrun | score88 += SC(0, 8) + SC(1, 9) + SC(2, 10) + SC(3, 11) + |
714 | bb270c08 | Diego Biurrun | SC(4, 12) + SC(5,13) + SC(6, 14) + SC(7, 15); |
715 | e15c3302 | Roman Shaposhnik | s += 8;
|
716 | } |
||
717 | /* Compute 2-4-8 score (small values give a better chance for 2-4-8 DCT) */
|
||
718 | s = blk; |
||
719 | for(i=0; i<6; i++) { |
||
720 | score248 += SC(0, 16) + SC(1,17) + SC(2, 18) + SC(3, 19) + |
||
721 | bb270c08 | Diego Biurrun | SC(4, 20) + SC(5,21) + SC(6, 22) + SC(7, 23); |
722 | e15c3302 | Roman Shaposhnik | s += 8;
|
723 | 10acc479 | Roman Shaposhnik | } |
724 | e15c3302 | Roman Shaposhnik | |
725 | return (score88 - score248 > -10); |
||
726 | } |
||
727 | |||
728 | static inline void dv_guess_qnos(EncBlockInfo* blks, int* qnos) |
||
729 | { |
||
730 | int size[5]; |
||
731 | c619ff6d | Michael Niedermayer | int i, j, k, a, prev;
|
732 | e15c3302 | Roman Shaposhnik | EncBlockInfo* b; |
733 | c619ff6d | Michael Niedermayer | |
734 | e15c3302 | Roman Shaposhnik | do {
|
735 | b = blks; |
||
736 | for (i=0; i<5; i++) { |
||
737 | if (!qnos[i])
|
||
738 | bb270c08 | Diego Biurrun | continue;
|
739 | 115329f1 | Diego Biurrun | |
740 | bb270c08 | Diego Biurrun | qnos[i]--; |
741 | size[i] = 0;
|
||
742 | e15c3302 | Roman Shaposhnik | for (j=0; j<6; j++, b++) { |
743 | bb270c08 | Diego Biurrun | for (a=0; a<4; a++) { |
744 | if (b->area_q[a] != dv_quant_shifts[qnos[i] + dv_quant_offset[b->cno]][a]) {
|
||
745 | b->bit_size[a] = 1; // 4 areas 4 bits for EOB :) |
||
746 | b->area_q[a]++; |
||
747 | c619ff6d | Michael Niedermayer | prev= b->prev[a]; |
748 | for (k= b->next[prev] ; k<mb_area_start[a+1]; k= b->next[k]) { |
||
749 | bb270c08 | Diego Biurrun | b->mb[k] >>= 1;
|
750 | if (b->mb[k]) {
|
||
751 | c619ff6d | Michael Niedermayer | b->bit_size[a] += dv_rl2vlc_size(k - prev - 1, b->mb[k]);
|
752 | bb270c08 | Diego Biurrun | prev= k; |
753 | c619ff6d | Michael Niedermayer | } else {
|
754 | b->next[prev] = b->next[k]; |
||
755 | } |
||
756 | bb270c08 | Diego Biurrun | } |
757 | c619ff6d | Michael Niedermayer | b->prev[a+1]= prev;
|
758 | bb270c08 | Diego Biurrun | } |
759 | size[i] += b->bit_size[a]; |
||
760 | } |
||
761 | } |
||
762 | e15c3302 | Roman Shaposhnik | } |
763 | 115329f1 | Diego Biurrun | } while ((vs_total_ac_bits < size[0] + size[1] + size[2] + size[3] + size[4]) && |
764 | e15c3302 | Roman Shaposhnik | (qnos[0]|qnos[1]|qnos[2]|qnos[3]|qnos[4])); |
765 | 10acc479 | Roman Shaposhnik | } |
766 | |||
767 | 4fa1c4fa | Roman Shaposhnik | /*
|
768 | * This is a very rough initial implementaion. The performance is
|
||
769 | 115329f1 | Diego Biurrun | * horrible and the weighting is missing. But it's missing from the
|
770 | 10acc479 | Roman Shaposhnik | * decoding step also -- so at least we're on the same page with decoder ;-)
|
771 | 4fa1c4fa | Roman Shaposhnik | */
|
772 | 115329f1 | Diego Biurrun | static inline void dv_encode_video_segment(DVVideoContext *s, |
773 | uint8_t *dif, |
||
774 | 4fa1c4fa | Roman Shaposhnik | const uint16_t *mb_pos_ptr)
|
775 | { |
||
776 | int mb_index, i, j, v;
|
||
777 | 115329f1 | Diego Biurrun | int mb_x, mb_y, c_offset, linesize;
|
778 | 4fa1c4fa | Roman Shaposhnik | uint8_t* y_ptr; |
779 | uint8_t* data; |
||
780 | e15c3302 | Roman Shaposhnik | uint8_t* ptr; |
781 | 4fa1c4fa | Roman Shaposhnik | int do_edge_wrap;
|
782 | e15c3302 | Roman Shaposhnik | DCTELEM block[64] __align8;
|
783 | 4fa1c4fa | Roman Shaposhnik | EncBlockInfo enc_blks[5*6]; |
784 | e15c3302 | Roman Shaposhnik | PutBitContext pbs[5*6]; |
785 | 115329f1 | Diego Biurrun | PutBitContext* pb; |
786 | 4fa1c4fa | Roman Shaposhnik | EncBlockInfo* enc_blk; |
787 | e15c3302 | Roman Shaposhnik | int vs_bit_size = 0; |
788 | int qnos[5]; |
||
789 | 115329f1 | Diego Biurrun | |
790 | c619ff6d | Michael Niedermayer | assert((((int)block) & 7) == 0); |
791 | 115329f1 | Diego Biurrun | |
792 | 10acc479 | Roman Shaposhnik | enc_blk = &enc_blks[0];
|
793 | e15c3302 | Roman Shaposhnik | pb = &pbs[0];
|
794 | 4fa1c4fa | Roman Shaposhnik | for(mb_index = 0; mb_index < 5; mb_index++) { |
795 | v = *mb_pos_ptr++; |
||
796 | mb_x = v & 0xff;
|
||
797 | mb_y = v >> 8;
|
||
798 | y_ptr = s->picture.data[0] + (mb_y * s->picture.linesize[0] * 8) + (mb_x * 8); |
||
799 | bb270c08 | Diego Biurrun | c_offset = (s->sys->pix_fmt == PIX_FMT_YUV411P) ? |
800 | ((mb_y * s->picture.linesize[1] * 8) + ((mb_x >> 2) * 8)) : |
||
801 | (((mb_y >> 1) * s->picture.linesize[1] * 8) + ((mb_x >> 1) * 8)); |
||
802 | do_edge_wrap = 0;
|
||
803 | qnos[mb_index] = 15; /* No quantization */ |
||
804 | e15c3302 | Roman Shaposhnik | ptr = dif + mb_index*80 + 4; |
805 | 4fa1c4fa | Roman Shaposhnik | for(j = 0;j < 6; j++) { |
806 | if (j < 4) { /* Four Y blocks */ |
||
807 | bb270c08 | Diego Biurrun | /* NOTE: at end of line, the macroblock is handled as 420 */
|
808 | if (s->sys->pix_fmt == PIX_FMT_YUV411P && mb_x < (704 / 8)) { |
||
809 | 4fa1c4fa | Roman Shaposhnik | data = y_ptr + (j * 8);
|
810 | } else {
|
||
811 | data = y_ptr + ((j & 1) * 8) + ((j >> 1) * 8 * s->picture.linesize[0]); |
||
812 | } |
||
813 | bb270c08 | Diego Biurrun | linesize = s->picture.linesize[0];
|
814 | 4fa1c4fa | Roman Shaposhnik | } else { /* Cr and Cb blocks */ |
815 | bb270c08 | Diego Biurrun | /* don't ask Fabrice why they inverted Cb and Cr ! */
|
816 | data = s->picture.data[6 - j] + c_offset;
|
||
817 | linesize = s->picture.linesize[6 - j];
|
||
818 | if (s->sys->pix_fmt == PIX_FMT_YUV411P && mb_x >= (704 / 8)) |
||
819 | do_edge_wrap = 1;
|
||
820 | } |
||
821 | |||
822 | /* Everything is set up -- now just copy data -> DCT block */
|
||
823 | if (do_edge_wrap) { /* Edge wrap copy: 4x16 -> 8x8 */ |
||
824 | uint8_t* d; |
||
825 | DCTELEM *b = block; |
||
826 | for (i=0;i<8;i++) { |
||
827 | d = data + 8 * linesize;
|
||
828 | b[0] = data[0]; b[1] = data[1]; b[2] = data[2]; b[3] = data[3]; |
||
829 | 4fa1c4fa | Roman Shaposhnik | b[4] = d[0]; b[5] = d[1]; b[6] = d[2]; b[7] = d[3]; |
830 | bb270c08 | Diego Biurrun | data += linesize; |
831 | b += 8;
|
||
832 | } |
||
833 | } else { /* Simple copy: 8x8 -> 8x8 */ |
||
834 | s->get_pixels(block, data, linesize); |
||
835 | } |
||
836 | 115329f1 | Diego Biurrun | |
837 | c619ff6d | Michael Niedermayer | if(s->avctx->flags & CODEC_FLAG_INTERLACED_DCT)
|
838 | enc_blk->dct_mode = dv_guess_dct_mode(block); |
||
839 | else
|
||
840 | enc_blk->dct_mode = 0;
|
||
841 | bb270c08 | Diego Biurrun | enc_blk->area_q[0] = enc_blk->area_q[1] = enc_blk->area_q[2] = enc_blk->area_q[3] = 0; |
842 | enc_blk->partial_bit_count = 0;
|
||
843 | enc_blk->partial_bit_buffer = 0;
|
||
844 | enc_blk->cur_ac = 0;
|
||
845 | 115329f1 | Diego Biurrun | |
846 | bb270c08 | Diego Biurrun | s->fdct[enc_blk->dct_mode](block); |
847 | 115329f1 | Diego Biurrun | |
848 | bb270c08 | Diego Biurrun | dv_set_class_number(block, enc_blk, |
849 | enc_blk->dct_mode ? ff_zigzag248_direct : ff_zigzag_direct, j/4);
|
||
850 | 115329f1 | Diego Biurrun | |
851 | e15c3302 | Roman Shaposhnik | init_put_bits(pb, ptr, block_sizes[j]/8);
|
852 | bb270c08 | Diego Biurrun | put_bits(pb, 9, (uint16_t)(((enc_blk->mb[0] >> 3) - 1024 + 2) >> 2)); |
853 | put_bits(pb, 1, enc_blk->dct_mode);
|
||
854 | put_bits(pb, 2, enc_blk->cno);
|
||
855 | |||
856 | vs_bit_size += enc_blk->bit_size[0] + enc_blk->bit_size[1] + |
||
857 | enc_blk->bit_size[2] + enc_blk->bit_size[3]; |
||
858 | ++enc_blk; |
||
859 | ++pb; |
||
860 | ptr += block_sizes[j]/8;
|
||
861 | 4fa1c4fa | Roman Shaposhnik | } |
862 | } |
||
863 | |||
864 | e15c3302 | Roman Shaposhnik | if (vs_total_ac_bits < vs_bit_size)
|
865 | dv_guess_qnos(&enc_blks[0], &qnos[0]); |
||
866 | 4fa1c4fa | Roman Shaposhnik | |
867 | for (i=0; i<5; i++) { |
||
868 | e15c3302 | Roman Shaposhnik | dif[i*80 + 3] = qnos[i]; |
869 | } |
||
870 | 4fa1c4fa | Roman Shaposhnik | |
871 | e15c3302 | Roman Shaposhnik | /* First pass over individual cells only */
|
872 | for (j=0; j<5*6; j++) |
||
873 | c619ff6d | Michael Niedermayer | dv_encode_ac(&enc_blks[j], &pbs[j], &pbs[j+1]);
|
874 | 4fa1c4fa | Roman Shaposhnik | |
875 | e15c3302 | Roman Shaposhnik | /* Second pass over each MB space */
|
876 | c619ff6d | Michael Niedermayer | for (j=0; j<5*6; j+=6) { |
877 | pb= &pbs[j]; |
||
878 | for (i=0; i<6; i++) { |
||
879 | if (enc_blks[i+j].partial_bit_count)
|
||
880 | pb=dv_encode_ac(&enc_blks[i+j], pb, &pbs[j+6]);
|
||
881 | } |
||
882 | 4fa1c4fa | Roman Shaposhnik | } |
883 | |||
884 | e15c3302 | Roman Shaposhnik | /* Third and final pass over the whole vides segment space */
|
885 | c619ff6d | Michael Niedermayer | pb= &pbs[0];
|
886 | e15c3302 | Roman Shaposhnik | for (j=0; j<5*6; j++) { |
887 | c619ff6d | Michael Niedermayer | if (enc_blks[j].partial_bit_count)
|
888 | pb=dv_encode_ac(&enc_blks[j], pb, &pbs[6*5]); |
||
889 | 4fa1c4fa | Roman Shaposhnik | } |
890 | e15c3302 | Roman Shaposhnik | |
891 | for (j=0; j<5*6; j++) |
||
892 | flush_put_bits(&pbs[j]); |
||
893 | 4fa1c4fa | Roman Shaposhnik | } |
894 | |||
895 | 6faa4645 | Roman Shaposhnik | static int dv_decode_mt(AVCodecContext *avctx, void* sl) |
896 | { |
||
897 | DVVideoContext *s = avctx->priv_data; |
||
898 | 7906085f | Falk Hüffner | int slice = (size_t)sl;
|
899 | 6faa4645 | Roman Shaposhnik | dv_decode_video_segment(s, &s->buf[((slice/27)*6+(slice/3)+slice*5+7)*80], |
900 | bb270c08 | Diego Biurrun | &s->sys->video_place[slice*5]);
|
901 | 6faa4645 | Roman Shaposhnik | return 0; |
902 | } |
||
903 | |||
904 | static int dv_encode_mt(AVCodecContext *avctx, void* sl) |
||
905 | { |
||
906 | DVVideoContext *s = avctx->priv_data; |
||
907 | 7906085f | Falk Hüffner | int slice = (size_t)sl;
|
908 | 6faa4645 | Roman Shaposhnik | dv_encode_video_segment(s, &s->buf[((slice/27)*6+(slice/3)+slice*5+7)*80], |
909 | bb270c08 | Diego Biurrun | &s->sys->video_place[slice*5]);
|
910 | 6faa4645 | Roman Shaposhnik | return 0; |
911 | } |
||
912 | |||
913 | 5d2231ee | Fabrice Bellard | /* NOTE: exactly one frame must be given (120000 bytes for NTSC,
|
914 | 144000 bytes for PAL) */
|
||
915 | 115329f1 | Diego Biurrun | static int dvvideo_decode_frame(AVCodecContext *avctx, |
916 | 5d2231ee | Fabrice Bellard | void *data, int *data_size, |
917 | 0c1a9eda | Zdenek Kabelac | uint8_t *buf, int buf_size)
|
918 | 5d2231ee | Fabrice Bellard | { |
919 | 6faa4645 | Roman Shaposhnik | DVVideoContext *s = avctx->priv_data; |
920 | 115329f1 | Diego Biurrun | |
921 | 7458ccbb | Roman Shaposhnik | s->sys = dv_frame_profile(buf); |
922 | if (!s->sys || buf_size < s->sys->frame_size)
|
||
923 | return -1; /* NOTE: we only accept several full frames */ |
||
924 | e9feea59 | Arpi | |
925 | e20c4069 | Michael Niedermayer | if(s->picture.data[0]) |
926 | avctx->release_buffer(avctx, &s->picture); |
||
927 | 115329f1 | Diego Biurrun | |
928 | 7458ccbb | Roman Shaposhnik | s->picture.reference = 0;
|
929 | 856170f7 | Edward Hervey | s->picture.key_frame = 1;
|
930 | s->picture.pict_type = FF_I_TYPE; |
||
931 | 7458ccbb | Roman Shaposhnik | avctx->pix_fmt = s->sys->pix_fmt; |
932 | 4325ffd0 | Michael Niedermayer | avcodec_set_dimensions(avctx, s->sys->width, s->sys->height); |
933 | 1e491e29 | Michael Niedermayer | if(avctx->get_buffer(avctx, &s->picture) < 0) { |
934 | 9b879566 | Michel Bardiaux | av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
|
935 | 1e491e29 | Michael Niedermayer | return -1; |
936 | b0397e0e | Zdenek Kabelac | } |
937 | 2744ca9a | Roman Shaposhnik | s->picture.interlaced_frame = 1;
|
938 | 9dad924e | Michael Niedermayer | s->picture.top_field_first = 0;
|
939 | b0397e0e | Zdenek Kabelac | |
940 | 6faa4645 | Roman Shaposhnik | s->buf = buf; |
941 | aa066582 | Roman Shaposhnik | avctx->execute(avctx, dv_decode_mt, (void**)&dv_anchor[0], NULL, |
942 | bb270c08 | Diego Biurrun | s->sys->difseg_size * 27);
|
943 | 115329f1 | Diego Biurrun | |
944 | 9e398782 | Arpi | emms_c(); |
945 | |||
946 | 5d2231ee | Fabrice Bellard | /* return image */
|
947 | 492cd3a9 | Michael Niedermayer | *data_size = sizeof(AVFrame);
|
948 | *(AVFrame*)data= s->picture; |
||
949 | 115329f1 | Diego Biurrun | |
950 | 7458ccbb | Roman Shaposhnik | return s->sys->frame_size;
|
951 | 5d2231ee | Fabrice Bellard | } |
952 | |||
953 | 115329f1 | Diego Biurrun | static int dvvideo_encode_frame(AVCodecContext *c, uint8_t *buf, int buf_size, |
954 | 4fa1c4fa | Roman Shaposhnik | void *data)
|
955 | 5d2231ee | Fabrice Bellard | { |
956 | 6faa4645 | Roman Shaposhnik | DVVideoContext *s = c->priv_data; |
957 | 4fa1c4fa | Roman Shaposhnik | |
958 | s->sys = dv_codec_profile(c); |
||
959 | if (!s->sys)
|
||
960 | bb270c08 | Diego Biurrun | return -1; |
961 | 0ecca7a4 | Michael Niedermayer | if(buf_size < s->sys->frame_size)
|
962 | return -1; |
||
963 | |||
964 | 4fa1c4fa | Roman Shaposhnik | c->pix_fmt = s->sys->pix_fmt; |
965 | s->picture = *((AVFrame *)data); |
||
966 | 856170f7 | Edward Hervey | s->picture.key_frame = 1;
|
967 | s->picture.pict_type = FF_I_TYPE; |
||
968 | 4fa1c4fa | Roman Shaposhnik | |
969 | 6faa4645 | Roman Shaposhnik | s->buf = buf; |
970 | aa066582 | Roman Shaposhnik | c->execute(c, dv_encode_mt, (void**)&dv_anchor[0], NULL, |
971 | bb270c08 | Diego Biurrun | s->sys->difseg_size * 27);
|
972 | 5d2231ee | Fabrice Bellard | |
973 | 4fa1c4fa | Roman Shaposhnik | emms_c(); |
974 | return s->sys->frame_size;
|
||
975 | } |
||
976 | |||
977 | c842aa37 | Burkhard Plaum | static int dvvideo_close(AVCodecContext *c) |
978 | { |
||
979 | |||
980 | return 0; |
||
981 | } |
||
982 | |||
983 | |||
984 | 983ea0bc | Roine Gustafsson | #ifdef CONFIG_DVVIDEO_ENCODER
|
985 | 6faa4645 | Roman Shaposhnik | AVCodec dvvideo_encoder = { |
986 | "dvvideo",
|
||
987 | CODEC_TYPE_VIDEO, |
||
988 | CODEC_ID_DVVIDEO, |
||
989 | sizeof(DVVideoContext),
|
||
990 | dvvideo_init, |
||
991 | dvvideo_encode_frame, |
||
992 | c842aa37 | Burkhard Plaum | dvvideo_close, |
993 | 6faa4645 | Roman Shaposhnik | NULL,
|
994 | CODEC_CAP_DR1, |
||
995 | NULL
|
||
996 | }; |
||
997 | 983ea0bc | Roine Gustafsson | #endif // CONFIG_DVVIDEO_ENCODER |
998 | 5d2231ee | Fabrice Bellard | |
999 | AVCodec dvvideo_decoder = { |
||
1000 | "dvvideo",
|
||
1001 | CODEC_TYPE_VIDEO, |
||
1002 | CODEC_ID_DVVIDEO, |
||
1003 | 6faa4645 | Roman Shaposhnik | sizeof(DVVideoContext),
|
1004 | 4fa1c4fa | Roman Shaposhnik | dvvideo_init, |
1005 | 6faa4645 | Roman Shaposhnik | NULL,
|
1006 | c842aa37 | Burkhard Plaum | dvvideo_close, |
1007 | 5d2231ee | Fabrice Bellard | dvvideo_decode_frame, |
1008 | b0397e0e | Zdenek Kabelac | CODEC_CAP_DR1, |
1009 | 5d2231ee | Fabrice Bellard | NULL
|
1010 | }; |