Mercurial > libavcodec.hg
annotate vp5.c @ 8130:c45366b01126 libavcodec
ARM: fix j_rev_dct_ARM
This is a bugfix for ARMv4 assembly implementation of 'j_rev_dct'
function.
The problem was in the incorrect partially empty row detection. Even
if the first two coefficients in the row were nonzero, it handled this
just like the case with only the first nonzero coefficient.
Now this function produces exactly the same output as the stripped
down reference C version of 'j_rev_dct' (with the nested checks like
'if (d6) { if (d2) { ...' always evaluated as true, avoiding shortcut
branches).
author | mru |
---|---|
date | Wed, 12 Nov 2008 20:23:36 +0000 |
parents | e943e1409077 |
children | 524cb7f5ad2b |
rev | line source |
---|---|
3695 | 1 /** |
2 * @file vp5.c | |
3 * VP5 compatible video decoder | |
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:
3697
diff
changeset
|
7 * This file is part of FFmpeg. |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3697
diff
changeset
|
8 * |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3697
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:
3697
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:
3697
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 <stdlib.h> | |
25 #include <string.h> | |
26 | |
27 #include "avcodec.h" | |
28 #include "dsputil.h" | |
29 #include "bitstream.h" | |
30 | |
31 #include "vp56.h" | |
32 #include "vp56data.h" | |
33 #include "vp5data.h" | |
34 | |
35 | |
6297 | 36 static int vp5_parse_header(vp56_context_t *s, const uint8_t *buf, int buf_size, |
3695 | 37 int *golden_frame) |
38 { | |
39 vp56_range_coder_t *c = &s->c; | |
40 int rows, cols; | |
41 | |
42 vp56_init_range_decoder(&s->c, buf, buf_size); | |
4595 | 43 s->framep[VP56_FRAME_CURRENT]->key_frame = !vp56_rac_get(c); |
3695 | 44 vp56_rac_get(c); |
45 vp56_init_dequant(s, vp56_rac_gets(c, 6)); | |
4595 | 46 if (s->framep[VP56_FRAME_CURRENT]->key_frame) |
3695 | 47 { |
48 vp56_rac_gets(c, 8); | |
49 if(vp56_rac_gets(c, 5) > 5) | |
50 return 0; | |
51 vp56_rac_gets(c, 2); | |
52 if (vp56_rac_get(c)) { | |
53 av_log(s->avctx, AV_LOG_ERROR, "interlacing not supported\n"); | |
54 return 0; | |
55 } | |
56 rows = vp56_rac_gets(c, 8); /* number of stored macroblock rows */ | |
57 cols = vp56_rac_gets(c, 8); /* number of stored macroblock cols */ | |
58 vp56_rac_gets(c, 8); /* number of displayed macroblock rows */ | |
59 vp56_rac_gets(c, 8); /* number of displayed macroblock cols */ | |
60 vp56_rac_gets(c, 2); | |
61 if (16*cols != s->avctx->coded_width || | |
62 16*rows != s->avctx->coded_height) { | |
63 avcodec_set_dimensions(s->avctx, 16*cols, 16*rows); | |
64 return 2; | |
65 } | |
66 } | |
67 return 1; | |
68 } | |
69 | |
70 /* Gives very similar result than the vp6 version except in a few cases */ | |
71 static int vp5_adjust(int v, int t) | |
72 { | |
73 int s2, s1 = v >> 31; | |
74 v ^= s1; | |
75 v -= s1; | |
76 v *= v < 2*t; | |
77 v -= t; | |
78 s2 = v >> 31; | |
79 v ^= s2; | |
80 v -= s2; | |
81 v = t - v; | |
82 v += s1; | |
83 v ^= s1; | |
84 return v; | |
85 } | |
86 | |
3697 | 87 static void vp5_parse_vector_adjustment(vp56_context_t *s, vp56_mv_t *vect) |
3695 | 88 { |
89 vp56_range_coder_t *c = &s->c; | |
5711 | 90 vp56_model_t *model = s->modelp; |
3695 | 91 int comp, di; |
92 | |
93 for (comp=0; comp<2; comp++) { | |
94 int delta = 0; | |
5711 | 95 if (vp56_rac_get_prob(c, model->vector_dct[comp])) { |
96 int sign = vp56_rac_get_prob(c, model->vector_sig[comp]); | |
97 di = vp56_rac_get_prob(c, model->vector_pdi[comp][0]); | |
98 di |= vp56_rac_get_prob(c, model->vector_pdi[comp][1]) << 1; | |
3695 | 99 delta = vp56_rac_get_tree(c, vp56_pva_tree, |
5711 | 100 model->vector_pdv[comp]); |
3695 | 101 delta = di | (delta << 2); |
102 delta = (delta ^ -sign) + sign; | |
103 } | |
104 if (!comp) | |
3697 | 105 vect->x = delta; |
3695 | 106 else |
3697 | 107 vect->y = delta; |
3695 | 108 } |
109 } | |
110 | |
111 static void vp5_parse_vector_models(vp56_context_t *s) | |
112 { | |
113 vp56_range_coder_t *c = &s->c; | |
5711 | 114 vp56_model_t *model = s->modelp; |
3695 | 115 int comp, node; |
116 | |
117 for (comp=0; comp<2; comp++) { | |
118 if (vp56_rac_get_prob(c, vp5_vmc_pct[comp][0])) | |
5711 | 119 model->vector_dct[comp] = vp56_rac_gets_nn(c, 7); |
3695 | 120 if (vp56_rac_get_prob(c, vp5_vmc_pct[comp][1])) |
5711 | 121 model->vector_sig[comp] = vp56_rac_gets_nn(c, 7); |
3695 | 122 if (vp56_rac_get_prob(c, vp5_vmc_pct[comp][2])) |
5711 | 123 model->vector_pdi[comp][0] = vp56_rac_gets_nn(c, 7); |
3695 | 124 if (vp56_rac_get_prob(c, vp5_vmc_pct[comp][3])) |
5711 | 125 model->vector_pdi[comp][1] = vp56_rac_gets_nn(c, 7); |
3695 | 126 } |
127 | |
128 for (comp=0; comp<2; comp++) | |
129 for (node=0; node<7; node++) | |
130 if (vp56_rac_get_prob(c, vp5_vmc_pct[comp][4 + node])) | |
5711 | 131 model->vector_pdv[comp][node] = vp56_rac_gets_nn(c, 7); |
3695 | 132 } |
133 | |
134 static void vp5_parse_coeff_models(vp56_context_t *s) | |
135 { | |
136 vp56_range_coder_t *c = &s->c; | |
5711 | 137 vp56_model_t *model = s->modelp; |
3695 | 138 uint8_t def_prob[11]; |
139 int node, cg, ctx; | |
140 int ct; /* code type */ | |
141 int pt; /* plane type (0 for Y, 1 for U or V) */ | |
142 | |
143 memset(def_prob, 0x80, sizeof(def_prob)); | |
144 | |
145 for (pt=0; pt<2; pt++) | |
146 for (node=0; node<11; node++) | |
147 if (vp56_rac_get_prob(c, vp5_dccv_pct[pt][node])) { | |
148 def_prob[node] = vp56_rac_gets_nn(c, 7); | |
5711 | 149 model->coeff_dccv[pt][node] = def_prob[node]; |
4595 | 150 } else if (s->framep[VP56_FRAME_CURRENT]->key_frame) { |
5711 | 151 model->coeff_dccv[pt][node] = def_prob[node]; |
3695 | 152 } |
153 | |
154 for (ct=0; ct<3; ct++) | |
155 for (pt=0; pt<2; pt++) | |
156 for (cg=0; cg<6; cg++) | |
157 for (node=0; node<11; node++) | |
158 if (vp56_rac_get_prob(c, vp5_ract_pct[ct][pt][cg][node])) { | |
159 def_prob[node] = vp56_rac_gets_nn(c, 7); | |
5711 | 160 model->coeff_ract[pt][ct][cg][node] = def_prob[node]; |
4595 | 161 } else if (s->framep[VP56_FRAME_CURRENT]->key_frame) { |
5711 | 162 model->coeff_ract[pt][ct][cg][node] = def_prob[node]; |
3695 | 163 } |
164 | |
5711 | 165 /* coeff_dcct is a linear combination of coeff_dccv */ |
3695 | 166 for (pt=0; pt<2; pt++) |
167 for (ctx=0; ctx<36; ctx++) | |
168 for (node=0; node<5; node++) | |
5711 | 169 model->coeff_dcct[pt][ctx][node] = av_clip(((model->coeff_dccv[pt][node] * vp5_dccv_lc[node][ctx][0] + 128) >> 8) + vp5_dccv_lc[node][ctx][1], 1, 254); |
3695 | 170 |
5711 | 171 /* coeff_acct is a linear combination of coeff_ract */ |
3695 | 172 for (ct=0; ct<3; ct++) |
173 for (pt=0; pt<2; pt++) | |
174 for (cg=0; cg<3; cg++) | |
175 for (ctx=0; ctx<6; ctx++) | |
176 for (node=0; node<5; node++) | |
5711 | 177 model->coeff_acct[pt][ct][cg][ctx][node] = av_clip(((model->coeff_ract[pt][ct][cg][node] * vp5_ract_lc[ct][cg][node][ctx][0] + 128) >> 8) + vp5_ract_lc[ct][cg][node][ctx][1], 1, 254); |
3695 | 178 } |
179 | |
180 static void vp5_parse_coeff(vp56_context_t *s) | |
181 { | |
182 vp56_range_coder_t *c = &s->c; | |
5711 | 183 vp56_model_t *model = s->modelp; |
3695 | 184 uint8_t *permute = s->scantable.permutated; |
5711 | 185 uint8_t *model1, *model2; |
3695 | 186 int coeff, sign, coeff_idx; |
187 int b, i, cg, idx, ctx, ctx_last; | |
188 int pt = 0; /* plane type (0 for Y, 1 for U or V) */ | |
189 | |
190 for (b=0; b<6; b++) { | |
191 int ct = 1; /* code type */ | |
192 | |
193 if (b > 3) pt = 1; | |
194 | |
195 ctx = 6*s->coeff_ctx[vp56_b6to4[b]][0] | |
196 + s->above_blocks[s->above_block_idx[b]].not_null_dc; | |
5711 | 197 model1 = model->coeff_dccv[pt]; |
198 model2 = model->coeff_dcct[pt][ctx]; | |
3695 | 199 |
200 for (coeff_idx=0; coeff_idx<64; ) { | |
201 if (vp56_rac_get_prob(c, model2[0])) { | |
202 if (vp56_rac_get_prob(c, model2[2])) { | |
203 if (vp56_rac_get_prob(c, model2[3])) { | |
204 s->coeff_ctx[vp56_b6to4[b]][coeff_idx] = 4; | |
5711 | 205 idx = vp56_rac_get_tree(c, vp56_pc_tree, model1); |
3695 | 206 sign = vp56_rac_get(c); |
5821 | 207 coeff = vp56_coeff_bias[idx+5]; |
3695 | 208 for (i=vp56_coeff_bit_length[idx]; i>=0; i--) |
209 coeff += vp56_rac_get_prob(c, vp56_coeff_parse_table[idx][i]) << i; | |
210 } else { | |
211 if (vp56_rac_get_prob(c, model2[4])) { | |
5711 | 212 coeff = 3 + vp56_rac_get_prob(c, model1[5]); |
3695 | 213 s->coeff_ctx[vp56_b6to4[b]][coeff_idx] = 3; |
214 } else { | |
215 coeff = 2; | |
216 s->coeff_ctx[vp56_b6to4[b]][coeff_idx] = 2; | |
217 } | |
218 sign = vp56_rac_get(c); | |
219 } | |
220 ct = 2; | |
221 } else { | |
222 ct = 1; | |
223 s->coeff_ctx[vp56_b6to4[b]][coeff_idx] = 1; | |
224 sign = vp56_rac_get(c); | |
225 coeff = 1; | |
226 } | |
227 coeff = (coeff ^ -sign) + sign; | |
228 if (coeff_idx) | |
229 coeff *= s->dequant_ac; | |
230 s->block_coeff[b][permute[coeff_idx]] = coeff; | |
231 } else { | |
232 if (ct && !vp56_rac_get_prob(c, model2[1])) | |
233 break; | |
234 ct = 0; | |
235 s->coeff_ctx[vp56_b6to4[b]][coeff_idx] = 0; | |
236 } | |
237 | |
238 cg = vp5_coeff_groups[++coeff_idx]; | |
239 ctx = s->coeff_ctx[vp56_b6to4[b]][coeff_idx]; | |
5711 | 240 model1 = model->coeff_ract[pt][ct][cg]; |
241 model2 = cg > 2 ? model1 : model->coeff_acct[pt][ct][cg][ctx]; | |
3695 | 242 } |
243 | |
244 ctx_last = FFMIN(s->coeff_ctx_last[vp56_b6to4[b]], 24); | |
245 s->coeff_ctx_last[vp56_b6to4[b]] = coeff_idx; | |
246 if (coeff_idx < ctx_last) | |
247 for (i=coeff_idx; i<=ctx_last; i++) | |
248 s->coeff_ctx[vp56_b6to4[b]][i] = 5; | |
249 s->above_blocks[s->above_block_idx[b]].not_null_dc = s->coeff_ctx[vp56_b6to4[b]][0]; | |
250 } | |
251 } | |
252 | |
253 static void vp5_default_models_init(vp56_context_t *s) | |
254 { | |
5711 | 255 vp56_model_t *model = s->modelp; |
3695 | 256 int i; |
257 | |
258 for (i=0; i<2; i++) { | |
5711 | 259 model->vector_sig[i] = 0x80; |
260 model->vector_dct[i] = 0x80; | |
261 model->vector_pdi[i][0] = 0x55; | |
262 model->vector_pdi[i][1] = 0x80; | |
3695 | 263 } |
5711 | 264 memcpy(model->mb_types_stats, vp56_def_mb_types_stats, sizeof(model->mb_types_stats)); |
265 memset(model->vector_pdv, 0x80, sizeof(model->vector_pdv)); | |
3695 | 266 } |
267 | |
6517
48759bfbd073
Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents:
6448
diff
changeset
|
268 static av_cold int vp5_decode_init(AVCodecContext *avctx) |
3695 | 269 { |
270 vp56_context_t *s = avctx->priv_data; | |
271 | |
5714
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
272 vp56_init(avctx, 1, 0); |
3695 | 273 s->vp56_coord_div = vp5_coord_div; |
274 s->parse_vector_adjustment = vp5_parse_vector_adjustment; | |
275 s->adjust = vp5_adjust; | |
276 s->parse_coeff = vp5_parse_coeff; | |
277 s->default_models_init = vp5_default_models_init; | |
278 s->parse_vector_models = vp5_parse_vector_models; | |
279 s->parse_coeff_models = vp5_parse_coeff_models; | |
280 s->parse_header = vp5_parse_header; | |
281 | |
282 return 0; | |
283 } | |
284 | |
285 AVCodec vp5_decoder = { | |
286 "vp5", | |
287 CODEC_TYPE_VIDEO, | |
288 CODEC_ID_VP5, | |
289 sizeof(vp56_context_t), | |
290 vp5_decode_init, | |
291 NULL, | |
292 vp56_free, | |
293 vp56_decode_frame, | |
4910 | 294 CODEC_CAP_DR1, |
7040
e943e1409077
Make AVCodec long_names definition conditional depending on CONFIG_SMALL.
stefano
parents:
6710
diff
changeset
|
295 .long_name = NULL_IF_CONFIG_SMALL("On2 VP5"), |
3695 | 296 }; |