GCC Code Coverage Report | |||||||||||||||||||||
|
|||||||||||||||||||||
Line | Branch | Exec | Source |
1 |
/* |
||
2 |
* SVQ1 decoder |
||
3 |
* ported to MPlayer by Arpi <arpi@thot.banki.hu> |
||
4 |
* ported to libavcodec by Nick Kurshev <nickols_k@mail.ru> |
||
5 |
* |
||
6 |
* Copyright (c) 2002 The Xine project |
||
7 |
* Copyright (c) 2002 The FFmpeg project |
||
8 |
* |
||
9 |
* SVQ1 Encoder (c) 2004 Mike Melanson <melanson@pcisys.net> |
||
10 |
* |
||
11 |
* This file is part of FFmpeg. |
||
12 |
* |
||
13 |
* FFmpeg is free software; you can redistribute it and/or |
||
14 |
* modify it under the terms of the GNU Lesser General Public |
||
15 |
* License as published by the Free Software Foundation; either |
||
16 |
* version 2.1 of the License, or (at your option) any later version. |
||
17 |
* |
||
18 |
* FFmpeg is distributed in the hope that it will be useful, |
||
19 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
20 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
||
21 |
* Lesser General Public License for more details. |
||
22 |
* |
||
23 |
* You should have received a copy of the GNU Lesser General Public |
||
24 |
* License along with FFmpeg; if not, write to the Free Software |
||
25 |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
||
26 |
*/ |
||
27 |
|||
28 |
/** |
||
29 |
* @file |
||
30 |
* Sorenson Vector Quantizer #1 (SVQ1) video codec. |
||
31 |
* For more information of the SVQ1 algorithm, visit: |
||
32 |
* http://www.pcisys.net/~melanson/codecs/ |
||
33 |
*/ |
||
34 |
|||
35 |
#include "libavutil/crc.h" |
||
36 |
#include "libavutil/thread.h" |
||
37 |
|||
38 |
#include "avcodec.h" |
||
39 |
#include "get_bits.h" |
||
40 |
#include "h263.h" |
||
41 |
#include "hpeldsp.h" |
||
42 |
#include "internal.h" |
||
43 |
#include "mathops.h" |
||
44 |
#include "svq1.h" |
||
45 |
|||
46 |
#define SVQ1_BLOCK_TYPE_VLC_BITS 3 |
||
47 |
static VLC svq1_block_type; |
||
48 |
static VLC svq1_motion_component; |
||
49 |
static VLC svq1_intra_multistage[6]; |
||
50 |
static VLC svq1_inter_multistage[6]; |
||
51 |
static VLC svq1_intra_mean; |
||
52 |
static VLC svq1_inter_mean; |
||
53 |
|||
54 |
/* motion vector (prediction) */ |
||
55 |
typedef struct svq1_pmv_s { |
||
56 |
int x; |
||
57 |
int y; |
||
58 |
} svq1_pmv; |
||
59 |
|||
60 |
typedef struct SVQ1Context { |
||
61 |
HpelDSPContext hdsp; |
||
62 |
GetBitContext gb; |
||
63 |
AVFrame *prev; |
||
64 |
|||
65 |
uint8_t *pkt_swapped; |
||
66 |
int pkt_swapped_allocated; |
||
67 |
|||
68 |
int width; |
||
69 |
int height; |
||
70 |
int frame_code; |
||
71 |
int nonref; // 1 if the current frame won't be referenced |
||
72 |
} SVQ1Context; |
||
73 |
|||
74 |
static const uint8_t string_table[256] = { |
||
75 |
0x00, 0xD5, 0x7F, 0xAA, 0xFE, 0x2B, 0x81, 0x54, |
||
76 |
0x29, 0xFC, 0x56, 0x83, 0xD7, 0x02, 0xA8, 0x7D, |
||
77 |
0x52, 0x87, 0x2D, 0xF8, 0xAC, 0x79, 0xD3, 0x06, |
||
78 |
0x7B, 0xAE, 0x04, 0xD1, 0x85, 0x50, 0xFA, 0x2F, |
||
79 |
0xA4, 0x71, 0xDB, 0x0E, 0x5A, 0x8F, 0x25, 0xF0, |
||
80 |
0x8D, 0x58, 0xF2, 0x27, 0x73, 0xA6, 0x0C, 0xD9, |
||
81 |
0xF6, 0x23, 0x89, 0x5C, 0x08, 0xDD, 0x77, 0xA2, |
||
82 |
0xDF, 0x0A, 0xA0, 0x75, 0x21, 0xF4, 0x5E, 0x8B, |
||
83 |
0x9D, 0x48, 0xE2, 0x37, 0x63, 0xB6, 0x1C, 0xC9, |
||
84 |
0xB4, 0x61, 0xCB, 0x1E, 0x4A, 0x9F, 0x35, 0xE0, |
||
85 |
0xCF, 0x1A, 0xB0, 0x65, 0x31, 0xE4, 0x4E, 0x9B, |
||
86 |
0xE6, 0x33, 0x99, 0x4C, 0x18, 0xCD, 0x67, 0xB2, |
||
87 |
0x39, 0xEC, 0x46, 0x93, 0xC7, 0x12, 0xB8, 0x6D, |
||
88 |
0x10, 0xC5, 0x6F, 0xBA, 0xEE, 0x3B, 0x91, 0x44, |
||
89 |
0x6B, 0xBE, 0x14, 0xC1, 0x95, 0x40, 0xEA, 0x3F, |
||
90 |
0x42, 0x97, 0x3D, 0xE8, 0xBC, 0x69, 0xC3, 0x16, |
||
91 |
0xEF, 0x3A, 0x90, 0x45, 0x11, 0xC4, 0x6E, 0xBB, |
||
92 |
0xC6, 0x13, 0xB9, 0x6C, 0x38, 0xED, 0x47, 0x92, |
||
93 |
0xBD, 0x68, 0xC2, 0x17, 0x43, 0x96, 0x3C, 0xE9, |
||
94 |
0x94, 0x41, 0xEB, 0x3E, 0x6A, 0xBF, 0x15, 0xC0, |
||
95 |
0x4B, 0x9E, 0x34, 0xE1, 0xB5, 0x60, 0xCA, 0x1F, |
||
96 |
0x62, 0xB7, 0x1D, 0xC8, 0x9C, 0x49, 0xE3, 0x36, |
||
97 |
0x19, 0xCC, 0x66, 0xB3, 0xE7, 0x32, 0x98, 0x4D, |
||
98 |
0x30, 0xE5, 0x4F, 0x9A, 0xCE, 0x1B, 0xB1, 0x64, |
||
99 |
0x72, 0xA7, 0x0D, 0xD8, 0x8C, 0x59, 0xF3, 0x26, |
||
100 |
0x5B, 0x8E, 0x24, 0xF1, 0xA5, 0x70, 0xDA, 0x0F, |
||
101 |
0x20, 0xF5, 0x5F, 0x8A, 0xDE, 0x0B, 0xA1, 0x74, |
||
102 |
0x09, 0xDC, 0x76, 0xA3, 0xF7, 0x22, 0x88, 0x5D, |
||
103 |
0xD6, 0x03, 0xA9, 0x7C, 0x28, 0xFD, 0x57, 0x82, |
||
104 |
0xFF, 0x2A, 0x80, 0x55, 0x01, 0xD4, 0x7E, 0xAB, |
||
105 |
0x84, 0x51, 0xFB, 0x2E, 0x7A, 0xAF, 0x05, 0xD0, |
||
106 |
0xAD, 0x78, 0xD2, 0x07, 0x53, 0x86, 0x2C, 0xF9 |
||
107 |
}; |
||
108 |
|||
109 |
#define SVQ1_PROCESS_VECTOR() \ |
||
110 |
for (; level > 0; i++) { \ |
||
111 |
/* process next depth */ \ |
||
112 |
if (i == m) { \ |
||
113 |
m = n; \ |
||
114 |
if (--level == 0) \ |
||
115 |
break; \ |
||
116 |
} \ |
||
117 |
/* divide block if next bit set */ \ |
||
118 |
if (!get_bits1(bitbuf)) \ |
||
119 |
break; \ |
||
120 |
/* add child nodes */ \ |
||
121 |
list[n++] = list[i]; \ |
||
122 |
list[n++] = list[i] + (((level & 1) ? pitch : 1) << ((level >> 1) + 1));\ |
||
123 |
} |
||
124 |
|||
125 |
#define SVQ1_ADD_CODEBOOK() \ |
||
126 |
/* add codebook entries to vector */ \ |
||
127 |
for (j = 0; j < stages; j++) { \ |
||
128 |
n3 = codebook[entries[j]] ^ 0x80808080; \ |
||
129 |
n1 += (n3 & 0xFF00FF00) >> 8; \ |
||
130 |
n2 += n3 & 0x00FF00FF; \ |
||
131 |
} \ |
||
132 |
\ |
||
133 |
/* clip to [0..255] */ \ |
||
134 |
if (n1 & 0xFF00FF00) { \ |
||
135 |
n3 = (n1 >> 15 & 0x00010001 | 0x01000100) - 0x00010001; \ |
||
136 |
n1 += 0x7F007F00; \ |
||
137 |
n1 |= (~n1 >> 15 & 0x00010001 | 0x01000100) - 0x00010001; \ |
||
138 |
n1 &= n3 & 0x00FF00FF; \ |
||
139 |
} \ |
||
140 |
\ |
||
141 |
if (n2 & 0xFF00FF00) { \ |
||
142 |
n3 = (n2 >> 15 & 0x00010001 | 0x01000100) - 0x00010001; \ |
||
143 |
n2 += 0x7F007F00; \ |
||
144 |
n2 |= (~n2 >> 15 & 0x00010001 | 0x01000100) - 0x00010001; \ |
||
145 |
n2 &= n3 & 0x00FF00FF; \ |
||
146 |
} |
||
147 |
|||
148 |
#define SVQ1_CALC_CODEBOOK_ENTRIES(cbook) \ |
||
149 |
codebook = (const uint32_t *)cbook[level]; \ |
||
150 |
if (stages > 0) \ |
||
151 |
bit_cache = get_bits(bitbuf, 4 * stages); \ |
||
152 |
/* calculate codebook entries for this vector */ \ |
||
153 |
for (j = 0; j < stages; j++) { \ |
||
154 |
entries[j] = (((bit_cache >> (4 * (stages - j - 1))) & 0xF) + \ |
||
155 |
16 * j) << (level + 1); \ |
||
156 |
} \ |
||
157 |
mean -= stages * 128; \ |
||
158 |
n4 = (mean << 16) + mean; |
||
159 |
|||
160 |
12351 |
static int svq1_decode_block_intra(GetBitContext *bitbuf, uint8_t *pixels, |
|
161 |
ptrdiff_t pitch) |
||
162 |
{ |
||
163 |
uint32_t bit_cache; |
||
164 |
uint8_t *list[63]; |
||
165 |
uint32_t *dst; |
||
166 |
const uint32_t *codebook; |
||
167 |
int entries[6]; |
||
168 |
int i, j, m, n; |
||
169 |
int stages; |
||
170 |
unsigned mean; |
||
171 |
unsigned x, y, width, height, level; |
||
172 |
uint32_t n1, n2, n3, n4; |
||
173 |
|||
174 |
/* initialize list for breadth first processing of vectors */ |
||
175 |
12351 |
list[0] = pixels; |
|
176 |
|||
177 |
/* recursively process vector */ |
||
178 |
✓✓ | 256176 |
for (i = 0, m = 1, n = 1, level = 5; i < n; i++) { |
179 |
✓✓✓✓ ✓✓✓✓ ✓✓ |
475299 |
SVQ1_PROCESS_VECTOR(); |
180 |
|||
181 |
/* destination address and vector size */ |
||
182 |
243825 |
dst = (uint32_t *)list[i]; |
|
183 |
243825 |
width = 1 << ((4 + level) / 2); |
|
184 |
243825 |
height = 1 << ((3 + level) / 2); |
|
185 |
|||
186 |
/* get number of stages (-1 skips vector, 0 for mean only) */ |
||
187 |
243825 |
stages = get_vlc2(bitbuf, svq1_intra_multistage[level].table, 3, 3) - 1; |
|
188 |
|||
189 |
✓✓ | 243825 |
if (stages == -1) { |
190 |
✓✓ | 4493 |
for (y = 0; y < height; y++) |
191 |
4122 |
memset(&dst[y * (pitch / 4)], 0, width); |
|
192 |
371 |
continue; /* skip vector */ |
|
193 |
} |
||
194 |
|||
195 |
✓✓✗✓ |
243454 |
if ((stages > 0 && level >= 4)) { |
196 |
ff_dlog(NULL, |
||
197 |
"Error (svq1_decode_block_intra): invalid vector: stages=%i level=%i\n", |
||
198 |
stages, level); |
||
199 |
return AVERROR_INVALIDDATA; /* invalid vector */ |
||
200 |
} |
||
201 |
✗✓ | 243454 |
av_assert0(stages >= 0); |
202 |
|||
203 |
243454 |
mean = get_vlc2(bitbuf, svq1_intra_mean.table, 8, 3); |
|
204 |
|||
205 |
✓✓ | 243454 |
if (stages == 0) { |
206 |
✓✓ | 218229 |
for (y = 0; y < height; y++) |
207 |
158460 |
memset(&dst[y * (pitch / 4)], mean, width); |
|
208 |
} else { |
||
209 |
✓✗✓✓ |
1133305 |
SVQ1_CALC_CODEBOOK_ENTRIES(ff_svq1_intra_codebooks); |
210 |
|||
211 |
✓✓ | 682355 |
for (y = 0; y < height; y++) { |
212 |
✓✓ | 1079708 |
for (x = 0; x < width / 4; x++, codebook++) { |
213 |
581038 |
n1 = n4; |
|
214 |
581038 |
n2 = n4; |
|
215 |
✓✓✓✓ ✓✓ |
3510202 |
SVQ1_ADD_CODEBOOK() |
216 |
/* store result */ |
||
217 |
581038 |
dst[x] = n1 << 8 | n2; |
|
218 |
} |
||
219 |
498670 |
dst += pitch / 4; |
|
220 |
} |
||
221 |
} |
||
222 |
} |
||
223 |
|||
224 |
12351 |
return 0; |
|
225 |
} |
||
226 |
|||
227 |
65696 |
static int svq1_decode_block_non_intra(GetBitContext *bitbuf, uint8_t *pixels, |
|
228 |
ptrdiff_t pitch) |
||
229 |
{ |
||
230 |
uint32_t bit_cache; |
||
231 |
uint8_t *list[63]; |
||
232 |
uint32_t *dst; |
||
233 |
const uint32_t *codebook; |
||
234 |
int entries[6]; |
||
235 |
int i, j, m, n; |
||
236 |
int stages; |
||
237 |
unsigned mean; |
||
238 |
int x, y, width, height, level; |
||
239 |
uint32_t n1, n2, n3, n4; |
||
240 |
|||
241 |
/* initialize list for breadth first processing of vectors */ |
||
242 |
65696 |
list[0] = pixels; |
|
243 |
|||
244 |
/* recursively process vector */ |
||
245 |
✓✓ | 1298962 |
for (i = 0, m = 1, n = 1, level = 5; i < n; i++) { |
246 |
✓✓✓✓ ✓✓✓✓ ✓✓ |
2400836 |
SVQ1_PROCESS_VECTOR(); |
247 |
|||
248 |
/* destination address and vector size */ |
||
249 |
1233266 |
dst = (uint32_t *)list[i]; |
|
250 |
1233266 |
width = 1 << ((4 + level) / 2); |
|
251 |
1233266 |
height = 1 << ((3 + level) / 2); |
|
252 |
|||
253 |
/* get number of stages (-1 skips vector, 0 for mean only) */ |
||
254 |
1233266 |
stages = get_vlc2(bitbuf, svq1_inter_multistage[level].table, 3, 2) - 1; |
|
255 |
|||
256 |
✓✓ | 1233266 |
if (stages == -1) |
257 |
29737 |
continue; /* skip vector */ |
|
258 |
|||
259 |
✓✓✗✓ |
1203529 |
if ((stages > 0 && level >= 4)) { |
260 |
ff_dlog(NULL, |
||
261 |
"Error (svq1_decode_block_non_intra): invalid vector: stages=%i level=%i\n", |
||
262 |
stages, level); |
||
263 |
return AVERROR_INVALIDDATA; /* invalid vector */ |
||
264 |
} |
||
265 |
✗✓ | 1203529 |
av_assert0(stages >= 0); |
266 |
|||
267 |
1203529 |
mean = get_vlc2(bitbuf, svq1_inter_mean.table, 9, 3) - 256; |
|
268 |
|||
269 |
✓✓✓✓ |
3371355 |
SVQ1_CALC_CODEBOOK_ENTRIES(ff_svq1_inter_codebooks); |
270 |
|||
271 |
✓✓ | 4430939 |
for (y = 0; y < height; y++) { |
272 |
✓✓ | 7237216 |
for (x = 0; x < width / 4; x++, codebook++) { |
273 |
4009806 |
n3 = dst[x]; |
|
274 |
/* add mean value to vector */ |
||
275 |
4009806 |
n1 = n4 + ((n3 & 0xFF00FF00) >> 8); |
|
276 |
4009806 |
n2 = n4 + (n3 & 0x00FF00FF); |
|
277 |
✓✓✓✓ ✓✓ |
9362040 |
SVQ1_ADD_CODEBOOK() |
278 |
/* store result */ |
||
279 |
4009806 |
dst[x] = n1 << 8 | n2; |
|
280 |
} |
||
281 |
3227410 |
dst += pitch / 4; |
|
282 |
} |
||
283 |
} |
||
284 |
65696 |
return 0; |
|
285 |
} |
||
286 |
|||
287 |
79616 |
static int svq1_decode_motion_vector(GetBitContext *bitbuf, svq1_pmv *mv, |
|
288 |
svq1_pmv **pmv) |
||
289 |
{ |
||
290 |
int diff; |
||
291 |
int i; |
||
292 |
|||
293 |
✓✓ | 238848 |
for (i = 0; i < 2; i++) { |
294 |
/* get motion code */ |
||
295 |
159232 |
diff = get_vlc2(bitbuf, svq1_motion_component.table, 7, 2); |
|
296 |
✗✓ | 159232 |
if (diff < 0) |
297 |
return AVERROR_INVALIDDATA; |
||
298 |
✓✓ | 159232 |
else if (diff) { |
299 |
✓✓ | 78989 |
if (get_bits1(bitbuf)) |
300 |
34286 |
diff = -diff; |
|
301 |
} |
||
302 |
|||
303 |
/* add median of motion vector predictors and clip result */ |
||
304 |
✓✓ | 159232 |
if (i == 1) |
305 |
79616 |
mv->y = sign_extend(diff + mid_pred(pmv[0]->y, pmv[1]->y, pmv[2]->y), 6); |
|
306 |
else |
||
307 |
79616 |
mv->x = sign_extend(diff + mid_pred(pmv[0]->x, pmv[1]->x, pmv[2]->x), 6); |
|
308 |
} |
||
309 |
|||
310 |
79616 |
return 0; |
|
311 |
} |
||
312 |
|||
313 |
5827 |
static void svq1_skip_block(uint8_t *current, uint8_t *previous, |
|
314 |
ptrdiff_t pitch, int x, int y) |
||
315 |
{ |
||
316 |
uint8_t *src; |
||
317 |
uint8_t *dst; |
||
318 |
int i; |
||
319 |
|||
320 |
5827 |
src = &previous[x + y * pitch]; |
|
321 |
5827 |
dst = current; |
|
322 |
|||
323 |
✓✓ | 99059 |
for (i = 0; i < 16; i++) { |
324 |
93232 |
memcpy(dst, src, 16); |
|
325 |
93232 |
src += pitch; |
|
326 |
93232 |
dst += pitch; |
|
327 |
} |
||
328 |
5827 |
} |
|
329 |
|||
330 |
61056 |
static int svq1_motion_inter_block(HpelDSPContext *hdsp, GetBitContext *bitbuf, |
|
331 |
uint8_t *current, uint8_t *previous, |
||
332 |
ptrdiff_t pitch, svq1_pmv *motion, int x, int y, |
||
333 |
int width, int height) |
||
334 |
{ |
||
335 |
uint8_t *src; |
||
336 |
uint8_t *dst; |
||
337 |
svq1_pmv mv; |
||
338 |
svq1_pmv *pmv[3]; |
||
339 |
int result; |
||
340 |
|||
341 |
/* predict and decode motion vector */ |
||
342 |
61056 |
pmv[0] = &motion[0]; |
|
343 |
✓✓ | 61056 |
if (y == 0) { |
344 |
5027 |
pmv[1] = |
|
345 |
5027 |
pmv[2] = pmv[0]; |
|
346 |
} else { |
||
347 |
56029 |
pmv[1] = &motion[x / 8 + 2]; |
|
348 |
56029 |
pmv[2] = &motion[x / 8 + 4]; |
|
349 |
} |
||
350 |
|||
351 |
61056 |
result = svq1_decode_motion_vector(bitbuf, &mv, pmv); |
|
352 |
✗✓ | 61056 |
if (result) |
353 |
return result; |
||
354 |
|||
355 |
61056 |
motion[0].x = |
|
356 |
61056 |
motion[x / 8 + 2].x = |
|
357 |
61056 |
motion[x / 8 + 3].x = mv.x; |
|
358 |
61056 |
motion[0].y = |
|
359 |
61056 |
motion[x / 8 + 2].y = |
|
360 |
61056 |
motion[x / 8 + 3].y = mv.y; |
|
361 |
|||
362 |
61056 |
mv.x = av_clip(mv.x, -2 * x, 2 * (width - x - 16)); |
|
363 |
61056 |
mv.y = av_clip(mv.y, -2 * y, 2 * (height - y - 16)); |
|
364 |
|||
365 |
61056 |
src = &previous[(x + (mv.x >> 1)) + (y + (mv.y >> 1)) * pitch]; |
|
366 |
61056 |
dst = current; |
|
367 |
|||
368 |
61056 |
hdsp->put_pixels_tab[0][(mv.y & 1) << 1 | (mv.x & 1)](dst, src, pitch, 16); |
|
369 |
|||
370 |
61056 |
return 0; |
|
371 |
} |
||
372 |
|||
373 |
4640 |
static int svq1_motion_inter_4v_block(HpelDSPContext *hdsp, GetBitContext *bitbuf, |
|
374 |
uint8_t *current, uint8_t *previous, |
||
375 |
ptrdiff_t pitch, svq1_pmv *motion, int x, int y, |
||
376 |
int width, int height) |
||
377 |
{ |
||
378 |
uint8_t *src; |
||
379 |
uint8_t *dst; |
||
380 |
svq1_pmv mv; |
||
381 |
svq1_pmv *pmv[4]; |
||
382 |
int i, result; |
||
383 |
|||
384 |
/* predict and decode motion vector (0) */ |
||
385 |
4640 |
pmv[0] = &motion[0]; |
|
386 |
✓✓ | 4640 |
if (y == 0) { |
387 |
729 |
pmv[1] = |
|
388 |
729 |
pmv[2] = pmv[0]; |
|
389 |
} else { |
||
390 |
3911 |
pmv[1] = &motion[(x / 8) + 2]; |
|
391 |
3911 |
pmv[2] = &motion[(x / 8) + 4]; |
|
392 |
} |
||
393 |
|||
394 |
4640 |
result = svq1_decode_motion_vector(bitbuf, &mv, pmv); |
|
395 |
✗✓ | 4640 |
if (result) |
396 |
return result; |
||
397 |
|||
398 |
/* predict and decode motion vector (1) */ |
||
399 |
4640 |
pmv[0] = &mv; |
|
400 |
✓✓ | 4640 |
if (y == 0) { |
401 |
729 |
pmv[1] = |
|
402 |
729 |
pmv[2] = pmv[0]; |
|
403 |
} else { |
||
404 |
3911 |
pmv[1] = &motion[(x / 8) + 3]; |
|
405 |
} |
||
406 |
4640 |
result = svq1_decode_motion_vector(bitbuf, &motion[0], pmv); |
|
407 |
✗✓ | 4640 |
if (result) |
408 |
return result; |
||
409 |
|||
410 |
/* predict and decode motion vector (2) */ |
||
411 |
4640 |
pmv[1] = &motion[0]; |
|
412 |
4640 |
pmv[2] = &motion[(x / 8) + 1]; |
|
413 |
|||
414 |
4640 |
result = svq1_decode_motion_vector(bitbuf, &motion[(x / 8) + 2], pmv); |
|
415 |
✗✓ | 4640 |
if (result) |
416 |
return result; |
||
417 |
|||
418 |
/* predict and decode motion vector (3) */ |
||
419 |
4640 |
pmv[2] = &motion[(x / 8) + 2]; |
|
420 |
4640 |
pmv[3] = &motion[(x / 8) + 3]; |
|
421 |
|||
422 |
4640 |
result = svq1_decode_motion_vector(bitbuf, pmv[3], pmv); |
|
423 |
✗✓ | 4640 |
if (result) |
424 |
return result; |
||
425 |
|||
426 |
/* form predictions */ |
||
427 |
✓✓ | 23200 |
for (i = 0; i < 4; i++) { |
428 |
18560 |
int mvx = pmv[i]->x + (i & 1) * 16; |
|
429 |
18560 |
int mvy = pmv[i]->y + (i >> 1) * 16; |
|
430 |
|||
431 |
// FIXME: clipping or padding? |
||
432 |
18560 |
mvx = av_clip(mvx, -2 * x, 2 * (width - x - 8)); |
|
433 |
18560 |
mvy = av_clip(mvy, -2 * y, 2 * (height - y - 8)); |
|
434 |
|||
435 |
18560 |
src = &previous[(x + (mvx >> 1)) + (y + (mvy >> 1)) * pitch]; |
|
436 |
18560 |
dst = current; |
|
437 |
|||
438 |
18560 |
hdsp->put_pixels_tab[1][((mvy & 1) << 1) | (mvx & 1)](dst, src, pitch, 8); |
|
439 |
|||
440 |
/* select next block */ |
||
441 |
✓✓ | 18560 |
if (i & 1) |
442 |
9280 |
current += 8 * (pitch - 1); |
|
443 |
else |
||
444 |
9280 |
current += 8; |
|
445 |
} |
||
446 |
|||
447 |
4640 |
return 0; |
|
448 |
} |
||
449 |
|||
450 |
75341 |
static int svq1_decode_delta_block(AVCodecContext *avctx, HpelDSPContext *hdsp, |
|
451 |
GetBitContext *bitbuf, |
||
452 |
uint8_t *current, uint8_t *previous, |
||
453 |
ptrdiff_t pitch, svq1_pmv *motion, int x, int y, |
||
454 |
int width, int height) |
||
455 |
{ |
||
456 |
uint32_t block_type; |
||
457 |
75341 |
int result = 0; |
|
458 |
|||
459 |
/* get block type */ |
||
460 |
75341 |
block_type = get_vlc2(bitbuf, svq1_block_type.table, |
|
461 |
SVQ1_BLOCK_TYPE_VLC_BITS, 1); |
||
462 |
|||
463 |
/* reset motion vectors */ |
||
464 |
✓✓✓✓ |
75341 |
if (block_type == SVQ1_BLOCK_SKIP || block_type == SVQ1_BLOCK_INTRA) { |
465 |
9645 |
motion[0].x = |
|
466 |
9645 |
motion[0].y = |
|
467 |
9645 |
motion[x / 8 + 2].x = |
|
468 |
9645 |
motion[x / 8 + 2].y = |
|
469 |
9645 |
motion[x / 8 + 3].x = |
|
470 |
9645 |
motion[x / 8 + 3].y = 0; |
|
471 |
} |
||
472 |
|||
473 |
✓✓✓✓ ✗ |
75341 |
switch (block_type) { |
474 |
5827 |
case SVQ1_BLOCK_SKIP: |
|
475 |
5827 |
svq1_skip_block(current, previous, pitch, x, y); |
|
476 |
5827 |
break; |
|
477 |
|||
478 |
61056 |
case SVQ1_BLOCK_INTER: |
|
479 |
61056 |
result = svq1_motion_inter_block(hdsp, bitbuf, current, previous, |
|
480 |
pitch, motion, x, y, width, height); |
||
481 |
|||
482 |
✗✓ | 61056 |
if (result != 0) { |
483 |
ff_dlog(avctx, "Error in svq1_motion_inter_block %i\n", result); |
||
484 |
break; |
||
485 |
} |
||
486 |
61056 |
result = svq1_decode_block_non_intra(bitbuf, current, pitch); |
|
487 |
61056 |
break; |
|
488 |
|||
489 |
4640 |
case SVQ1_BLOCK_INTER_4V: |
|
490 |
4640 |
result = svq1_motion_inter_4v_block(hdsp, bitbuf, current, previous, |
|
491 |
pitch, motion, x, y, width, height); |
||
492 |
|||
493 |
✗✓ | 4640 |
if (result != 0) { |
494 |
ff_dlog(avctx, "Error in svq1_motion_inter_4v_block %i\n", result); |
||
495 |
break; |
||
496 |
} |
||
497 |
4640 |
result = svq1_decode_block_non_intra(bitbuf, current, pitch); |
|
498 |
4640 |
break; |
|
499 |
|||
500 |
3818 |
case SVQ1_BLOCK_INTRA: |
|
501 |
3818 |
result = svq1_decode_block_intra(bitbuf, current, pitch); |
|
502 |
3818 |
break; |
|
503 |
} |
||
504 |
|||
505 |
75341 |
return result; |
|
506 |
} |
||
507 |
|||
508 |
static void svq1_parse_string(GetBitContext *bitbuf, uint8_t out[257]) |
||
509 |
{ |
||
510 |
uint8_t seed; |
||
511 |
int i; |
||
512 |
|||
513 |
out[0] = get_bits(bitbuf, 8); |
||
514 |
seed = string_table[out[0]]; |
||
515 |
|||
516 |
for (i = 1; i <= out[0]; i++) { |
||
517 |
out[i] = get_bits(bitbuf, 8) ^ seed; |
||
518 |
seed = string_table[out[i] ^ seed]; |
||
519 |
} |
||
520 |
out[i] = 0; |
||
521 |
} |
||
522 |
|||
523 |
355 |
static int svq1_decode_frame_header(AVCodecContext *avctx, AVFrame *frame) |
|
524 |
{ |
||
525 |
355 |
SVQ1Context *s = avctx->priv_data; |
|
526 |
355 |
GetBitContext *bitbuf = &s->gb; |
|
527 |
int frame_size_code; |
||
528 |
355 |
int width = s->width; |
|
529 |
355 |
int height = s->height; |
|
530 |
|||
531 |
355 |
skip_bits(bitbuf, 8); /* temporal_reference */ |
|
532 |
|||
533 |
/* frame type */ |
||
534 |
355 |
s->nonref = 0; |
|
535 |
✓✗✓✗ |
355 |
switch (get_bits(bitbuf, 2)) { |
536 |
36 |
case 0: |
|
537 |
36 |
frame->pict_type = AV_PICTURE_TYPE_I; |
|
538 |
36 |
break; |
|
539 |
case 2: |
||
540 |
s->nonref = 1; |
||
541 |
319 |
case 1: |
|
542 |
319 |
frame->pict_type = AV_PICTURE_TYPE_P; |
|
543 |
319 |
break; |
|
544 |
default: |
||
545 |
av_log(avctx, AV_LOG_ERROR, "Invalid frame type.\n"); |
||
546 |
return AVERROR_INVALIDDATA; |
||
547 |
} |
||
548 |
|||
549 |
✓✓ | 355 |
if (frame->pict_type == AV_PICTURE_TYPE_I) { |
550 |
/* unknown fields */ |
||
551 |
✓✓✗✓ |
36 |
if (s->frame_code == 0x50 || s->frame_code == 0x60) { |
552 |
1 |
int csum = get_bits(bitbuf, 16); |
|
553 |
|||
554 |
1 |
csum = av_bswap16(av_crc(av_crc_get_table(AV_CRC_16_CCITT), av_bswap16(csum), bitbuf->buffer, bitbuf->size_in_bits >> 3)); |
|
555 |
|||
556 |
ff_dlog(avctx, "%s checksum (%02x) for packet data\n", |
||
557 |
(csum == 0) ? "correct" : "incorrect", csum); |
||
558 |
} |
||
559 |
|||
560 |
✗✓ | 36 |
if ((s->frame_code ^ 0x10) >= 0x50) { |
561 |
uint8_t msg[257]; |
||
562 |
|||
563 |
svq1_parse_string(bitbuf, msg); |
||
564 |
|||
565 |
av_log(avctx, AV_LOG_INFO, |
||
566 |
"embedded message:\n%s\n", ((char *)msg) + 1); |
||
567 |
} |
||
568 |
|||
569 |
36 |
skip_bits(bitbuf, 2); |
|
570 |
36 |
skip_bits(bitbuf, 2); |
|
571 |
36 |
skip_bits1(bitbuf); |
|
572 |
|||
573 |
/* load frame size */ |
||
574 |
36 |
frame_size_code = get_bits(bitbuf, 3); |
|
575 |
|||
576 |
✓✓ | 36 |
if (frame_size_code == 7) { |
577 |
/* load width, height (12 bits each) */ |
||
578 |
6 |
width = get_bits(bitbuf, 12); |
|
579 |
6 |
height = get_bits(bitbuf, 12); |
|
580 |
|||
581 |
✓✗✗✓ |
6 |
if (!width || !height) |
582 |
return AVERROR_INVALIDDATA; |
||
583 |
} else { |
||
584 |
/* get width, height from table */ |
||
585 |
30 |
width = ff_svq1_frame_size_table[frame_size_code][0]; |
|
586 |
30 |
height = ff_svq1_frame_size_table[frame_size_code][1]; |
|
587 |
} |
||
588 |
} |
||
589 |
|||
590 |
/* unknown fields */ |
||
591 |
✗✓ | 355 |
if (get_bits1(bitbuf)) { |
592 |
skip_bits1(bitbuf); /* use packet checksum if (1) */ |
||
593 |
skip_bits1(bitbuf); /* component checksums after image data if (1) */ |
||
594 |
|||
595 |
if (get_bits(bitbuf, 2) != 0) |
||
596 |
return AVERROR_INVALIDDATA; |
||
597 |
} |
||
598 |
|||
599 |
✓✓ | 355 |
if (get_bits1(bitbuf)) { |
600 |
155 |
skip_bits1(bitbuf); |
|
601 |
155 |
skip_bits(bitbuf, 4); |
|
602 |
155 |
skip_bits1(bitbuf); |
|
603 |
155 |
skip_bits(bitbuf, 2); |
|
604 |
|||
605 |
✗✓ | 155 |
if (skip_1stop_8data_bits(bitbuf) < 0) |
606 |
return AVERROR_INVALIDDATA; |
||
607 |
} |
||
608 |
✗✓ | 355 |
if (get_bits_left(bitbuf) <= 0) |
609 |
return AVERROR_INVALIDDATA; |
||
610 |
|||
611 |
355 |
s->width = width; |
|
612 |
355 |
s->height = height; |
|
613 |
355 |
return 0; |
|
614 |
} |
||
615 |
|||
616 |
355 |
static int svq1_decode_frame(AVCodecContext *avctx, void *data, |
|
617 |
int *got_frame, AVPacket *avpkt) |
||
618 |
{ |
||
619 |
355 |
const uint8_t *buf = avpkt->data; |
|
620 |
355 |
int buf_size = avpkt->size; |
|
621 |
355 |
SVQ1Context *s = avctx->priv_data; |
|
622 |
355 |
AVFrame *cur = data; |
|
623 |
uint8_t *current; |
||
624 |
int result, i, x, y, width, height; |
||
625 |
svq1_pmv *pmv; |
||
626 |
int ret; |
||
627 |
|||
628 |
/* initialize bit buffer */ |
||
629 |
355 |
ret = init_get_bits8(&s->gb, buf, buf_size); |
|
630 |
✗✓ | 355 |
if (ret < 0) |
631 |
return ret; |
||
632 |
|||
633 |
/* decode frame header */ |
||
634 |
355 |
s->frame_code = get_bits(&s->gb, 22); |
|
635 |
|||
636 |
✓✗✗✓ |
355 |
if ((s->frame_code & ~0x70) || !(s->frame_code & 0x60)) |
637 |
return AVERROR_INVALIDDATA; |
||
638 |
|||
639 |
/* swap some header bytes (why?) */ |
||
640 |
✓✓ | 355 |
if (s->frame_code != 0x20) { |
641 |
uint32_t *src; |
||
642 |
|||
643 |
✗✓ | 4 |
if (buf_size < 9 * 4) { |
644 |
av_log(avctx, AV_LOG_ERROR, "Input packet too small\n"); |
||
645 |
return AVERROR_INVALIDDATA; |
||
646 |
} |
||
647 |
|||
648 |
4 |
av_fast_padded_malloc(&s->pkt_swapped, |
|
649 |
4 |
&s->pkt_swapped_allocated, |
|
650 |
buf_size); |
||
651 |
✗✓ | 4 |
if (!s->pkt_swapped) |
652 |
return AVERROR(ENOMEM); |
||
653 |
|||
654 |
4 |
memcpy(s->pkt_swapped, buf, buf_size); |
|
655 |
4 |
buf = s->pkt_swapped; |
|
656 |
4 |
init_get_bits(&s->gb, buf, buf_size * 8); |
|
657 |
4 |
skip_bits(&s->gb, 22); |
|
658 |
|||
659 |
4 |
src = (uint32_t *)(s->pkt_swapped + 4); |
|
660 |
|||
661 |
✓✓ | 20 |
for (i = 0; i < 4; i++) |
662 |
16 |
src[i] = ((src[i] << 16) | (src[i] >> 16)) ^ src[7 - i]; |
|
663 |
} |
||
664 |
|||
665 |
355 |
result = svq1_decode_frame_header(avctx, cur); |
|
666 |
✗✓ | 355 |
if (result != 0) { |
667 |
ff_dlog(avctx, "Error in svq1_decode_frame_header %i\n", result); |
||
668 |
return result; |
||
669 |
} |
||
670 |
|||
671 |
355 |
result = ff_set_dimensions(avctx, s->width, s->height); |
|
672 |
✗✓ | 355 |
if (result < 0) |
673 |
return result; |
||
674 |
|||
675 |
✗✓✗✗ |
355 |
if ((avctx->skip_frame >= AVDISCARD_NONREF && s->nonref) || |
676 |
✗✓ | 355 |
(avctx->skip_frame >= AVDISCARD_NONKEY && |
677 |
cur->pict_type != AV_PICTURE_TYPE_I) || |
||
678 |
✗✓ | 355 |
avctx->skip_frame >= AVDISCARD_ALL) |
679 |
return buf_size; |
||
680 |
|||
681 |
355 |
result = ff_get_buffer(avctx, cur, s->nonref ? 0 : AV_GET_BUFFER_FLAG_REF); |
|
682 |
✗✓ | 355 |
if (result < 0) |
683 |
return result; |
||
684 |
|||
685 |
355 |
pmv = av_malloc_array(FFALIGN(s->width, 16) / 8 + 3, sizeof(*pmv)); |
|
686 |
✗✓ | 355 |
if (!pmv) |
687 |
return AVERROR(ENOMEM); |
||
688 |
|||
689 |
/* decode y, u and v components */ |
||
690 |
✓✓ | 1420 |
for (i = 0; i < 3; i++) { |
691 |
1065 |
int linesize = cur->linesize[i]; |
|
692 |
✓✓ | 1065 |
if (i == 0) { |
693 |
355 |
width = FFALIGN(s->width, 16); |
|
694 |
355 |
height = FFALIGN(s->height, 16); |
|
695 |
} else { |
||
696 |
✗✓ | 710 |
if (avctx->flags & AV_CODEC_FLAG_GRAY) |
697 |
break; |
||
698 |
710 |
width = FFALIGN(s->width / 4, 16); |
|
699 |
710 |
height = FFALIGN(s->height / 4, 16); |
|
700 |
} |
||
701 |
|||
702 |
1065 |
current = cur->data[i]; |
|
703 |
|||
704 |
✓✓ | 1065 |
if (cur->pict_type == AV_PICTURE_TYPE_I) { |
705 |
/* keyframe */ |
||
706 |
✓✓ | 751 |
for (y = 0; y < height; y += 16) { |
707 |
✓✓ | 9176 |
for (x = 0; x < width; x += 16) { |
708 |
8533 |
result = svq1_decode_block_intra(&s->gb, ¤t[x], |
|
709 |
linesize); |
||
710 |
✗✓ | 8533 |
if (result) { |
711 |
av_log(avctx, AV_LOG_ERROR, |
||
712 |
"Error in svq1_decode_block %i (keyframe)\n", |
||
713 |
result); |
||
714 |
goto err; |
||
715 |
} |
||
716 |
} |
||
717 |
643 |
current += 16 * linesize; |
|
718 |
} |
||
719 |
} else { |
||
720 |
/* delta frame */ |
||
721 |
957 |
uint8_t *previous = s->prev->data[i]; |
|
722 |
✓✗ | 957 |
if (!previous || |
723 |
✓✗✗✓ |
957 |
s->prev->width != s->width || s->prev->height != s->height) { |
724 |
av_log(avctx, AV_LOG_ERROR, "Missing reference frame.\n"); |
||
725 |
result = AVERROR_INVALIDDATA; |
||
726 |
goto err; |
||
727 |
} |
||
728 |
|||
729 |
957 |
memset(pmv, 0, ((width / 8) + 3) * sizeof(svq1_pmv)); |
|
730 |
|||
731 |
✓✓ | 6648 |
for (y = 0; y < height; y += 16) { |
732 |
✓✓ | 81032 |
for (x = 0; x < width; x += 16) { |
733 |
75341 |
result = svq1_decode_delta_block(avctx, &s->hdsp, |
|
734 |
&s->gb, ¤t[x], |
||
735 |
previous, linesize, |
||
736 |
pmv, x, y, width, height); |
||
737 |
✗✓ | 75341 |
if (result != 0) { |
738 |
ff_dlog(avctx, |
||
739 |
"Error in svq1_decode_delta_block %i\n", |
||
740 |
result); |
||
741 |
goto err; |
||
742 |
} |
||
743 |
} |
||
744 |
|||
745 |
5691 |
pmv[0].x = |
|
746 |
5691 |
pmv[0].y = 0; |
|
747 |
|||
748 |
5691 |
current += 16 * linesize; |
|
749 |
} |
||
750 |
} |
||
751 |
} |
||
752 |
|||
753 |
✓✗ | 355 |
if (!s->nonref) { |
754 |
355 |
av_frame_unref(s->prev); |
|
755 |
355 |
result = av_frame_ref(s->prev, cur); |
|
756 |
✗✓ | 355 |
if (result < 0) |
757 |
goto err; |
||
758 |
} |
||
759 |
|||
760 |
355 |
*got_frame = 1; |
|
761 |
355 |
result = buf_size; |
|
762 |
|||
763 |
355 |
err: |
|
764 |
355 |
av_free(pmv); |
|
765 |
355 |
return result; |
|
766 |
} |
||
767 |
|||
768 |
7 |
static av_cold void svq1_static_init(void) |
|
769 |
{ |
||
770 |
7 |
INIT_VLC_STATIC(&svq1_block_type, SVQ1_BLOCK_TYPE_VLC_BITS, 4, |
|
771 |
&ff_svq1_block_type_vlc[0][1], 2, 1, |
||
772 |
&ff_svq1_block_type_vlc[0][0], 2, 1, 8); |
||
773 |
|||
774 |
7 |
INIT_VLC_STATIC(&svq1_motion_component, 7, 33, |
|
775 |
&ff_mvtab[0][1], 2, 1, |
||
776 |
&ff_mvtab[0][0], 2, 1, 176); |
||
777 |
|||
778 |
✓✓ | 49 |
for (int i = 0, offset = 0; i < 6; i++) { |
779 |
static const uint8_t sizes[2][6] = { { 14, 10, 14, 18, 16, 18 }, |
||
780 |
{ 10, 10, 14, 14, 14, 16 } }; |
||
781 |
static VLC_TYPE table[168][2]; |
||
782 |
42 |
svq1_intra_multistage[i].table = &table[offset]; |
|
783 |
42 |
svq1_intra_multistage[i].table_allocated = sizes[0][i]; |
|
784 |
42 |
offset += sizes[0][i]; |
|
785 |
42 |
init_vlc(&svq1_intra_multistage[i], 3, 8, |
|
786 |
&ff_svq1_intra_multistage_vlc[i][0][1], 2, 1, |
||
787 |
&ff_svq1_intra_multistage_vlc[i][0][0], 2, 1, |
||
788 |
INIT_VLC_USE_NEW_STATIC); |
||
789 |
42 |
svq1_inter_multistage[i].table = &table[offset]; |
|
790 |
42 |
svq1_inter_multistage[i].table_allocated = sizes[1][i]; |
|
791 |
42 |
offset += sizes[1][i]; |
|
792 |
42 |
init_vlc(&svq1_inter_multistage[i], 3, 8, |
|
793 |
&ff_svq1_inter_multistage_vlc[i][0][1], 2, 1, |
||
794 |
&ff_svq1_inter_multistage_vlc[i][0][0], 2, 1, |
||
795 |
INIT_VLC_USE_NEW_STATIC); |
||
796 |
} |
||
797 |
|||
798 |
7 |
INIT_VLC_STATIC(&svq1_intra_mean, 8, 256, |
|
799 |
&ff_svq1_intra_mean_vlc[0][1], 4, 2, |
||
800 |
&ff_svq1_intra_mean_vlc[0][0], 4, 2, 632); |
||
801 |
|||
802 |
7 |
INIT_VLC_STATIC(&svq1_inter_mean, 9, 512, |
|
803 |
&ff_svq1_inter_mean_vlc[0][1], 4, 2, |
||
804 |
&ff_svq1_inter_mean_vlc[0][0], 4, 2, 1434); |
||
805 |
7 |
} |
|
806 |
|||
807 |
13 |
static av_cold int svq1_decode_init(AVCodecContext *avctx) |
|
808 |
{ |
||
809 |
static AVOnce init_static_once = AV_ONCE_INIT; |
||
810 |
13 |
SVQ1Context *s = avctx->priv_data; |
|
811 |
|||
812 |
13 |
s->prev = av_frame_alloc(); |
|
813 |
✗✓ | 13 |
if (!s->prev) |
814 |
return AVERROR(ENOMEM); |
||
815 |
|||
816 |
13 |
s->width = avctx->width + 3 & ~3; |
|
817 |
13 |
s->height = avctx->height + 3 & ~3; |
|
818 |
13 |
avctx->pix_fmt = AV_PIX_FMT_YUV410P; |
|
819 |
|||
820 |
13 |
ff_hpeldsp_init(&s->hdsp, avctx->flags); |
|
821 |
|||
822 |
13 |
ff_thread_once(&init_static_once, svq1_static_init); |
|
823 |
|||
824 |
13 |
return 0; |
|
825 |
} |
||
826 |
|||
827 |
13 |
static av_cold int svq1_decode_end(AVCodecContext *avctx) |
|
828 |
{ |
||
829 |
13 |
SVQ1Context *s = avctx->priv_data; |
|
830 |
|||
831 |
13 |
av_frame_free(&s->prev); |
|
832 |
13 |
av_freep(&s->pkt_swapped); |
|
833 |
13 |
s->pkt_swapped_allocated = 0; |
|
834 |
|||
835 |
13 |
return 0; |
|
836 |
} |
||
837 |
|||
838 |
static void svq1_flush(AVCodecContext *avctx) |
||
839 |
{ |
||
840 |
SVQ1Context *s = avctx->priv_data; |
||
841 |
|||
842 |
av_frame_unref(s->prev); |
||
843 |
} |
||
844 |
|||
845 |
AVCodec ff_svq1_decoder = { |
||
846 |
.name = "svq1", |
||
847 |
.long_name = NULL_IF_CONFIG_SMALL("Sorenson Vector Quantizer 1 / Sorenson Video 1 / SVQ1"), |
||
848 |
.type = AVMEDIA_TYPE_VIDEO, |
||
849 |
.id = AV_CODEC_ID_SVQ1, |
||
850 |
.priv_data_size = sizeof(SVQ1Context), |
||
851 |
.init = svq1_decode_init, |
||
852 |
.close = svq1_decode_end, |
||
853 |
.decode = svq1_decode_frame, |
||
854 |
.capabilities = AV_CODEC_CAP_DR1, |
||
855 |
.flush = svq1_flush, |
||
856 |
.pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV410P, |
||
857 |
AV_PIX_FMT_NONE }, |
||
858 |
.caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, |
||
859 |
}; |
Generated by: GCOVR (Version 4.2) |