Mercurial > libavcodec.hg
annotate vp56.c @ 8228:416ffc3907bf libavcodec
Remove ineffectual hack that attempts to build ppc/check_altivec.o without
AltiVec flags. The flags are set by configure and used to compile all files
anyway. Setting extra AltiVec options here just duplicates them for the files
for which they are set.
author | diego |
---|---|
date | Sun, 30 Nov 2008 16:57:28 +0000 |
parents | 6c7e7fdedfd3 |
children | 800444234375 |
rev | line source |
---|---|
3695 | 1 /** |
2 * @file vp56.c | |
3 * VP5 and VP6 compatible video decoder (common features) | |
4 * | |
5 * Copyright (C) 2006 Aurelien Jacobs <aurel@gnuage.org> | |
6 * | |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3715
diff
changeset
|
7 * This file is part of FFmpeg. |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3715
diff
changeset
|
8 * |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3715
diff
changeset
|
9 * FFmpeg is free software; you can redistribute it and/or |
3695 | 10 * modify it under the terms of the GNU Lesser General Public |
11 * License as published by the Free Software Foundation; either | |
12 * version 2.1 of the License, or (at your option) any later version. | |
13 * | |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3715
diff
changeset
|
14 * FFmpeg is distributed in the hope that it will be useful, |
3695 | 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
17 * Lesser General Public License for more details. | |
18 * | |
19 * You should have received a copy of the GNU Lesser General Public | |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3715
diff
changeset
|
20 * License along with FFmpeg; if not, write to the Free Software |
5215 | 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
3695 | 22 */ |
23 | |
24 #include "avcodec.h" | |
5714
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
25 #include "bytestream.h" |
3695 | 26 |
27 #include "vp56.h" | |
28 #include "vp56data.h" | |
29 | |
30 | |
31 void vp56_init_dequant(vp56_context_t *s, int quantizer) | |
32 { | |
33 s->quantizer = quantizer; | |
34 s->dequant_dc = vp56_dc_dequant[quantizer] << 2; | |
35 s->dequant_ac = vp56_ac_dequant[quantizer] << 2; | |
36 } | |
37 | |
38 static int vp56_get_vectors_predictors(vp56_context_t *s, int row, int col, | |
39 vp56_frame_t ref_frame) | |
40 { | |
41 int nb_pred = 0; | |
3697 | 42 vp56_mv_t vect[2] = {{0,0}, {0,0}}; |
3695 | 43 int pos, offset; |
44 vp56_mv_t mvp; | |
45 | |
46 for (pos=0; pos<12; pos++) { | |
47 mvp.x = col + vp56_candidate_predictor_pos[pos][0]; | |
48 mvp.y = row + vp56_candidate_predictor_pos[pos][1]; | |
49 if (mvp.x < 0 || mvp.x >= s->mb_width || | |
50 mvp.y < 0 || mvp.y >= s->mb_height) | |
51 continue; | |
52 offset = mvp.x + s->mb_width*mvp.y; | |
53 | |
54 if (vp56_reference_frame[s->macroblocks[offset].type] != ref_frame) | |
55 continue; | |
3697 | 56 if ((s->macroblocks[offset].mv.x == vect[0].x && |
57 s->macroblocks[offset].mv.y == vect[0].y) || | |
3695 | 58 (s->macroblocks[offset].mv.x == 0 && |
59 s->macroblocks[offset].mv.y == 0)) | |
60 continue; | |
61 | |
3697 | 62 vect[nb_pred++] = s->macroblocks[offset].mv; |
3695 | 63 if (nb_pred > 1) { |
64 nb_pred = -1; | |
65 break; | |
66 } | |
67 s->vector_candidate_pos = pos; | |
68 } | |
69 | |
3697 | 70 s->vector_candidate[0] = vect[0]; |
71 s->vector_candidate[1] = vect[1]; | |
3695 | 72 |
73 return nb_pred+1; | |
74 } | |
75 | |
76 static void vp56_parse_mb_type_models(vp56_context_t *s) | |
77 { | |
78 vp56_range_coder_t *c = &s->c; | |
5711 | 79 vp56_model_t *model = s->modelp; |
3695 | 80 int i, ctx, type; |
81 | |
82 for (ctx=0; ctx<3; ctx++) { | |
83 if (vp56_rac_get_prob(c, 174)) { | |
84 int idx = vp56_rac_gets(c, 4); | |
5711 | 85 memcpy(model->mb_types_stats[ctx], |
86 vp56_pre_def_mb_type_stats[idx][ctx], | |
87 sizeof(model->mb_types_stats[ctx])); | |
3695 | 88 } |
89 if (vp56_rac_get_prob(c, 254)) { | |
90 for (type=0; type<10; type++) { | |
91 for(i=0; i<2; i++) { | |
92 if (vp56_rac_get_prob(c, 205)) { | |
93 int delta, sign = vp56_rac_get(c); | |
94 | |
95 delta = vp56_rac_get_tree(c, vp56_pmbtm_tree, | |
96 vp56_mb_type_model_model); | |
97 if (!delta) | |
98 delta = 4 * vp56_rac_gets(c, 7); | |
5711 | 99 model->mb_types_stats[ctx][type][i] += (delta ^ -sign) + sign; |
3695 | 100 } |
101 } | |
102 } | |
103 } | |
104 } | |
105 | |
106 /* compute MB type probability tables based on previous MB type */ | |
107 for (ctx=0; ctx<3; ctx++) { | |
108 int p[10]; | |
109 | |
110 for (type=0; type<10; type++) | |
5711 | 111 p[type] = 100 * model->mb_types_stats[ctx][type][1]; |
3695 | 112 |
113 for (type=0; type<10; type++) { | |
114 int p02, p34, p0234, p17, p56, p89, p5689, p156789; | |
115 | |
116 /* conservative MB type probability */ | |
5711 | 117 model->mb_type[ctx][type][0] = 255 - (255 * model->mb_types_stats[ctx][type][0]) / (1 + model->mb_types_stats[ctx][type][0] + model->mb_types_stats[ctx][type][1]); |
3695 | 118 |
119 p[type] = 0; /* same MB type => weight is null */ | |
120 | |
121 /* binary tree parsing probabilities */ | |
122 p02 = p[0] + p[2]; | |
123 p34 = p[3] + p[4]; | |
124 p0234 = p02 + p34; | |
125 p17 = p[1] + p[7]; | |
126 p56 = p[5] + p[6]; | |
127 p89 = p[8] + p[9]; | |
128 p5689 = p56 + p89; | |
129 p156789 = p17 + p5689; | |
130 | |
5711 | 131 model->mb_type[ctx][type][1] = 1 + 255 * p0234/(1+p0234+p156789); |
132 model->mb_type[ctx][type][2] = 1 + 255 * p02 / (1+p0234); | |
133 model->mb_type[ctx][type][3] = 1 + 255 * p17 / (1+p156789); | |
134 model->mb_type[ctx][type][4] = 1 + 255 * p[0] / (1+p02); | |
135 model->mb_type[ctx][type][5] = 1 + 255 * p[3] / (1+p34); | |
136 model->mb_type[ctx][type][6] = 1 + 255 * p[1] / (1+p17); | |
137 model->mb_type[ctx][type][7] = 1 + 255 * p56 / (1+p5689); | |
138 model->mb_type[ctx][type][8] = 1 + 255 * p[5] / (1+p56); | |
139 model->mb_type[ctx][type][9] = 1 + 255 * p[8] / (1+p89); | |
3695 | 140 |
141 /* restore initial value */ | |
5711 | 142 p[type] = 100 * model->mb_types_stats[ctx][type][1]; |
3695 | 143 } |
144 } | |
145 } | |
146 | |
147 static vp56_mb_t vp56_parse_mb_type(vp56_context_t *s, | |
148 vp56_mb_t prev_type, int ctx) | |
149 { | |
5711 | 150 uint8_t *mb_type_model = s->modelp->mb_type[ctx][prev_type]; |
3695 | 151 vp56_range_coder_t *c = &s->c; |
152 | |
153 if (vp56_rac_get_prob(c, mb_type_model[0])) | |
154 return prev_type; | |
155 else | |
156 return vp56_rac_get_tree(c, vp56_pmbt_tree, mb_type_model); | |
157 } | |
158 | |
159 static void vp56_decode_4mv(vp56_context_t *s, int row, int col) | |
160 { | |
161 vp56_mv_t mv = {0,0}; | |
162 int type[4]; | |
163 int b; | |
164 | |
165 /* parse each block type */ | |
166 for (b=0; b<4; b++) { | |
167 type[b] = vp56_rac_gets(&s->c, 2); | |
168 if (type[b]) | |
169 type[b]++; /* only returns 0, 2, 3 or 4 (all INTER_PF) */ | |
170 } | |
171 | |
172 /* get vectors */ | |
173 for (b=0; b<4; b++) { | |
174 switch (type[b]) { | |
175 case VP56_MB_INTER_NOVEC_PF: | |
176 s->mv[b] = (vp56_mv_t) {0,0}; | |
177 break; | |
178 case VP56_MB_INTER_DELTA_PF: | |
179 s->parse_vector_adjustment(s, &s->mv[b]); | |
180 break; | |
181 case VP56_MB_INTER_V1_PF: | |
182 s->mv[b] = s->vector_candidate[0]; | |
183 break; | |
184 case VP56_MB_INTER_V2_PF: | |
185 s->mv[b] = s->vector_candidate[1]; | |
186 break; | |
187 } | |
188 mv.x += s->mv[b].x; | |
189 mv.y += s->mv[b].y; | |
190 } | |
191 | |
192 /* this is the one selected for the whole MB for prediction */ | |
193 s->macroblocks[row * s->mb_width + col].mv = s->mv[3]; | |
194 | |
195 /* chroma vectors are average luma vectors */ | |
196 if (s->avctx->codec->id == CODEC_ID_VP5) { | |
197 s->mv[4].x = s->mv[5].x = RSHIFT(mv.x,2); | |
198 s->mv[4].y = s->mv[5].y = RSHIFT(mv.y,2); | |
199 } else { | |
200 s->mv[4] = s->mv[5] = (vp56_mv_t) {mv.x/4, mv.y/4}; | |
201 } | |
202 } | |
203 | |
204 static vp56_mb_t vp56_decode_mv(vp56_context_t *s, int row, int col) | |
205 { | |
3697 | 206 vp56_mv_t *mv, vect = {0,0}; |
3695 | 207 int ctx, b; |
208 | |
209 ctx = vp56_get_vectors_predictors(s, row, col, VP56_FRAME_PREVIOUS); | |
210 s->mb_type = vp56_parse_mb_type(s, s->mb_type, ctx); | |
211 s->macroblocks[row * s->mb_width + col].type = s->mb_type; | |
212 | |
213 switch (s->mb_type) { | |
214 case VP56_MB_INTER_V1_PF: | |
215 mv = &s->vector_candidate[0]; | |
216 break; | |
217 | |
218 case VP56_MB_INTER_V2_PF: | |
219 mv = &s->vector_candidate[1]; | |
220 break; | |
221 | |
222 case VP56_MB_INTER_V1_GF: | |
223 vp56_get_vectors_predictors(s, row, col, VP56_FRAME_GOLDEN); | |
224 mv = &s->vector_candidate[0]; | |
225 break; | |
226 | |
227 case VP56_MB_INTER_V2_GF: | |
228 vp56_get_vectors_predictors(s, row, col, VP56_FRAME_GOLDEN); | |
229 mv = &s->vector_candidate[1]; | |
230 break; | |
231 | |
232 case VP56_MB_INTER_DELTA_PF: | |
3697 | 233 s->parse_vector_adjustment(s, &vect); |
234 mv = &vect; | |
3695 | 235 break; |
236 | |
237 case VP56_MB_INTER_DELTA_GF: | |
238 vp56_get_vectors_predictors(s, row, col, VP56_FRAME_GOLDEN); | |
3697 | 239 s->parse_vector_adjustment(s, &vect); |
240 mv = &vect; | |
3695 | 241 break; |
242 | |
243 case VP56_MB_INTER_4V: | |
244 vp56_decode_4mv(s, row, col); | |
245 return s->mb_type; | |
246 | |
247 default: | |
3697 | 248 mv = &vect; |
3695 | 249 break; |
250 } | |
251 | |
252 s->macroblocks[row*s->mb_width + col].mv = *mv; | |
253 | |
254 /* same vector for all blocks */ | |
255 for (b=0; b<6; b++) | |
256 s->mv[b] = *mv; | |
257 | |
258 return s->mb_type; | |
259 } | |
260 | |
261 static void vp56_add_predictors_dc(vp56_context_t *s, vp56_frame_t ref_frame) | |
262 { | |
263 int idx = s->scantable.permutated[0]; | |
5718
bb4293d858da
rename one variable to be consistent with the rest of the file
aurel
parents:
5717
diff
changeset
|
264 int b; |
3695 | 265 |
5718
bb4293d858da
rename one variable to be consistent with the rest of the file
aurel
parents:
5717
diff
changeset
|
266 for (b=0; b<6; b++) { |
bb4293d858da
rename one variable to be consistent with the rest of the file
aurel
parents:
5717
diff
changeset
|
267 vp56_ref_dc_t *ab = &s->above_blocks[s->above_block_idx[b]]; |
bb4293d858da
rename one variable to be consistent with the rest of the file
aurel
parents:
5717
diff
changeset
|
268 vp56_ref_dc_t *lb = &s->left_block[vp56_b6to4[b]]; |
3695 | 269 int count = 0; |
270 int dc = 0; | |
5719 | 271 int i; |
3695 | 272 |
273 if (ref_frame == lb->ref_frame) { | |
274 dc += lb->dc_coeff; | |
275 count++; | |
276 } | |
277 if (ref_frame == ab->ref_frame) { | |
278 dc += ab->dc_coeff; | |
279 count++; | |
280 } | |
5719 | 281 if (s->avctx->codec->id == CODEC_ID_VP5) |
282 for (i=0; i<2; i++) | |
283 if (count < 2 && ref_frame == ab[-1+2*i].ref_frame) { | |
284 dc += ab[-1+2*i].dc_coeff; | |
285 count++; | |
286 } | |
3695 | 287 if (count == 0) |
5718
bb4293d858da
rename one variable to be consistent with the rest of the file
aurel
parents:
5717
diff
changeset
|
288 dc = s->prev_dc[vp56_b2p[b]][ref_frame]; |
3695 | 289 else if (count == 2) |
290 dc /= 2; | |
291 | |
5718
bb4293d858da
rename one variable to be consistent with the rest of the file
aurel
parents:
5717
diff
changeset
|
292 s->block_coeff[b][idx] += dc; |
bb4293d858da
rename one variable to be consistent with the rest of the file
aurel
parents:
5717
diff
changeset
|
293 s->prev_dc[vp56_b2p[b]][ref_frame] = s->block_coeff[b][idx]; |
bb4293d858da
rename one variable to be consistent with the rest of the file
aurel
parents:
5717
diff
changeset
|
294 ab->dc_coeff = s->block_coeff[b][idx]; |
3695 | 295 ab->ref_frame = ref_frame; |
5718
bb4293d858da
rename one variable to be consistent with the rest of the file
aurel
parents:
5717
diff
changeset
|
296 lb->dc_coeff = s->block_coeff[b][idx]; |
3695 | 297 lb->ref_frame = ref_frame; |
5718
bb4293d858da
rename one variable to be consistent with the rest of the file
aurel
parents:
5717
diff
changeset
|
298 s->block_coeff[b][idx] *= s->dequant_dc; |
3695 | 299 } |
300 } | |
301 | |
302 static void vp56_edge_filter(vp56_context_t *s, uint8_t *yuv, | |
303 int pix_inc, int line_inc, int t) | |
304 { | |
305 int pix2_inc = 2 * pix_inc; | |
306 int i, v; | |
307 | |
308 for (i=0; i<12; i++) { | |
309 v = (yuv[-pix2_inc] + 3*(yuv[0]-yuv[-pix_inc]) - yuv[pix_inc] + 4) >>3; | |
310 v = s->adjust(v, t); | |
4594 | 311 yuv[-pix_inc] = av_clip_uint8(yuv[-pix_inc] + v); |
312 yuv[0] = av_clip_uint8(yuv[0] - v); | |
3695 | 313 yuv += line_inc; |
314 } | |
315 } | |
316 | |
317 static void vp56_deblock_filter(vp56_context_t *s, uint8_t *yuv, | |
318 int stride, int dx, int dy) | |
319 { | |
320 int t = vp56_filter_threshold[s->quantizer]; | |
321 if (dx) vp56_edge_filter(s, yuv + 10-dx , 1, stride, t); | |
322 if (dy) vp56_edge_filter(s, yuv + stride*(10-dy), stride, 1, t); | |
323 } | |
324 | |
5708 | 325 static void vp56_mc(vp56_context_t *s, int b, int plane, uint8_t *src, |
3695 | 326 int stride, int x, int y) |
327 { | |
4595 | 328 uint8_t *dst=s->framep[VP56_FRAME_CURRENT]->data[plane]+s->block_offset[b]; |
3695 | 329 uint8_t *src_block; |
330 int src_offset; | |
331 int overlap_offset = 0; | |
332 int mask = s->vp56_coord_div[b] - 1; | |
333 int deblock_filtering = s->deblock_filtering; | |
334 int dx; | |
335 int dy; | |
336 | |
337 if (s->avctx->skip_loop_filter >= AVDISCARD_ALL || | |
338 (s->avctx->skip_loop_filter >= AVDISCARD_NONKEY | |
4595 | 339 && !s->framep[VP56_FRAME_CURRENT]->key_frame)) |
3695 | 340 deblock_filtering = 0; |
341 | |
342 dx = s->mv[b].x / s->vp56_coord_div[b]; | |
343 dy = s->mv[b].y / s->vp56_coord_div[b]; | |
344 | |
345 if (b >= 4) { | |
346 x /= 2; | |
347 y /= 2; | |
348 } | |
349 x += dx - 2; | |
350 y += dy - 2; | |
351 | |
352 if (x<0 || x+12>=s->plane_width[plane] || | |
353 y<0 || y+12>=s->plane_height[plane]) { | |
354 ff_emulated_edge_mc(s->edge_emu_buffer, | |
355 src + s->block_offset[b] + (dy-2)*stride + (dx-2), | |
356 stride, 12, 12, x, y, | |
357 s->plane_width[plane], | |
358 s->plane_height[plane]); | |
359 src_block = s->edge_emu_buffer; | |
360 src_offset = 2 + 2*stride; | |
361 } else if (deblock_filtering) { | |
3715
cdaee53c5da1
replaces back some C code by dsp.put_pixels_tab[0][0] (revert r6231)
aurel
parents:
3706
diff
changeset
|
362 /* only need a 12x12 block, but there is no such dsp function, */ |
cdaee53c5da1
replaces back some C code by dsp.put_pixels_tab[0][0] (revert r6231)
aurel
parents:
3706
diff
changeset
|
363 /* so copy a 16x12 block */ |
cdaee53c5da1
replaces back some C code by dsp.put_pixels_tab[0][0] (revert r6231)
aurel
parents:
3706
diff
changeset
|
364 s->dsp.put_pixels_tab[0][0](s->edge_emu_buffer, |
cdaee53c5da1
replaces back some C code by dsp.put_pixels_tab[0][0] (revert r6231)
aurel
parents:
3706
diff
changeset
|
365 src + s->block_offset[b] + (dy-2)*stride + (dx-2), |
cdaee53c5da1
replaces back some C code by dsp.put_pixels_tab[0][0] (revert r6231)
aurel
parents:
3706
diff
changeset
|
366 stride, 12); |
3695 | 367 src_block = s->edge_emu_buffer; |
368 src_offset = 2 + 2*stride; | |
369 } else { | |
370 src_block = src; | |
371 src_offset = s->block_offset[b] + dy*stride + dx; | |
372 } | |
373 | |
374 if (deblock_filtering) | |
375 vp56_deblock_filter(s, src_block, stride, dx&7, dy&7); | |
376 | |
377 if (s->mv[b].x & mask) | |
378 overlap_offset += (s->mv[b].x > 0) ? 1 : -1; | |
379 if (s->mv[b].y & mask) | |
380 overlap_offset += (s->mv[b].y > 0) ? stride : -stride; | |
381 | |
382 if (overlap_offset) { | |
383 if (s->filter) | |
384 s->filter(s, dst, src_block, src_offset, src_offset+overlap_offset, | |
385 stride, s->mv[b], mask, s->filter_selection, b<4); | |
386 else | |
387 s->dsp.put_no_rnd_pixels_l2[1](dst, src_block+src_offset, | |
388 src_block+src_offset+overlap_offset, | |
389 stride, 8); | |
390 } else { | |
391 s->dsp.put_pixels_tab[1][0](dst, src_block+src_offset, stride, 8); | |
392 } | |
393 } | |
394 | |
5714
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
395 static void vp56_decode_mb(vp56_context_t *s, int row, int col, int is_alpha) |
3695 | 396 { |
397 AVFrame *frame_current, *frame_ref; | |
398 vp56_mb_t mb_type; | |
399 vp56_frame_t ref_frame; | |
5717 | 400 int b, ab, b_max, plane, off; |
3695 | 401 |
4595 | 402 if (s->framep[VP56_FRAME_CURRENT]->key_frame) |
3695 | 403 mb_type = VP56_MB_INTRA; |
404 else | |
405 mb_type = vp56_decode_mv(s, row, col); | |
406 ref_frame = vp56_reference_frame[mb_type]; | |
407 | |
408 memset(s->block_coeff, 0, sizeof(s->block_coeff)); | |
409 | |
410 s->parse_coeff(s); | |
411 | |
412 vp56_add_predictors_dc(s, ref_frame); | |
413 | |
4595 | 414 frame_current = s->framep[VP56_FRAME_CURRENT]; |
415 frame_ref = s->framep[ref_frame]; | |
3695 | 416 |
5714
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
417 ab = 6*is_alpha; |
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
418 b_max = 6 - 2*is_alpha; |
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
419 |
3695 | 420 switch (mb_type) { |
421 case VP56_MB_INTRA: | |
5714
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
422 for (b=0; b<b_max; b++) { |
5717 | 423 plane = vp56_b2p[b+ab]; |
424 s->dsp.idct_put(frame_current->data[plane] + s->block_offset[b], | |
425 s->stride[plane], s->block_coeff[b]); | |
3695 | 426 } |
427 break; | |
428 | |
429 case VP56_MB_INTER_NOVEC_PF: | |
430 case VP56_MB_INTER_NOVEC_GF: | |
5714
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
431 for (b=0; b<b_max; b++) { |
5717 | 432 plane = vp56_b2p[b+ab]; |
3695 | 433 off = s->block_offset[b]; |
5717 | 434 s->dsp.put_pixels_tab[1][0](frame_current->data[plane] + off, |
435 frame_ref->data[plane] + off, | |
436 s->stride[plane], 8); | |
437 s->dsp.idct_add(frame_current->data[plane] + off, | |
438 s->stride[plane], s->block_coeff[b]); | |
3695 | 439 } |
440 break; | |
441 | |
442 case VP56_MB_INTER_DELTA_PF: | |
443 case VP56_MB_INTER_V1_PF: | |
444 case VP56_MB_INTER_V2_PF: | |
445 case VP56_MB_INTER_DELTA_GF: | |
446 case VP56_MB_INTER_4V: | |
447 case VP56_MB_INTER_V1_GF: | |
448 case VP56_MB_INTER_V2_GF: | |
5714
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
449 for (b=0; b<b_max; b++) { |
3695 | 450 int x_off = b==1 || b==3 ? 8 : 0; |
451 int y_off = b==2 || b==3 ? 8 : 0; | |
5717 | 452 plane = vp56_b2p[b+ab]; |
453 vp56_mc(s, b, plane, frame_ref->data[plane], s->stride[plane], | |
3695 | 454 16*col+x_off, 16*row+y_off); |
5717 | 455 s->dsp.idct_add(frame_current->data[plane] + s->block_offset[b], |
456 s->stride[plane], s->block_coeff[b]); | |
3695 | 457 } |
458 break; | |
459 } | |
460 } | |
461 | |
5708 | 462 static int vp56_size_changed(AVCodecContext *avctx) |
3695 | 463 { |
5708 | 464 vp56_context_t *s = avctx->priv_data; |
4595 | 465 int stride = s->framep[VP56_FRAME_CURRENT]->linesize[0]; |
3695 | 466 int i; |
467 | |
5714
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
468 s->plane_width[0] = s->plane_width[3] = avctx->coded_width; |
5708 | 469 s->plane_width[1] = s->plane_width[2] = avctx->coded_width/2; |
5714
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
470 s->plane_height[0] = s->plane_height[3] = avctx->coded_height; |
5708 | 471 s->plane_height[1] = s->plane_height[2] = avctx->coded_height/2; |
3695 | 472 |
5714
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
473 for (i=0; i<4; i++) |
4595 | 474 s->stride[i] = s->flip * s->framep[VP56_FRAME_CURRENT]->linesize[i]; |
3695 | 475 |
5708 | 476 s->mb_width = (avctx->coded_width +15) / 16; |
477 s->mb_height = (avctx->coded_height+15) / 16; | |
3695 | 478 |
479 if (s->mb_width > 1000 || s->mb_height > 1000) { | |
480 av_log(avctx, AV_LOG_ERROR, "picture too big\n"); | |
481 return -1; | |
482 } | |
483 | |
484 s->above_blocks = av_realloc(s->above_blocks, | |
485 (4*s->mb_width+6) * sizeof(*s->above_blocks)); | |
486 s->macroblocks = av_realloc(s->macroblocks, | |
487 s->mb_width*s->mb_height*sizeof(*s->macroblocks)); | |
3715
cdaee53c5da1
replaces back some C code by dsp.put_pixels_tab[0][0] (revert r6231)
aurel
parents:
3706
diff
changeset
|
488 av_free(s->edge_emu_buffer_alloc); |
cdaee53c5da1
replaces back some C code by dsp.put_pixels_tab[0][0] (revert r6231)
aurel
parents:
3706
diff
changeset
|
489 s->edge_emu_buffer_alloc = av_malloc(16*stride); |
3695 | 490 s->edge_emu_buffer = s->edge_emu_buffer_alloc; |
491 if (s->flip < 0) | |
492 s->edge_emu_buffer += 15 * stride; | |
493 | |
494 return 0; | |
495 } | |
496 | |
497 int vp56_decode_frame(AVCodecContext *avctx, void *data, int *data_size, | |
6297 | 498 const uint8_t *buf, int buf_size) |
3695 | 499 { |
500 vp56_context_t *s = avctx->priv_data; | |
4595 | 501 AVFrame *const p = s->framep[VP56_FRAME_CURRENT]; |
6756
c00f5cad61cc
ensure vp56_decode_frame always return unchanged buf_size
aurel
parents:
6517
diff
changeset
|
502 int remaining_buf_size = buf_size; |
5714
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
503 int is_alpha, alpha_offset; |
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
504 |
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
505 if (s->has_alpha) { |
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
506 alpha_offset = bytestream_get_be24(&buf); |
6756
c00f5cad61cc
ensure vp56_decode_frame always return unchanged buf_size
aurel
parents:
6517
diff
changeset
|
507 remaining_buf_size -= 3; |
5714
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
508 } |
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
509 |
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
510 for (is_alpha=0; is_alpha < 1+s->has_alpha; is_alpha++) { |
5715 | 511 int mb_row, mb_col, mb_row_flip, mb_offset = 0; |
512 int block, y, uv, stride_y, stride_uv; | |
513 int golden_frame = 0; | |
514 int res; | |
3695 | 515 |
5715 | 516 s->modelp = &s->models[is_alpha]; |
3695 | 517 |
6756
c00f5cad61cc
ensure vp56_decode_frame always return unchanged buf_size
aurel
parents:
6517
diff
changeset
|
518 res = s->parse_header(s, buf, remaining_buf_size, &golden_frame); |
5715 | 519 if (!res) |
520 return -1; | |
3695 | 521 |
5715 | 522 if (!is_alpha) { |
523 p->reference = 1; | |
524 if (avctx->get_buffer(avctx, p) < 0) { | |
525 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); | |
526 return -1; | |
3695 | 527 } |
528 | |
5715 | 529 if (res == 2) |
530 if (vp56_size_changed(avctx)) { | |
531 avctx->release_buffer(avctx, p); | |
532 return -1; | |
533 } | |
534 } | |
535 | |
536 if (p->key_frame) { | |
537 p->pict_type = FF_I_TYPE; | |
538 s->default_models_init(s); | |
539 for (block=0; block<s->mb_height*s->mb_width; block++) | |
540 s->macroblocks[block].type = VP56_MB_INTRA; | |
541 } else { | |
542 p->pict_type = FF_P_TYPE; | |
543 vp56_parse_mb_type_models(s); | |
544 s->parse_vector_models(s); | |
545 s->mb_type = VP56_MB_INTER_NOVEC_PF; | |
546 } | |
547 | |
548 s->parse_coeff_models(s); | |
549 | |
550 memset(s->prev_dc, 0, sizeof(s->prev_dc)); | |
551 s->prev_dc[1][VP56_FRAME_CURRENT] = 128; | |
552 s->prev_dc[2][VP56_FRAME_CURRENT] = 128; | |
553 | |
554 for (block=0; block < 4*s->mb_width+6; block++) { | |
6795 | 555 s->above_blocks[block].ref_frame = VP56_FRAME_NONE; |
5715 | 556 s->above_blocks[block].dc_coeff = 0; |
557 s->above_blocks[block].not_null_dc = 0; | |
558 } | |
6795 | 559 s->above_blocks[2*s->mb_width + 2].ref_frame = VP56_FRAME_CURRENT; |
560 s->above_blocks[3*s->mb_width + 4].ref_frame = VP56_FRAME_CURRENT; | |
5715 | 561 |
562 stride_y = p->linesize[0]; | |
563 stride_uv = p->linesize[1]; | |
564 | |
565 if (s->flip < 0) | |
566 mb_offset = 7; | |
567 | |
568 /* main macroblocks loop */ | |
569 for (mb_row=0; mb_row<s->mb_height; mb_row++) { | |
570 if (s->flip < 0) | |
571 mb_row_flip = s->mb_height - mb_row - 1; | |
572 else | |
573 mb_row_flip = mb_row; | |
574 | |
575 for (block=0; block<4; block++) { | |
6795 | 576 s->left_block[block].ref_frame = VP56_FRAME_NONE; |
5715 | 577 s->left_block[block].dc_coeff = 0; |
578 s->left_block[block].not_null_dc = 0; | |
579 } | |
5716 | 580 memset(s->coeff_ctx, 0, sizeof(s->coeff_ctx)); |
5715 | 581 memset(s->coeff_ctx_last, 24, sizeof(s->coeff_ctx_last)); |
582 | |
583 s->above_block_idx[0] = 1; | |
584 s->above_block_idx[1] = 2; | |
585 s->above_block_idx[2] = 1; | |
586 s->above_block_idx[3] = 2; | |
587 s->above_block_idx[4] = 2*s->mb_width + 2 + 1; | |
588 s->above_block_idx[5] = 3*s->mb_width + 4 + 1; | |
589 | |
590 s->block_offset[s->frbi] = (mb_row_flip*16 + mb_offset) * stride_y; | |
591 s->block_offset[s->srbi] = s->block_offset[s->frbi] + 8*stride_y; | |
592 s->block_offset[1] = s->block_offset[0] + 8; | |
593 s->block_offset[3] = s->block_offset[2] + 8; | |
594 s->block_offset[4] = (mb_row_flip*8 + mb_offset) * stride_uv; | |
595 s->block_offset[5] = s->block_offset[4]; | |
596 | |
597 for (mb_col=0; mb_col<s->mb_width; mb_col++) { | |
598 vp56_decode_mb(s, mb_row, mb_col, is_alpha); | |
599 | |
600 for (y=0; y<4; y++) { | |
601 s->above_block_idx[y] += 2; | |
602 s->block_offset[y] += 16; | |
603 } | |
604 | |
605 for (uv=4; uv<6; uv++) { | |
606 s->above_block_idx[uv] += 1; | |
607 s->block_offset[uv] += 8; | |
608 } | |
3695 | 609 } |
610 } | |
611 | |
5715 | 612 if (p->key_frame || golden_frame) { |
613 if (s->framep[VP56_FRAME_GOLDEN]->data[0] && | |
614 s->framep[VP56_FRAME_GOLDEN] != s->framep[VP56_FRAME_GOLDEN2]) | |
615 avctx->release_buffer(avctx, s->framep[VP56_FRAME_GOLDEN]); | |
616 s->framep[VP56_FRAME_GOLDEN] = p; | |
617 } | |
5714
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
618 |
5715 | 619 if (s->has_alpha) { |
620 FFSWAP(AVFrame *, s->framep[VP56_FRAME_GOLDEN], | |
621 s->framep[VP56_FRAME_GOLDEN2]); | |
622 buf += alpha_offset; | |
6756
c00f5cad61cc
ensure vp56_decode_frame always return unchanged buf_size
aurel
parents:
6517
diff
changeset
|
623 remaining_buf_size -= alpha_offset; |
5715 | 624 } |
5714
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
625 } |
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
626 |
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
627 if (s->framep[VP56_FRAME_PREVIOUS] == s->framep[VP56_FRAME_GOLDEN] || |
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
628 s->framep[VP56_FRAME_PREVIOUS] == s->framep[VP56_FRAME_GOLDEN2]) { |
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
629 if (s->framep[VP56_FRAME_UNUSED] != s->framep[VP56_FRAME_GOLDEN] && |
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
630 s->framep[VP56_FRAME_UNUSED] != s->framep[VP56_FRAME_GOLDEN2]) |
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
631 FFSWAP(AVFrame *, s->framep[VP56_FRAME_PREVIOUS], |
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
632 s->framep[VP56_FRAME_UNUSED]); |
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
633 else |
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
634 FFSWAP(AVFrame *, s->framep[VP56_FRAME_PREVIOUS], |
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
635 s->framep[VP56_FRAME_UNUSED2]); |
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
636 } else if (s->framep[VP56_FRAME_PREVIOUS]->data[0]) |
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
637 avctx->release_buffer(avctx, s->framep[VP56_FRAME_PREVIOUS]); |
4595 | 638 FFSWAP(AVFrame *, s->framep[VP56_FRAME_CURRENT], |
639 s->framep[VP56_FRAME_PREVIOUS]); | |
3695 | 640 |
4596 | 641 *(AVFrame*)data = *p; |
642 *data_size = sizeof(AVFrame); | |
3695 | 643 |
644 return buf_size; | |
645 } | |
646 | |
6517
48759bfbd073
Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents:
6297
diff
changeset
|
647 av_cold void vp56_init(AVCodecContext *avctx, int flip, int has_alpha) |
3695 | 648 { |
5708 | 649 vp56_context_t *s = avctx->priv_data; |
3695 | 650 int i; |
651 | |
652 s->avctx = avctx; | |
5714
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
653 avctx->pix_fmt = has_alpha ? PIX_FMT_YUVA420P : PIX_FMT_YUV420P; |
3695 | 654 |
5708 | 655 if (avctx->idct_algo == FF_IDCT_AUTO) |
656 avctx->idct_algo = FF_IDCT_VP3; | |
657 dsputil_init(&s->dsp, avctx); | |
3695 | 658 ff_init_scantable(s->dsp.idct_permutation, &s->scantable,ff_zigzag_direct); |
659 | |
5708 | 660 avcodec_set_dimensions(avctx, 0, 0); |
3695 | 661 |
5714
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
662 for (i=0; i<4; i++) |
4595 | 663 s->framep[i] = &s->frames[i]; |
664 s->framep[VP56_FRAME_UNUSED] = s->framep[VP56_FRAME_GOLDEN]; | |
5714
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
665 s->framep[VP56_FRAME_UNUSED2] = s->framep[VP56_FRAME_GOLDEN2]; |
3695 | 666 s->edge_emu_buffer_alloc = NULL; |
667 | |
668 s->above_blocks = NULL; | |
669 s->macroblocks = NULL; | |
670 s->quantizer = -1; | |
671 s->deblock_filtering = 1; | |
672 | |
673 s->filter = NULL; | |
674 | |
5714
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
675 s->has_alpha = has_alpha; |
3695 | 676 if (flip) { |
677 s->flip = -1; | |
678 s->frbi = 2; | |
679 s->srbi = 0; | |
680 } else { | |
681 s->flip = 1; | |
682 s->frbi = 0; | |
683 s->srbi = 2; | |
684 } | |
685 } | |
686 | |
6517
48759bfbd073
Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents:
6297
diff
changeset
|
687 av_cold int vp56_free(AVCodecContext *avctx) |
3695 | 688 { |
689 vp56_context_t *s = avctx->priv_data; | |
690 | |
691 av_free(s->above_blocks); | |
692 av_free(s->macroblocks); | |
693 av_free(s->edge_emu_buffer_alloc); | |
5708 | 694 if (s->framep[VP56_FRAME_GOLDEN]->data[0]) |
4595 | 695 avctx->release_buffer(avctx, s->framep[VP56_FRAME_GOLDEN]); |
5714
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
696 if (s->framep[VP56_FRAME_GOLDEN2]->data[0]) |
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
697 avctx->release_buffer(avctx, s->framep[VP56_FRAME_GOLDEN2]); |
4595 | 698 if (s->framep[VP56_FRAME_PREVIOUS]->data[0]) |
699 avctx->release_buffer(avctx, s->framep[VP56_FRAME_PREVIOUS]); | |
3695 | 700 return 0; |
701 } |