Mercurial > libavcodec.hg
annotate vp56.h @ 10061:09f2db2d7c90 libavcodec
Fix bug caused by difference in stride and picture width.
When a frame is allocated using libschroedinger routines, the frame data size
does not match the actual frame size if the width is not a multiple of 16. So
we cannot do a straightforward memcpy of the frame returned by libschroedinger
into the FFmpeg picture as the stride differs from the width.
Fix this bug by allocating for the libschroedinger frame with the dimensions
in AVCodecContext within libavcodec and passing the frame to libschroedinger.
patch by Anuradha Suraparaju, anuradha rd.bbc.co uk
author | diego |
---|---|
date | Sat, 15 Aug 2009 11:59:53 +0000 |
parents | c7c1c6b35a73 |
children | 34a65026fa06 |
rev | line source |
---|---|
3695 | 1 /** |
8718
e9d9d946f213
Use full internal pathname in doxygen @file directives.
diego
parents:
8304
diff
changeset
|
2 * @file libavcodec/vp56.h |
3695 | 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:
3759
diff
changeset
|
7 * This file is part of FFmpeg. |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3759
diff
changeset
|
8 * |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3759
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:
3759
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:
3759
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 | |
7760 | 24 #ifndef AVCODEC_VP56_H |
25 #define AVCODEC_VP56_H | |
3695 | 26 |
27 #include "vp56data.h" | |
28 #include "dsputil.h" | |
9428 | 29 #include "get_bits.h" |
5089 | 30 #include "bytestream.h" |
3695 | 31 |
32 | |
8299 | 33 typedef struct vp56_context VP56Context; |
34 typedef struct vp56_mv VP56mv; | |
3695 | 35 |
8299 | 36 typedef void (*VP56ParseVectorAdjustment)(VP56Context *s, |
8300 | 37 VP56mv *vect); |
38 typedef int (*VP56Adjust)(int v, int t); | |
8299 | 39 typedef void (*VP56Filter)(VP56Context *s, uint8_t *dst, uint8_t *src, |
8300 | 40 int offset1, int offset2, int stride, |
41 VP56mv mv, int mask, int select, int luma); | |
8299 | 42 typedef void (*VP56ParseCoeff)(VP56Context *s); |
43 typedef void (*VP56DefaultModelsInit)(VP56Context *s); | |
44 typedef void (*VP56ParseVectorModels)(VP56Context *s); | |
45 typedef void (*VP56ParseCoeffModels)(VP56Context *s); | |
8300 | 46 typedef int (*VP56ParseHeader)(VP56Context *s, const uint8_t *buf, |
47 int buf_size, int *golden_frame); | |
3695 | 48 |
49 typedef struct { | |
50 int high; | |
51 int bits; | |
6297 | 52 const uint8_t *buffer; |
9919
c7c1c6b35a73
vp56dec: ensure range coder won't read past the end of input buffer
aurel
parents:
9428
diff
changeset
|
53 const uint8_t *end; |
3695 | 54 unsigned long code_word; |
8299 | 55 } VP56RangeCoder; |
3695 | 56 |
57 typedef struct { | |
58 uint8_t not_null_dc; | |
8299 | 59 VP56Frame ref_frame; |
3695 | 60 DCTELEM dc_coeff; |
8299 | 61 } VP56RefDc; |
3695 | 62 |
63 struct vp56_mv { | |
64 int x; | |
65 int y; | |
66 }; | |
67 | |
68 typedef struct { | |
69 uint8_t type; | |
8299 | 70 VP56mv mv; |
71 } VP56Macroblock; | |
3695 | 72 |
5711 | 73 typedef struct { |
74 uint8_t coeff_reorder[64]; /* used in vp6 only */ | |
75 uint8_t coeff_index_to_pos[64]; /* used in vp6 only */ | |
76 uint8_t vector_sig[2]; /* delta sign */ | |
77 uint8_t vector_dct[2]; /* delta coding types */ | |
78 uint8_t vector_pdi[2][2]; /* predefined delta init */ | |
79 uint8_t vector_pdv[2][7]; /* predefined delta values */ | |
80 uint8_t vector_fdv[2][8]; /* 8 bit delta value definition */ | |
81 uint8_t coeff_dccv[2][11]; /* DC coeff value */ | |
82 uint8_t coeff_ract[2][3][6][11]; /* Run/AC coding type and AC coeff value */ | |
83 uint8_t coeff_acct[2][3][3][6][5];/* vp5 only AC coding type for coding group < 3 */ | |
84 uint8_t coeff_dcct[2][36][5]; /* DC coeff coding type */ | |
85 uint8_t coeff_runv[2][14]; /* run value (vp6 only) */ | |
86 uint8_t mb_type[3][10][10]; /* model for decoding MB type */ | |
87 uint8_t mb_types_stats[3][10][2];/* contextual, next MB type stats */ | |
8304 | 88 } VP56Model; |
5711 | 89 |
3695 | 90 struct vp56_context { |
91 AVCodecContext *avctx; | |
92 DSPContext dsp; | |
93 ScanTable scantable; | |
5714
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
94 AVFrame frames[4]; |
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
95 AVFrame *framep[6]; |
3695 | 96 uint8_t *edge_emu_buffer_alloc; |
97 uint8_t *edge_emu_buffer; | |
8299 | 98 VP56RangeCoder c; |
99 VP56RangeCoder cc; | |
100 VP56RangeCoder *ccp; | |
4308 | 101 int sub_version; |
3695 | 102 |
103 /* frame info */ | |
5714
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
104 int plane_width[4]; |
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
105 int plane_height[4]; |
3695 | 106 int mb_width; /* number of horizontal MB */ |
107 int mb_height; /* number of vertical MB */ | |
108 int block_offset[6]; | |
109 | |
110 int quantizer; | |
111 uint16_t dequant_dc; | |
112 uint16_t dequant_ac; | |
113 | |
114 /* DC predictors management */ | |
8299 | 115 VP56RefDc *above_blocks; |
116 VP56RefDc left_block[4]; | |
3695 | 117 int above_block_idx[6]; |
118 DCTELEM prev_dc[3][3]; /* [plan][ref_frame] */ | |
119 | |
120 /* blocks / macroblock */ | |
8299 | 121 VP56mb mb_type; |
122 VP56Macroblock *macroblocks; | |
3695 | 123 DECLARE_ALIGNED_16(DCTELEM, block_coeff[6][64]); |
124 | |
125 /* motion vectors */ | |
8299 | 126 VP56mv mv[6]; /* vectors for each block in MB */ |
127 VP56mv vector_candidate[2]; | |
3695 | 128 int vector_candidate_pos; |
129 | |
130 /* filtering hints */ | |
4348 | 131 int filter_header; /* used in vp6 only */ |
3695 | 132 int deblock_filtering; |
133 int filter_selection; | |
134 int filter_mode; | |
135 int max_vector_length; | |
136 int sample_variance_threshold; | |
137 | |
138 uint8_t coeff_ctx[4][64]; /* used in vp5 only */ | |
139 uint8_t coeff_ctx_last[4]; /* used in vp5 only */ | |
140 | |
5714
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
141 int has_alpha; |
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
142 |
3695 | 143 /* upside-down flipping hints */ |
144 int flip; /* are we flipping ? */ | |
145 int frbi; /* first row block index in MB */ | |
146 int srbi; /* second row block index in MB */ | |
5714
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
147 int stride[4]; /* stride for each plan */ |
3695 | 148 |
149 const uint8_t *vp56_coord_div; | |
8299 | 150 VP56ParseVectorAdjustment parse_vector_adjustment; |
151 VP56Adjust adjust; | |
152 VP56Filter filter; | |
153 VP56ParseCoeff parse_coeff; | |
154 VP56DefaultModelsInit default_models_init; | |
155 VP56ParseVectorModels parse_vector_models; | |
156 VP56ParseCoeffModels parse_coeff_models; | |
157 VP56ParseHeader parse_header; | |
5711 | 158 |
8304 | 159 VP56Model *modelp; |
160 VP56Model models[2]; | |
5821 | 161 |
162 /* huffman decoding */ | |
163 int use_huffman; | |
164 GetBitContext gb; | |
165 VLC dccv_vlc[2]; | |
166 VLC runv_vlc[2]; | |
167 VLC ract_vlc[2][3][6]; | |
168 unsigned int nb_null[2][2]; /* number of consecutive NULL DC/AC */ | |
3695 | 169 }; |
170 | |
171 | |
5714
314be1cfdcb0
add a new vp6a codec (add alpha plan support to vp6)
aurel
parents:
5711
diff
changeset
|
172 void vp56_init(AVCodecContext *avctx, int flip, int has_alpha); |
3695 | 173 int vp56_free(AVCodecContext *avctx); |
8299 | 174 void vp56_init_dequant(VP56Context *s, int quantizer); |
3695 | 175 int vp56_decode_frame(AVCodecContext *avctx, void *data, int *data_size, |
9356
2983bd7deaf5
fix vp5/vp6 decoding by using new prototype for decode function
aurel
parents:
8718
diff
changeset
|
176 AVPacket *avpkt); |
3695 | 177 |
178 | |
179 /** | |
180 * vp56 specific range coder implementation | |
181 */ | |
182 | |
8299 | 183 static inline void vp56_init_range_decoder(VP56RangeCoder *c, |
6297 | 184 const uint8_t *buf, int buf_size) |
3695 | 185 { |
186 c->high = 255; | |
187 c->bits = 8; | |
188 c->buffer = buf; | |
9919
c7c1c6b35a73
vp56dec: ensure range coder won't read past the end of input buffer
aurel
parents:
9428
diff
changeset
|
189 c->end = buf + buf_size; |
5089 | 190 c->code_word = bytestream_get_be16(&c->buffer); |
3695 | 191 } |
192 | |
8299 | 193 static inline int vp56_rac_get_prob(VP56RangeCoder *c, uint8_t prob) |
3695 | 194 { |
195 unsigned int low = 1 + (((c->high - 1) * prob) / 256); | |
196 unsigned int low_shift = low << 8; | |
197 int bit = c->code_word >= low_shift; | |
198 | |
199 if (bit) { | |
200 c->high -= low; | |
201 c->code_word -= low_shift; | |
202 } else { | |
203 c->high = low; | |
204 } | |
205 | |
206 /* normalize */ | |
207 while (c->high < 128) { | |
208 c->high <<= 1; | |
209 c->code_word <<= 1; | |
9919
c7c1c6b35a73
vp56dec: ensure range coder won't read past the end of input buffer
aurel
parents:
9428
diff
changeset
|
210 if (--c->bits == 0 && c->buffer < c->end) { |
3695 | 211 c->bits = 8; |
212 c->code_word |= *c->buffer++; | |
213 } | |
214 } | |
215 return bit; | |
216 } | |
217 | |
8299 | 218 static inline int vp56_rac_get(VP56RangeCoder *c) |
3695 | 219 { |
220 /* equiprobable */ | |
221 int low = (c->high + 1) >> 1; | |
222 unsigned int low_shift = low << 8; | |
223 int bit = c->code_word >= low_shift; | |
224 if (bit) { | |
225 c->high = (c->high - low) << 1; | |
226 c->code_word -= low_shift; | |
227 } else { | |
228 c->high = low << 1; | |
229 } | |
230 | |
231 /* normalize */ | |
232 c->code_word <<= 1; | |
9919
c7c1c6b35a73
vp56dec: ensure range coder won't read past the end of input buffer
aurel
parents:
9428
diff
changeset
|
233 if (--c->bits == 0 && c->buffer < c->end) { |
3695 | 234 c->bits = 8; |
235 c->code_word |= *c->buffer++; | |
236 } | |
237 return bit; | |
238 } | |
239 | |
8299 | 240 static inline int vp56_rac_gets(VP56RangeCoder *c, int bits) |
3695 | 241 { |
242 int value = 0; | |
243 | |
244 while (bits--) { | |
245 value = (value << 1) | vp56_rac_get(c); | |
246 } | |
247 | |
248 return value; | |
249 } | |
250 | |
8299 | 251 static inline int vp56_rac_gets_nn(VP56RangeCoder *c, int bits) |
3695 | 252 { |
253 int v = vp56_rac_gets(c, 7) << 1; | |
254 return v + !v; | |
255 } | |
256 | |
8299 | 257 static inline int vp56_rac_get_tree(VP56RangeCoder *c, |
258 const VP56Tree *tree, | |
3695 | 259 const uint8_t *probs) |
260 { | |
261 while (tree->val > 0) { | |
262 if (vp56_rac_get_prob(c, probs[tree->prob_idx])) | |
263 tree += tree->val; | |
264 else | |
265 tree++; | |
266 } | |
267 return -tree->val; | |
268 } | |
269 | |
7760 | 270 #endif /* AVCODEC_VP56_H */ |