Mercurial > libavcodec.hg
annotate vp5.c @ 11557:53822d92c3f7 libavcodec
Make sure the EC code does not attempt to use inter based concealment if there
is no reference frame available. (this can happen because the EC code will attempt
to use reference frames even for I/IDR frames)
author | michael |
---|---|
date | Tue, 30 Mar 2010 20:46:46 +0000 |
parents | 0dce4fe6e6f3 |
children | 8a4984c5cacc |
rev | line source |
---|---|
3695 | 1 /** |
8718
e9d9d946f213
Use full internal pathname in doxygen @file directives.
diego
parents:
8674
diff
changeset
|
2 * @file libavcodec/vp5.c |
3695 | 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" | |
9428 | 29 #include "get_bits.h" |
3695 | 30 |
31 #include "vp56.h" | |
32 #include "vp56data.h" | |
33 #include "vp5data.h" | |
34 | |
35 | |
8299 | 36 static int vp5_parse_header(VP56Context *s, const uint8_t *buf, int buf_size, |
3695 | 37 int *golden_frame) |
38 { | |
8299 | 39 VP56RangeCoder *c = &s->c; |
3695 | 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); | |
8329 | 61 if (!s->macroblocks || /* first frame */ |
62 16*cols != s->avctx->coded_width || | |
3695 | 63 16*rows != s->avctx->coded_height) { |
64 avcodec_set_dimensions(s->avctx, 16*cols, 16*rows); | |
65 return 2; | |
66 } | |
8674
f36e2c1749b5
vp5: don't try decoding a P frame before any I frame was parsed
aurel
parents:
8329
diff
changeset
|
67 } else if (!s->macroblocks) |
f36e2c1749b5
vp5: don't try decoding a P frame before any I frame was parsed
aurel
parents:
8329
diff
changeset
|
68 return 0; |
3695 | 69 return 1; |
70 } | |
71 | |
72 /* Gives very similar result than the vp6 version except in a few cases */ | |
73 static int vp5_adjust(int v, int t) | |
74 { | |
75 int s2, s1 = v >> 31; | |
76 v ^= s1; | |
77 v -= s1; | |
78 v *= v < 2*t; | |
79 v -= t; | |
80 s2 = v >> 31; | |
81 v ^= s2; | |
82 v -= s2; | |
83 v = t - v; | |
84 v += s1; | |
85 v ^= s1; | |
86 return v; | |
87 } | |
88 | |
8299 | 89 static void vp5_parse_vector_adjustment(VP56Context *s, VP56mv *vect) |
3695 | 90 { |
8299 | 91 VP56RangeCoder *c = &s->c; |
8304 | 92 VP56Model *model = s->modelp; |
3695 | 93 int comp, di; |
94 | |
95 for (comp=0; comp<2; comp++) { | |
96 int delta = 0; | |
5711 | 97 if (vp56_rac_get_prob(c, model->vector_dct[comp])) { |
98 int sign = vp56_rac_get_prob(c, model->vector_sig[comp]); | |
99 di = vp56_rac_get_prob(c, model->vector_pdi[comp][0]); | |
100 di |= vp56_rac_get_prob(c, model->vector_pdi[comp][1]) << 1; | |
3695 | 101 delta = vp56_rac_get_tree(c, vp56_pva_tree, |
5711 | 102 model->vector_pdv[comp]); |
3695 | 103 delta = di | (delta << 2); |
104 delta = (delta ^ -sign) + sign; | |
105 } | |
106 if (!comp) | |
3697 | 107 vect->x = delta; |
3695 | 108 else |
3697 | 109 vect->y = delta; |
3695 | 110 } |
111 } | |
112 | |
8299 | 113 static void vp5_parse_vector_models(VP56Context *s) |
3695 | 114 { |
8299 | 115 VP56RangeCoder *c = &s->c; |
8304 | 116 VP56Model *model = s->modelp; |
3695 | 117 int comp, node; |
118 | |
119 for (comp=0; comp<2; comp++) { | |
120 if (vp56_rac_get_prob(c, vp5_vmc_pct[comp][0])) | |
5711 | 121 model->vector_dct[comp] = vp56_rac_gets_nn(c, 7); |
3695 | 122 if (vp56_rac_get_prob(c, vp5_vmc_pct[comp][1])) |
5711 | 123 model->vector_sig[comp] = vp56_rac_gets_nn(c, 7); |
3695 | 124 if (vp56_rac_get_prob(c, vp5_vmc_pct[comp][2])) |
5711 | 125 model->vector_pdi[comp][0] = vp56_rac_gets_nn(c, 7); |
3695 | 126 if (vp56_rac_get_prob(c, vp5_vmc_pct[comp][3])) |
5711 | 127 model->vector_pdi[comp][1] = vp56_rac_gets_nn(c, 7); |
3695 | 128 } |
129 | |
130 for (comp=0; comp<2; comp++) | |
131 for (node=0; node<7; node++) | |
132 if (vp56_rac_get_prob(c, vp5_vmc_pct[comp][4 + node])) | |
5711 | 133 model->vector_pdv[comp][node] = vp56_rac_gets_nn(c, 7); |
3695 | 134 } |
135 | |
8299 | 136 static void vp5_parse_coeff_models(VP56Context *s) |
3695 | 137 { |
8299 | 138 VP56RangeCoder *c = &s->c; |
8304 | 139 VP56Model *model = s->modelp; |
3695 | 140 uint8_t def_prob[11]; |
141 int node, cg, ctx; | |
142 int ct; /* code type */ | |
143 int pt; /* plane type (0 for Y, 1 for U or V) */ | |
144 | |
145 memset(def_prob, 0x80, sizeof(def_prob)); | |
146 | |
147 for (pt=0; pt<2; pt++) | |
148 for (node=0; node<11; node++) | |
149 if (vp56_rac_get_prob(c, vp5_dccv_pct[pt][node])) { | |
150 def_prob[node] = vp56_rac_gets_nn(c, 7); | |
5711 | 151 model->coeff_dccv[pt][node] = def_prob[node]; |
4595 | 152 } else if (s->framep[VP56_FRAME_CURRENT]->key_frame) { |
5711 | 153 model->coeff_dccv[pt][node] = def_prob[node]; |
3695 | 154 } |
155 | |
156 for (ct=0; ct<3; ct++) | |
157 for (pt=0; pt<2; pt++) | |
158 for (cg=0; cg<6; cg++) | |
159 for (node=0; node<11; node++) | |
160 if (vp56_rac_get_prob(c, vp5_ract_pct[ct][pt][cg][node])) { | |
161 def_prob[node] = vp56_rac_gets_nn(c, 7); | |
5711 | 162 model->coeff_ract[pt][ct][cg][node] = def_prob[node]; |
4595 | 163 } else if (s->framep[VP56_FRAME_CURRENT]->key_frame) { |
5711 | 164 model->coeff_ract[pt][ct][cg][node] = def_prob[node]; |
3695 | 165 } |
166 | |
5711 | 167 /* coeff_dcct is a linear combination of coeff_dccv */ |
3695 | 168 for (pt=0; pt<2; pt++) |
169 for (ctx=0; ctx<36; ctx++) | |
170 for (node=0; node<5; node++) | |
5711 | 171 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 | 172 |
5711 | 173 /* coeff_acct is a linear combination of coeff_ract */ |
3695 | 174 for (ct=0; ct<3; ct++) |
175 for (pt=0; pt<2; pt++) | |
176 for (cg=0; cg<3; cg++) | |
177 for (ctx=0; ctx<6; ctx++) | |
178 for (node=0; node<5; node++) | |
5711 | 179 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 | 180 } |
181 | |
8299 | 182 static void vp5_parse_coeff(VP56Context *s) |
3695 | 183 { |
8299 | 184 VP56RangeCoder *c = &s->c; |
8304 | 185 VP56Model *model = s->modelp; |
3695 | 186 uint8_t *permute = s->scantable.permutated; |
5711 | 187 uint8_t *model1, *model2; |
3695 | 188 int coeff, sign, coeff_idx; |
189 int b, i, cg, idx, ctx, ctx_last; | |
190 int pt = 0; /* plane type (0 for Y, 1 for U or V) */ | |
191 | |
192 for (b=0; b<6; b++) { | |
193 int ct = 1; /* code type */ | |
194 | |
195 if (b > 3) pt = 1; | |
196 | |
197 ctx = 6*s->coeff_ctx[vp56_b6to4[b]][0] | |
198 + s->above_blocks[s->above_block_idx[b]].not_null_dc; | |
5711 | 199 model1 = model->coeff_dccv[pt]; |
200 model2 = model->coeff_dcct[pt][ctx]; | |
3695 | 201 |
202 for (coeff_idx=0; coeff_idx<64; ) { | |
203 if (vp56_rac_get_prob(c, model2[0])) { | |
204 if (vp56_rac_get_prob(c, model2[2])) { | |
205 if (vp56_rac_get_prob(c, model2[3])) { | |
206 s->coeff_ctx[vp56_b6to4[b]][coeff_idx] = 4; | |
5711 | 207 idx = vp56_rac_get_tree(c, vp56_pc_tree, model1); |
3695 | 208 sign = vp56_rac_get(c); |
5821 | 209 coeff = vp56_coeff_bias[idx+5]; |
3695 | 210 for (i=vp56_coeff_bit_length[idx]; i>=0; i--) |
211 coeff += vp56_rac_get_prob(c, vp56_coeff_parse_table[idx][i]) << i; | |
212 } else { | |
213 if (vp56_rac_get_prob(c, model2[4])) { | |
5711 | 214 coeff = 3 + vp56_rac_get_prob(c, model1[5]); |
3695 | 215 s->coeff_ctx[vp56_b6to4[b]][coeff_idx] = 3; |
216 } else { | |
217 coeff = 2; | |
218 s->coeff_ctx[vp56_b6to4[b]][coeff_idx] = 2; | |
219 } | |
220 sign = vp56_rac_get(c); | |
221 } | |
222 ct = 2; | |
223 } else { | |
224 ct = 1; | |
225 s->coeff_ctx[vp56_b6to4[b]][coeff_idx] = 1; | |
226 sign = vp56_rac_get(c); | |
227 coeff = 1; | |
228 } | |
229 coeff = (coeff ^ -sign) + sign; | |
230 if (coeff_idx) | |
231 coeff *= s->dequant_ac; | |
232 s->block_coeff[b][permute[coeff_idx]] = coeff; | |
233 } else { | |
234 if (ct && !vp56_rac_get_prob(c, model2[1])) | |
235 break; | |
236 ct = 0; | |
237 s->coeff_ctx[vp56_b6to4[b]][coeff_idx] = 0; | |
238 } | |
239 | |
240 cg = vp5_coeff_groups[++coeff_idx]; | |
241 ctx = s->coeff_ctx[vp56_b6to4[b]][coeff_idx]; | |
5711 | 242 model1 = model->coeff_ract[pt][ct][cg]; |
243 model2 = cg > 2 ? model1 : model->coeff_acct[pt][ct][cg][ctx]; | |
3695 | 244 } |
245 | |
246 ctx_last = FFMIN(s->coeff_ctx_last[vp56_b6to4[b]], 24); | |
247 s->coeff_ctx_last[vp56_b6to4[b]] = coeff_idx; | |
248 if (coeff_idx < ctx_last) | |
249 for (i=coeff_idx; i<=ctx_last; i++) | |
250 s->coeff_ctx[vp56_b6to4[b]][i] = 5; | |
251 s->above_blocks[s->above_block_idx[b]].not_null_dc = s->coeff_ctx[vp56_b6to4[b]][0]; | |
252 } | |
253 } | |
254 | |
8299 | 255 static void vp5_default_models_init(VP56Context *s) |
3695 | 256 { |
8304 | 257 VP56Model *model = s->modelp; |
3695 | 258 int i; |
259 | |
260 for (i=0; i<2; i++) { | |
5711 | 261 model->vector_sig[i] = 0x80; |
262 model->vector_dct[i] = 0x80; | |
263 model->vector_pdi[i][0] = 0x55; | |
264 model->vector_pdi[i][1] = 0x80; | |
3695 | 265 } |
5711 | 266 memcpy(model->mb_types_stats, vp56_def_mb_types_stats, sizeof(model->mb_types_stats)); |
267 memset(model->vector_pdv, 0x80, sizeof(model->vector_pdv)); | |
3695 | 268 } |
269 | |
6517
48759bfbd073
Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents:
6448
diff
changeset
|
270 static av_cold int vp5_decode_init(AVCodecContext *avctx) |
3695 | 271 { |
8299 | 272 VP56Context *s = avctx->priv_data; |
3695 | 273 |
5714
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
274 vp56_init(avctx, 1, 0); |
3695 | 275 s->vp56_coord_div = vp5_coord_div; |
276 s->parse_vector_adjustment = vp5_parse_vector_adjustment; | |
277 s->adjust = vp5_adjust; | |
278 s->parse_coeff = vp5_parse_coeff; | |
279 s->default_models_init = vp5_default_models_init; | |
280 s->parse_vector_models = vp5_parse_vector_models; | |
281 s->parse_coeff_models = vp5_parse_coeff_models; | |
282 s->parse_header = vp5_parse_header; | |
283 | |
284 return 0; | |
285 } | |
286 | |
287 AVCodec vp5_decoder = { | |
288 "vp5", | |
289 CODEC_TYPE_VIDEO, | |
290 CODEC_ID_VP5, | |
8299 | 291 sizeof(VP56Context), |
3695 | 292 vp5_decode_init, |
293 NULL, | |
294 vp56_free, | |
295 vp56_decode_frame, | |
4910 | 296 CODEC_CAP_DR1, |
7040
e943e1409077
Make AVCodec long_names definition conditional depending on CONFIG_SMALL.
stefano
parents:
6710
diff
changeset
|
297 .long_name = NULL_IF_CONFIG_SMALL("On2 VP5"), |
3695 | 298 }; |